Monday, November 14, 2022

Oracle Java SE Programmer I Exam: Preparation Tips & Relevant 1Z0-808 Practice Tests

1z0-808, 1z0-808 exam, 1z0-808 practice test, ocajp 1z0-808, 1z0-808 dumps, 1z0-808 syllabus pdf, 1z0-808 practice test pdf, 1z0-808 syllabus, java 1z0-808, oca 1z0-808, 1z0-808 exam questions, oracle 1z0-808, 1z0-808 exam cost, java se 8 programmer i exam number: 1z0-808, 1z0-808 practice test free, 1z0-808 exam topics, java se 8 programmer i 1z0-808 dumps, java se 8 programmer i 1z0-808, java se 8 programmer i 1z0-808 syllabus, 1z0-808 sample questions, 1z0-808 questions and answers pdf, 1z0-808 exam syllabus, java 1z0-808 practice exam, 1z0-808 topics, oca 1z0-808 exam questions, java certification exam for ocajp 1z0-808, java certification exam for ocajp 1z0-808, java 1z0-808 dumps, 1z0-808 dumps pdf download, 1z0-808 dumps free pdf download, java se 8 programmer i | 1z0-808, java se 8 programmer i 1z0-808 practice test, 1z0-808 real exam questions, 1z0-808 certification, 1z0-808 pdf, 1z0-808: java se 8 programmer i, 1z0-808 questions, java se 8 certification, oracle certified associate java se 8 programmer dumps, java se 8 exam questions, java se 8 programmer exam questions, oca java se 8 mock exam free, oracle certified associate java se 8 programmer practice exams, oracle certified associate java se 8 programmer exam questions, oca java se 8 programmer i exam guide, oracle certified associate java se 8 programmer

OCA is the acronym for Oracle Certified Associate and is the first certification you can get as a Java developer to demonstrate a solid knowledge of Java. Oracle offers many certificates related to Java, and Oracle Certified Associate, 1Z0-808 Java SE 8 Programmer I, is one such certification.

This entry-level focuses on variables, classes and interface definition, arrays, exception handling, encapsulation, polymorphism, and flow control. Basic API knowledge is required about strings and array lists.

Overview of Oracle 1Z0-808 Java SE 8 Programmer I Exam

Oracle 1Z0-808 Java SE 8 Programmer I exam is for those candidates who want to get certified as Oracle Associate. This certification helps you understand Java better, enhancing your programming skills. You must have a technical background to take this Oracle 1Z0-808 certification exam, which encompasses technical management, system administration, web development, and technical writing.

Oracle Certified Associate (OCA) Java SE 8 Programmer I certification helps you build a foundational understanding of Java. You are getting certified as Oracle Certified Associate Java SE 8 Programmer (OCA) is the first of two steps in displaying the high-level skills required to become a professional Java developer.

Oracle Certified Associate (OCA) Java SE 8 Programmer I certification is an entry-level certification in the Java roadmap. You might be wondering what SE means in Java SE 8. There are four programming platforms in Java.

Certification does not mean that a developer that has it is better than another developer because of it. Still, it means that this person has been able to pass a tricky 1Z0-808 exam and has dedicated some time to improve his knowledge of the Java programming language and will have a deeper understanding of how works a Java program.

To better prepare for this 1Z0-808 exam, you can complete Oracle's Java SE 8 Fundamentals certification. The time to prepare for the Oracle Java SE 8 Programmer I (1Z0-808) certification exam can differ depending on your Java programming knowledge and experience. For a fresher with basic programming knowledge, the ideal time for preparation is two months if they spend considerable time in a day on the practices.

For those with reasonably good knowledge and experience in Java, this time can be decreased to one month or even 15 days, depending on your learning speed and the time allocated for daily practice. For a novice who has yet to learn about Java or Object Oriented Programming, the time required for learning can go up to 6 months since they have to understand the programming concepts and then move on to Java-specific learning.

Steps That Can Help You in Your Journey to the Oracle 1Z0-808 Certification

The preparations require focus, effort, and time. Incorporate the steps mentioned here as a part of your daily routine by allocating a regular and fixed time spot that can be quickly followed:

1. Understand the 1Z0-808 Syllabus

The primary step is to get the entire syllabus of the 1Z0-808 exam. This will give you a detailed insight into the topics you must cover within the set time frame. A study plan can be prepared based on the number of topics and the time needed to complete each section.

2. Collect Resources

Once you are familiar with the Java SE 8 Programmer I syllabus and the topics, gathering helpful resources is next. These could include books as well as online resources.

3. Join Java Forums and Communities

It is always a good idea to join a popular forum or community where you can post questions and doubts and get them answered by experts. This will also help you get new ideas, practical solutions, and tips that can significantly assist you while taking the mock tests and the 1Z0-808 certification exam. You can also read blogs by community members.

4. Practice 1Z0-808 Practice Tests

As important as daily coding sessions are the 1Z0-808 practice tests. Only by taking as many tests as possible can you master the technique of completing the actual Java SE 8 Programmer I exam in the prescribed time. Almost all guides have 1Z0-808 practice tests you can solve by timing yourself. Other than these, there is a plethora of online sites that offer practice tests for aspirants.

5. Revision

Revising the lessons is the ultimate step in preparing for the Oracle Java SE 8 Programmer I certification exam. You would not want to waste precious time going through all the books you have covered in the last few months. Revision means remembering the main points of each chapter. It is here the notes and tips you have prepared become handy. Recap all the essential facts, practice coding, and take 1Z0-808 mock tests until the last minute.

Closing Words

These steps are just a guide for your preparations. Learning strategies can change as per personal preferences and the time required to master a concept. Prepare entirely, stay calm, and take the Oracle 1Z0-808 Java SE 8 Programmer I test confidently.

Quiz yourself: The truth about Java enums

Java enums, Oracle Java Exam, Oracle Java Prep, Oracle Java Career, Oracle Java Skills, Oracle Java Skills, Oracle Java Prep


Which statements about enums are correct? Choose two.


A. You cannot declare a final method in the enum type.
B. You can declare an abstract method in the enum type.
C. enum instances are immutable.
D. You can override the equals method to implement your own comparison based on an enum constant’s state.
E. enum members with protected access modifiers cannot be accessed outside an enum’s own package.

Answer. The goal of the enum concept is to provide a specific number of instances of a given type. That number is fixed in the source code, and each instance has a well-defined name in the code.

Enums have a common parent class. It’s prohibited to describe another class as extends any enum. This rule ensures that no other class can be defined from which objects can be created that are assignment-compatible with the enum type. After all, if you were allowed to define new classes compatible with the enum type, you could then arbitrarily add new objects beyond the intended set of instances.

In addition, controls are imposed on any enum to ensure that deserialization and other behaviors do not create new, unintended instances.

Supporting these ideas is one of the effects of having the common parent class—but note that the enum must not declare that it extends that parent class. Instead, this happens automatically because of the use of the enum keyword in place of the class keyword.

These initial ideas have some consequences that are relevant to determining the answer to this question.

Option A suggests that you cannot declare a final method in an enum type. At first glance doing so might seem pointless, since the enum seems to be final. However, you can, in fact, define subtypes of the enum, provided you do so directly within the enum type itself, in the context of one of the instances.

It’s probably helpful to emphasize the distinction between the enum type and the instances of the enum.

Consider the sample code below; the enum type called Type has two instances: One is referred to using the reference GOOD, and the other is referred to using the reference BAD. However, the syntax used here, where GOOD is followed by curly braces, actually means that GOOD refers to an instance of an anonymous subtype of Type. Given that the example defines the doIt() method in the enum type Type as being final, this prevents overriding of that method in GOOD.

enum Type {
    GOOD {}, // cannot override doIt here
    BAD;
    final void doIt() {} // OK
}

Since subclassing the enum is possible, although only under these very specific syntactic constraints, it’s not unreasonable to declare a method as final, and it is, in fact, permitted. From this, it’s clear that option A is incorrect.

Now that you know that limited subtyping is possible with enum types, it’s reasonable to expect that you can usefully declare an abstract method inside an enum type, and that expectation is correct. In such a situation you must provide an implementation of the abstract method inside each enum constant’s body. You must not leave any abstract method unimplemented, because the enum type may not itself be declared as abstract.

enum Type { // cannot have abstract modifier
    GOOD {
        String describe() { return "Good"; }
    },
    BAD {
        String describe() { return "Not good"; }
    };
    // this is valid provided all the above objects implement
    // the method 
    abstract String describe(); 
}

From this you know that option B is correct.

An enum guarantees a specific number of instances of the type but does not guarantee immutability. Guaranteeing immutability is the responsibility of the developer. An enum constant is really a public static final reference to an instance of the enum type. While that reference cannot be modified, the object to which it refers might be mutable. This can happen if the enum is declared in such a way that it contains a mutable field, and the following code illustrates this:

enum Type {
    GOOD,
    BAD;
    // description is not final, so it can be modified
    public String description; 
    String describe() { return description; }
}

In this example, the public String field named description could be reassigned to refer to a different String object. Similarly, if the field were declared to be of the StringBuilder type, the contents of that object would be intrinsically mutable. From this you can see that option C is incorrect.

Option D is also incorrect: Each enum type implicitly inherits from the java.lang.Enum class, which already has some final methods, in particular, the following:

◉ compareTo()
◉ equals()
◉ hashCode()
◉ name()
◉ ordinal()

Because the equals() method is final in the base type Enum, you cannot override it, and you cannot implement your own comparison logic. The inherited implementation looks like this.

public final boolean equals(Object other) {
  return this==other;
}

Option E is correct, as protected members of Java classes (including enums) can be accessed only in a different package if the access is performed in a subtype that’s declared in that other package.

However, subclasses of an enum must be nested, that is, declared inside the top-level curly braces that contain the body of the enum declaration. Because of that, the subtypes of an enum cannot possibly be in a different package. Consequently, all protected members can be accessed only from the enum’s package and not from external packages. Their access is, therefore, indistinguishable from what it would be if they were declared with default accessibility, that is, without any explicit modifier.

Conclusion. The correct answers are options B and E.

Source: oracle.com

Friday, November 11, 2022

Curly Braces #6: Recursion and tail-call optimization


Over the years, I’ve come to appreciate the power of recursion, yet I have two minor gripes with it.

First, there is one part of every recursive call that jumps out at me as inelegant: the base case, also known as the escape clause.

Let’s look at the classic factorial example in Java.

int factorial(int n) {
        if (n <= 1) // Base case
            return 1; 
        return n * factorial(n - 1); // Recursive case
    }

Here’s the point: factorial is recursive except when it reaches the base case. Yes, I’m nitpicking—and mostly joking.

My second gripe is a more serious one: In practice, I rarely witness the use of recursion. The recursion use cases that stand out to me include XML parsing as well as code that handles hierarchical data in general. For instance, I once came across a neat piece of code that walked a TreeMap using a two-method recursive implementation. The fact that it involved two methods that repeatedly called each other blew developers’ minds. (The code also wasn’t commented.)

This implementation was beautiful. I still see, in my head, these two methods of equal size accomplishing an astonishing amount of work with so little code. This was true recursive power.

Of course, there are other valid uses of recursion in Java, such as in searching, sorting (see the Towers of Hanoi problem), and machine learning (due to the hierarchical structure of applicable datasets). But the truth is, due to stack concerns and the perceived complexity of recursion, Java developers generally write loop-centered algorithms instead.

Introducing the tail call


If the use of recursion is not common in the Java community, why write about it? Because Java is more than a language. It’s a platform based on a virtual machine, and the JVM supports other languages beyond Java. Some of those languages, such as Groovy, rely heavily on recursion.

Many functional language interpreters contain an optimization for recursion to save stack space based on tail calls. A tail call is when a method or function call is the last instruction inside of another method or function. (For simplicity, I’ll refer to all calls as function calls.)

Consider the function foo(), as defined as follows:

int foo(int a) {
  a = a + 1;
  return func(a);
}

The call to function func() is the last statement in function foo(); therefore, it’s a tail call. If foo() executed any instructions after the return call to func(), then func() would no longer be referred to as a tail call. Here’s an example where the recursive function is also a tail call.

int fact(int i, int acc) {
      if ( i == 0 ) 
        return acc;
      else
        return fact( i – 1, acc * i);
    }
    
    int factorial(int n) {
      if ( n == 0 )
        return 1;
      else
        return fact( n – 1, 1 );
    }

If you compile this code with a C compiler and debug it, you can examine the assembly code as it executes (see Figure 1). The red arrow points to the last two instructions for the function fact(), which are the call to fact() itself and retq for the return statement. This fits the definition of a tail call. (I generated this view using NetBeans; while I was debugging, I chose the Disassembly submenu option under Window > Debugging.)

Oracle Java, Java Career, Java Prep, Java Certification, Oracle Java Guides, Java Jobs, Java Prep, Java Preparation

Figure 1. Function fact() is a recursive tail call, as shown by the assembly code.

I chose to illustrate this example in C because it was easier to show the associated assembly code, but the same holds true for Java. In fact, you can copy this code into a Java class verbatim, and it will compile and work the same way.

Now, it’s time to optimize these functions, and there can be a significant benefit.

Tail-call optimization


Tail-call optimization (TCO) is very relevant for recursive calls, and the topic has become important in functional programming. You see, with any tail call—not just a recursive one—the function call itself can be optimized away and turned into what is effectively a goto. The benefit is that the optimization eliminates all the work required to set up the stack before the function call (the prolog) and then restore the stack afterwards (the epilog).

Consider the following code:

int func_a(int data) {
  data = do_this(data);
  return do_that(data);
}

The function do_that() is a tail call, and its nonoptimized assembly code might look something like the following:

... ! executing inside func_a()
push EIP ! push current instruction pointer on stack
push data ! push variable 'data' on the stack
jmp do_this ! call do_this() by jumping to its address
... ! executing inside do_this()
push EIP ! push current instruction pointer on stack
push data ! push variable 'data' on the stack
jmp do_that ! call do_that() by jumping to its address
... ! executing inside do_that()
pop data ! prepare to return value of 'data'
pop EIP ! return to do_this()
pop data ! prepare to return value of 'data'
pop EIP ! return to func_a()
pop data ! prepare to return value of 'data'
pop EIP ! return to func_a() caller
...

Notice the multiple pop instructions for both data and EIP (extended instruction pointer) register occurring in succession. The EIP register returns the value of data and restores the instruction pointer. One set of these epilogs and its associated prolog (where data and the EIP register are saved on the stack) could be eliminated and replaced by a simple jump (JMP) assembly instruction. This optimization can be done because the function do_that() will execute the epilog code for the calling function, func_a().

This optimization is safe because func_a() doesn’t perform any meaningful instructions after do_that() returns, because it’s a tail call. (Recall that if something were done with the return value after the call to do_that() returns, this optimization cannot be performed because do_that() would no longer be a tail call.)

Here’s the result of TCO; the crossed-out lines indicate instructions that were removed.

Oracle Java, Java Career, Java Prep, Java Certification, Oracle Java Guides, Java Jobs, Java Prep, Java Preparation

Shown slightly differently, this is the code before TCO.

Oracle Java, Java Career, Java Prep, Java Certification, Oracle Java Guides, Java Jobs, Java Prep, Java Preparation

Here it is again after TCO.

Oracle Java, Java Career, Java Prep, Java Certification, Oracle Java Guides, Java Jobs, Java Prep, Java Preparation

Comparing the shaded row in both, you can see how much less machine code there is to run in the optimized version.

Reducing the amount of code is good, but it’s not the biggest reason for preferring the optimized version. The real benefits appear when you combine TCO with recursion.

If you review the recursive factorial example shown earlier, you can see that when it is combined with this optimization, all the prolog and epilog assembly code that would be needed repeatedly can be removed. Such optimization effectively turns the following recursive pseudocode, which I’ve taken from a Wikipedia example

call factorial(3)
  call fact(3,1)
    call fact(2,3)
      call fact(1,6)
        call fact(0,6)
        return 6
      return 6
    return 6
  return 6
return 6

into this iterative pseudocode

call factorial(3)
  call fact(3,1)
  update variables with (2,3)
  update variables with (1,6)
  update variables with (0,6)
  return 6
return 6

In other words, TCO replaces the recursive code with a loop, which goes back to the observation that many Java developers would prefer to use loops instead of recursion. This optimization reduces the function call prolog and epilog assembly code for numerous recursive calls, and it also greatly reduces pressure on the stack.

Without this optimization, calculating the factorial of very large numbers (or doing other large recursive operations) would likely blow the stack. Reducing the algorithms to a loop in the compiled code removes that risk. This is why most functional language interpreters perform TCO behind the scenes.

Java and TCO


I spoke to Brian Goetz, the Java language architect at Oracle, about TCO back in 2014. At the time, he told me that it’s on a list of things to be added to the JVM. I caught up with him recently to discuss the topic, and he said that while progress has been made, and more may occur in the future, TCO hasn’t been fully implemented due to some security concerns.

Mark Reinhold, chief architect of the Java Platform Group at Oracle, recently was quoted saying the following:

It’s not clear to me that we would ever want to expose tail calls and continuations in the platform for general use but there may be ways we could use them inside the platform, in some fairly interesting ways.

It isn’t a big deal to most developers writing Java code that the JVM doesn’t fully perform TCO, because Java programmers tend to avoid recursion through the use of loops. For instance, here’s an iterative implementation of factorial in Java.

int factorial(int n) {
  int result = 1;
  for (int t=n; t > 1; t--)
      result *= t;
  return result;
}

However, the lack of TCO does become an issue when you run functional languages (such as Groovy) within the JVM. Then, recursive code that ran fine with that language’s native interpreter may blow the stack when it’s executed in the JVM.

It’s important to note that this isn’t a bug in the JVM. Still, for now, it’s best to do TCO yourself, if you can, by avoiding deeply recursive functions when you’re coding in a functional language on the JVM.

Source: oracle.com

Wednesday, November 9, 2022

The Arrival of Java 19

The arrival of Java 19!


Oracle is proud to announce the general availability of JDK 19. This release is the tenth Feature Release delivered on time through the six-month release cadence. This level of predictability allows developers to easily manage their adoption of innovation thanks to a steady stream of expected changes.

Java 19, Core Java, Oracle Java, Oracle Java Certification, Oracle Java Prep, Oracle Java Preparation, Oracle Java Skills, Java Jobs, Java Tutorial and Mateirals

Java’s ability to boost performance, stability, and security continues to make it the world’s most popular programming language. According to an IDC report more than 10 million developers – representing 75% of full-time developers worldwide – use Java.

JDK 19 is now available!


Oracle now offers JDK 19 for developers, end-users, and enterprises. Oracle JDK 19 will receive performance, stability and security updates following the Oracle Critical Patch Update (CPU) schedule as outlined in the Oracle Java SE Support Roadmap.

Oracle JDK 19 is not a long-term support (LTS) release. Oracle JDK 17 (announced on September 14, 2021) is the second LTS  under the release cadence announced in 2018. Oracle has announced plans to shorten the time between future LTS releases, from three years to two years so you should expect the next LTS to be Java 21 in September of 2023.

Another important change announced with Oracle JDK 17 was the introduction of a new and simpler license terms which will allow companies to use Oracle JDK 17 – including the quarterly performance, stability, and security patches – at no cost for at least the next three years, allowing one full year of overlap with the next LTS release. Java SE subscribers get access to Oracle’s Java SE Support and commercial features such as GraalVM Enterprise, Java Management Service and the Advanced Management Console.

Java 19, Together


As with previous releases, with Java 19 we continue to celebrate the contributions from many individuals and organizations in the OpenJDK Community — we all build Java, together!

JDK 19 Fix Ratio

The rate of change over time in the JDK releases has remained largely constant for years, but under the six-month cadence the pace at which production-ready features and improvements are delivered has vastly improved.

Instead of making tens of thousands of fixes and delivering close to one hundred JEPs (JDK Enhancement Proposals) every few years as we did with yesteryear Major Releases, enhancements are delivered in leaner Feature Releases on a more manageable, predictable six-month schedule. The changes range from significant new features to small enhancements to routine maintenance, bug fixes, and documentation improvements. Each change is represented in a single commit for a single issue in the JDK Bug System.

Of the 19,297 JIRA issues marked as fixed in Java 11 through Java 19 at the time of their GA, 13,825 were completed by people working for Oracle while 5,472 were contributed by individual developers and developers working for other organizations. Going through the issues and collating the organization data from assignees results in the following chart of organizations sponsoring the development of contributions in Java:

Java 19, Core Java, Oracle Java, Oracle Java Certification, Oracle Java Prep, Oracle Java Preparation, Oracle Java Skills, Java Jobs, Java Tutorial and Mateirals

In Java 19, of the 1,962 JIRA issues marked as fixed, 1,383 were completed by Oracle, while 579 were contributed by other members of the Java community.

Oracle would like to thank the developers working for organizations including Alibaba, Amazon, ARM, Huawei, IBM, Intel, JetBrains, NTT Data, Red Hat, SAP and Tencent for their notable contributions. We are also thankful to see contributions from smaller organizations such as Bellsoft, DataDog, Loongson, and Skymatic, as well as independent developers who collectively contributed 6% of the fixes in Java 19.

We are equally grateful to the many experienced developers who reviewed proposed changes, the early adopters who tried out early access builds and reported issues, and the dedicated professionals who provided feedback on the OpenJDK mailing lists. 

The following individuals provided invaluable feedback on build quality, logged good quality bugs, or offered frequent updates:

◉ Uwe Schindler (Apache Lucene)
◉ Martin Grigorov (Apache Tomcat, Apache Wicket)
◉ Rafael Winterhalter (Byte Buddy)
◉ Yoann Rodière (Hibernate ORM, Validator, Search, Reactive)
◉ Marc Hoffman (JaCoCo)
◉ Lukas Eder (JOOQ)

Additionally, through the Quality Outreach program we would like to thank the following FOSS projects and individuals who provided excellent feedback on testing Java 19 early access builds to help improve the quality of the release:

◉ Apache Derby (Rick Hillegas)
◉ Apache Zookeeper (Enrico Olivelli)
◉ BNYM Code Katas (Rinat Gatyatullin)
◉ RxJava (David Karnok)
◉ Apache Johnzon
◉ JobRunr
◉ MyBatis
◉ Renaissance

New in Java 19


Along with thousands of performance, stability and security updates, Java 19 delivers dozens of new features and enhancements, seven enhancements/changes rise to the level of being managed through the JDK Enhancement Proposals - JEPs process, including four preview features and two incubator features.

Some new features not requiring a JEP include new (D)TLS Signature Schemes, support for Unicode 14.0, additional DateTime formats and PAC-RET Protection on AArch64 systems.  Full details of these and many other new features can be found at https://jdk.java.net/19/release-notes.

JEP Preview Features are fully specified and fully implemented Language or VM Features of the Java SE Platform; and yet impermanent. They are made available in JDK Feature Releases to allow for developer feedback based on real-world uses, before them becoming permanent in a future release. This also affords tool vendors the opportunity to work towards supporting features before they are finalized into the Java SE Standard.

JEP Incubator modules allow putting non-final APIs and non-final tools in the hands of developers and users to gather feedback that will ultimately improve the quality of the Java platform.

The seven JEPs delivered with Java 19 are grouped into four categories mapping to key long-term Java technology projects and hardware support.

Project Amber



Improves developer productivity by extending pattern matching to express more sophisticated, composable data queries. This is done by enhancing the Java programming language with record patterns to deconstruct record values. Record patterns and type patterns can be nested to enable a powerful, declarative, and composable form of data navigation and processing.

JEP 405 relates to:

- [JDK 19] JEP 427: Pattern Matching for switch (3rd Preview)


Improves developer productivity by improving Java’s code semantics. This is done by enhancing the Java programming language with pattern matching for switch expressions and statements. Extending pattern matching to switch allows an expression to be tested against a number of patterns, each with a specific action, so that complex data-oriented queries can be expressed concisely and safely.

JEP 427 relates to:

- [JDK 17] JEP 406: Pattern Matching for switch (Preview)
- [JDK 18] JEP 420: Pattern Matching for switch (Second Preview)
- [JDK 19] JEP 405: Record Patterns (Preview)
 

Project Panama



The Foreign Function & Memory API offers value in four unique ways:

Ease of use — Replaces the Java Native Interface (JNI) with a superior, pure-Java development model.

Performance — Provides performance that is comparable to, if not better than, existing APIs such as JNI and sun.misc.Unsafe.

Generality — Provides ways to operate on different kinds of foreign memory (e.g., native memory, persistent memory, and managed heap memory) and, over time, to accommodate other platforms (e.g., 32-bit x86) and foreign functions written in languages other than C (e.g., C++, Fortran).

Safety — Allows programs to perform unsafe operations on foreign memory but warn users about such operations by default.

The Foreign Function & Memory API introduces an API by which Java programs can interoperate with code and data outside of the Java runtime. By efficiently invoking foreign functions (i.e., code outside the JVM), and by safely accessing foreign memory (i.e., memory not managed by the JVM), the API enables Java programs to call native libraries and process native data without the brittleness and danger of JNI.

JEP 424 relates to:

- [JDK 18] JEP 419: Foreign Function & Memory API (Second Incubator)
- [JDK 17] JEP 412: Foreign Function & Memory API (Incubator)


Improves performance achieving performance superior to equivalent scalar computations. This is done by Introducing an API to express vector computations that reliably compile at runtime to optimal vector instructions on supported CPU architectures, thus achieving performance superior to equivalent scalar computations. Vector APIs were incubated in JDK 16, 17, and 18. JDK 19 incorporates feedback from users of those releases as well as performance improvements and implementation enhancements. It uses some of the Foreign Function and Memory APIs which are now mature enough to create this dependency.

JEP 426 relates to:

- [JDK 16] JEP 338: Vector API (Incubator)
- [JDK 17] JEP 414: Vector API (Second Incubator)
- [JDK 18] JEP 417: Vector API (Third Incubator)

Project Loom



Virtual Threads are lightweight threads that dramaticaly reduce the effort of writing, maintaining, and observing high-throughput concurrent applications.

Virtual Threads is the first JEP as part of Project Loom. Project Loom upgrades the Java concurrency model to meet the needs of today’s high-scale server applications.

There are a lot of great things about Java’s threads. They offer a natural programming model, with readable, sequential code using control flow operators that users understand – loops, conditionals, exceptions. Users get great debugging and serviceability, and readable stack traces. And threads are natural units of scheduling for OSes. We want to retain these advantages. 

The problem is that the implementation of threads by the OS is too heavyweight. It takes too long to start a thread for each connection, but worse, the number of threads the OS can support at any one time limits the number of concurrent transactions a server can handle — to well below the capacity of the hardware or the network — and so threads become a severe constraining factor on server throughput.

Many people assumed we would embrace the asynchronous programming style offered by so-called “reactive” frameworks. By not representing concurrent operations directly as threads, it does scale beyond the limits posed by the thread-per-request model, but at a huge cost – much more complicated code that is harder to write, harder to read, and much harder to debug or profile because the platform in all its layers and its tools, is built around threads. Reactive may be the best people can do with the current JVM, but our goal is to do better, which we can do by making threads lighter and more scalable, letting developers keep using the model and tooling they’ve been using successfully for years.

Developers today have three bad options: waste hardware through underutilization, waste programmer effort with worse programming models and observability, or switch away from Java. So, Project Loom offers developers a better option.

Project Loom timeline:

- Late 2017: Work on Loom begins
- Jul 2019: EA build of Fiber prototype released for feedback
- Sept 2019: JEP 353 (Reimplement Legacy Socket API) shipped in JDK 13
- Sept 2020: JEP 373 (Reimplement Legacy DatagramSocket API) shipped in JDK 15
- Nov 2021: Early Access builds of structured concurrency support released for feedback
- Nov 2021: Draft JEPs for virtual threads and for structured concurrency published for comment
- Mar 2022: JEP 418 (Internet Address Resolution SPI) shipped in JDK 18
- Sep 2022: Preview in JDK 19
 

Structured Concurrency simplifies multithreaded programming by introducing an API for structured concurrency. Structured Concurrency treats multipe tasks running in different threads as a single unit of work, thereby streamling error handling and cancellation, improving reliability, and enhancing observability.

New Port



Ports the JDK to the Linux/RISC-V architecture. RISC-V is a free and open-source RISC instruction set architecture (ISA) designed originally at the University of California, Berkeley, and now developed collaboratively under the sponsorship of RISC-V International. It is already supported by a wide range of language toolchains. With the increasing availability of RISC-V hardware, a port of the JDK offers value to developers.

Source: oracle.com

Monday, November 7, 2022

Troubleshooting deadlock in an Apache opensource library

Apache PDFBox is a popular open-source library that facilitates java applications to work with PDF documents. Recently we encountered a Deadlock that surfaced in this library. In this post we have shared how we troubleshooted and identified the root cause of the problem.

What is Deadlock?


First let’s try to understand what ‘Deadlock’ means. Several technical definitions aren’t clear. ‘Deadlock’ definition is one among them :-). Deadlock’s definition goes like this: “Deadlock is a situation where a set of processes are blocked because each process is holding a resource and waiting for another resource acquired by some other process.” It’s always easier to learn something new through examples and pictures. Let’s look at the below practical example, which may help you to understand Deadlock better.

Core Java, Java Exam Prep, Java Tutorial and Materials, Java Prep, Java Preparation, Java Certification, Java Career, Java skill

Core Java, Java Exam Prep, Java Tutorial and Materials, Java Prep, Java Preparation, Java Certification, Java Career, Java skill

Let’s say there is only one train track, and this train track has six parts(part-1, part-2, part-3, part-4, part-5, part-6). Train-A starts at part-1 and Train-B starts at Part-6 on the same train track at the same time. Both trains travel at the same speed. Under this circumstance, Train-A and Train-B will reach a Deadlock state when they reach part-3 and part-4 of the train track. Because when Train-A is in part-3 of the train track, it will be stuck waiting for part-4 of the track, which Train-B holds. On the other hand, when Train-B is in part-4, it will be stuck waiting for part-3, which Train-A holds. Thus, both the trains can’t move forward. This is a classic Deadlock situation. Similarly, once a Deadlock happens in the application, it cannot be recovered. The only way to recover from Deadlock is to restart the application.

Troubleshooting Deadlock


Now let’s discuss about the Deadlock problem we faced in the application. From the above explanation you can understand that Deadlock is caused due to threads. Thus, to analyze Deadlock, you need to capture thread dump from the application. Thread dump is basically a snapshot of all threads that are running in your application. It contains information such as: stack trace, thread state, thread priority, … You can capture thread dump using one of the approaches given here.

Note: Most of the time, you will not know whether the actual problem in your application is deadlock or not. What you will notice is unresponsiveness from the application. Thus, it’s safe to capture all the prominent artifacts that are essential for troubleshooting such as: Garbage Collection log, thread dump, heap dump, netstat, iostat,… you may use yCrash open source script, which would capture 360-degree data (GC log, 3 snapshots of thread dump, heap dump, netstat, iostat, vmstat, top, top -H,…) from your application stack within a minute and generate a bundle zip file.

We uploaded the captured thread dump to fastThread – a thread dump analysis tool. Tool immediately pointed out that the two threads caused the deadlock. Below is the excerpt from the fastThread report.

Core Java, Java Exam Prep, Java Tutorial and Materials, Java Prep, Java Preparation, Java Certification, Java Career, Java skill

Tool pointed out the stack trace of the two threads that were in deadlock. Below is the stack trace of those two threads:

"APP_Thread_50_WorkerTask_pool-5-thread-6" #1899 prio=5 os_prio=0 tid=0x00007f894c405555 nid=0x44d1 waiting for monitor entry [0x00007f88e9c44000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at org.apache.fontbox.ttf.TrueTypeFont.getTable(TrueTypeFont.java:147)
    - waiting to lock <0x00000002d216fec8> (a org.apache.fontbox.ttf.TrueTypeFont)
    at org.apache.fontbox.ttf.TrueTypeFont.getHorizontalMetrics(TrueTypeFont.java:229)
    at org.apache.fontbox.ttf.GlyphTable.getGlyphData(GlyphTable.java:210)
    at org.apache.fontbox.ttf.GlyphTable.getGlyph(GlyphTable.java:191)
    - locked <0x00000002d218ca28> (a org.apache.fontbox.ttf.RAFDataStream)
    at org.apache.fontbox.ttf.TrueTypeFont.getPath(TrueTypeFont.java:676)
    at org.apache.pdfbox.pdmodel.font.PDType1Font.getPath(PDType1Font.java:638)
    at org.apache.pdfbox.rendering.Type1Glyph2D.getPathForCharacterCode(Type1Glyph2D.java:83)
    at org.apache.pdfbox.rendering.PageDrawer.drawGlyph2D(PageDrawer.java:495)
    at org.apache.pdfbox.rendering.PageDrawer.showFontGlyph(PageDrawer.java:476)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.showGlyph(PDFStreamEngine.java:787)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.showGlyph(PDFStreamEngine.java:805)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.showText(PDFStreamEngine.java:743)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.showTextString(PDFStreamEngine.java:606)
    at org.apache.pdfbox.Contentstream.operator.text.ShowText.process(ShowText.java:56)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.processOperator(PDFStreamEngine.java:933)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.processStreamOperators(PDFStreamEngine.java:514)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.processStream(PDFStreamEngine.java:492)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.processPage(PDFStreamEngine.java:155)
    at org.apache.pdfbox.rendering.PageDrawer.drawPage(PageDrawer.java:277)
    at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:347)
    at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:268)
    at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:228)
    at xxxxxxx.export.service.thumbnail.PDFSlideGeneratorServiceImpl$1.call(PDFSlideGeneratorServiceImpl.java:60)
    at xxxxxxx.ops.executor.util.ParallelExecutorTask.doCall(ParallelExecutorTask.java:43)
    at xxxxxxx.ops.executor.util.ParallelExecutor.executeTaskFromQueue(ParallelExecutor.java:154)
    at xxxxxxx.ops.executor.util.ParallelExecutor.access$100(ParallelExecutor.java:26)
    at xxxxxxx.ops.executor.util.ParallelExecutor$WorkerTask.doCall(ParallelExecutor.java:164)
    at xxxxxxx.ops.executor.util.UserContextAwareCallable.call(UserContextAwareCallable.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"APP_Thread_WorkerTask_APP-pool-5-thread-5" #1898 prio=5 os_prio=0 tid=0x00007f894c898900 nid=0x44d0 waiting for monitor entry [0x00007f88e9d45000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at org.apache.fontbox.ttf.TrueTypeFont.readTable(TrueTypeFont.java:356)
    - waiting to lock <0x00000002d218ca28> (a org.apache.fontbox.ttf.RAFDataStream)
    at org.apache.fontbox.ttf.TrueTypeFont.getTable(TrueTypeFont.java:150)
    - locked <0x00000002d216fec8> (a org.apache.fontbox.ttf.TrueTypeFont)
    at org.apache.fontbox.ttf.TrueTypeFont.getCmap(TrueTypeFont.java:262)
    at org.apache.fontbox.ttf.TrueTypeFont.getUnicodeCmapImpl(TrueTypeFont.java:556)
    at org.apache.fontbox.ttf.TrueTypeFont.getUnicodeCmapLookup(TrueTypeFont.java:541)
    at org.apache.fontbox.ttf.TrueTypeFont.nameToGID(TrueTypeFont.java:629)
    at org.apache.fontbox.ttf.TrueTypeFont.hasGlyph(TrueTypeFont.java:698)
    at org.apache.pdfbox.pdmodel.font.PDType1Font.getNameInFont(PDType1Font.java:601)
    at org.apache.pdfbox.pdmodel.font.PDType1Font.hasGlyph(PDType1Font.java:645)
    at org.apache.pdfbox.rendering.Type1Glyph2D.getPathForCharacterCode(Type1Glyph2D.java:59)
    at org.apache.pdfbox.rendering.PageDrawer.drawGlyph2D(PageDrawer.java:495)
    at org.apache.pdfbox.rendering.PageDrawer.showFontGlyph(PageDrawer.java:476)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.showGlyph(PDFStreamEngine.java:787)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.showGlyph(PDFStreamEngine.java:805)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.showText(PDFStreamEngine.java:743)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.showTextString(PDFStreamEngine.java:606)
    at org.apache.pdfbox.Contentstream.operator.text.ShowText.process(ShowText.java:56)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.processOperator(PDFStreamEngine.java:933)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.processStreamOperators(PDFStreamEngine.java:514)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.processStream(PDFStreamEngine.java:492)
    at org.apache.pdfbox.Contentstream.PDFStreamEngine.processPage(PDFStreamEngine.java:155)
    at org.apache.pdfbox.rendering.PageDrawer.drawPage(PageDrawer.java:277)
    at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:347)
    at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:268)
    at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:228)
    at xxxxxxx.export.service.thumbnail.PDFSlideGeneratorServiceImpl$1.call(PDFSlideGeneratorServiceImpl.java:60)
    at xxxxxxx.ops.executor.util.ParallelExecutorTask.doCall(ParallelExecutorTask.java:43)
    at xxxxxxx.ops.executor.util.ParallelExecutor.executeTaskFromQueue(ParallelExecutor.java:154)
    at xxxxxxx.ops.executor.util.ParallelExecutor.access$100(ParallelExecutor.java:26)
    at xxxxxxx.ops.executor.util.ParallelExecutor$WorkerTask.doCall(ParallelExecutor.java:164)
    at xxxxxxx.ops.executor.util.UserContextAwareCallable.call(UserContextAwareCallable.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

You can see the ‘APP_Thread_50_WorkerTask_pool-5-thread-6’ thread is in Deadlock with ‘APP_Thread_50_WorkerTask_pool-5-thread-5’ thread. From the stacktrace you can observe following two things:

1. ‘APP_Thread_50_WorkerTask_pool-5-thread-6’ has acquired the lock ‘0x00000002d218ca28’ of the ‘org.apache.fontbox.ttf.RAFDataStream’ object and waiting to acquire the lock ‘0x00000002d216fec8’ of the ‘org.apache.fontbox.ttf.TrueTypeFont’ object. 

2. On the other hand, ‘APP_Thread_50_WorkerTask_pool-5-thread-5’ thread is trying to do the exact opposite, it acquired the lock ‘0x00000002d216fec8’ of ‘org.apache.fontbox.ttf.TrueTypeFont’ object and waiting to acquire the lock ‘0x00000002d218ca28’ of the ‘org.apache.fontbox.ttf.RAFDataStream’ object. 

Indeed, it’s a classic Deadlock condition. 

Deadlock in Apache PDFBox

If you notice two objects which are causing Deadlock are ‘org.apache.fontbox.ttf.TrueTypeFont’ and ‘org.apache.fontbox.ttf.RAFDataStream’. Both of these objects are originating from the open source Apache PDFBox library.

Once seeing this bug, we searched in the Apache PDFBox bug database to see whether this problem was already reported or not. We couldn’t see this problem reported earlier. Thus, we went ahead and filed a new ticket in the Apache bug database with the details. Here is the ticket that we filed, for your reference. The Apache PDFBox development team was highly responsive. They started acting on it right away and issued a fix within 2 – 3 days. Great job from the PDFBox team. Truly enjoyed the open source community collaboration.

Source: javacodegeeks.com

Wednesday, November 2, 2022

Taking Java to OCI

Java to OCI, Oracle Java Exam, Oracle Java Prep, Oracle Java Career, Java Jobs, Java Skills, Java Tutorial and Materials

I first started working with Java some time in 1997, which is quite a scary thought in some ways.  In other ways though, it’s quite a comforting thought – the language that I learned then is going strong and continues to grow and evolve.

Today Java is the most widely used software development language and platform in the world.

Since the late 90s, both Java and the world have been through some pretty profound changes.  In terms of IT, one of the most obvious is the rise of cloud.

When we think about the cloud and Java, according to a 2021 VDC study:

◉ Java is viewed as the most important language for cloud.
◉ Java is the #1 language developers expect to be using in three years time.
◉ In 2020 there were 56 billion active JVMs worldwide, 60.5% of them in the cloud.  By 2025, there are predicted to be 82 billion, with 74.2% in the cloud.

So, Java’s footprint in the cloud is big and expanding, and developers are betting on Java to keep themselves relevant and employable.

When we look at Oracle’s cloud, OCI, we see that Java is by far the most popular SDK used by developers

When developers choose to use Java in OCI they get all the benefits of a Java SE Subscription at no additional cost.  This means they can unlock additional value and benefits for themselves and their businesses.

One of these is the Java Management Service.  This helps DevOps teams and administrators understand what Java workloads they have deployed, which JDK version and the origin of the JDK.

If they are using the Oracle JDK they can get additional insight into the security state (whether it needs patching) and the applications that are running on top of it.

Oracle is the steward and #1 contributor to Java and the OpenJDK project.

However, many organisations want more than just the Java binaries that they get with OpenJDK.  They are looking for security, patching, support and expert advice on upgrades and application performance.

They may want the flexibility to carry on running existing applications on older versions of Java, so they can upgrade at their own pace or focus development resources on building new applications rather than upgrading old ones.

They may want to enhance the performance of their applications by running them using the latest versions of Java or GraalVM Enterprise.

For on premises customers, these benefits are available through the Java SE subscription.

For OCI customers they are included OOTB.

So you can migrate existing applications to OCI, or develop new ones on OCI and take advantage of these benefits.

As both a cloud provider and the steward and leading contributor to Java, Oracle is uniquely placed to deliver an optimised Java cloud platform and experience.

I’ve witnessed at first hand some of the joint engineering efforts and I think it’s tremendously exciting.

With the new possibilities that Java and GraalVM provide to developers such as the management service, performance benefits, support for older versions of Java and expert advice from the creators of Java, OCI really is the best cloud for your Java workloads.

If you are interested in building and deploying your Java application on OCI, you can start from this introductory hands-on content repository, including architecture best practice for: microservices-based RESTfull applications; modern web and mobile applications; serverless applications; and an introduction to GraalVM.

When you are ready to start testing Java on OCI, you can access the advanced hands-on content repository, including deployment automation code to set up some of the most popular architectures in a Free Trial Oracle Cloud account (e.g. an Apache Tomcat server connected to MySQL Database Service; a CI/CD pipeline for cloud deployments by using GitHub; microservices with a converged database).

If you need any help with the technical resources in the content repository, feel free to reach out to us via our public slack workspace dedicated to developers – and post your questions to the Java channel.

Source: oracle.com