Jakarta Going Forward

The agreement between the Eclipse Foundation and Oracle regarding rights to Java trademarks has been signed! This is truly an important milestone for Jakarta EE since we will now be able to move forward with Jakarta EE.

As outlined in https://eclipse-foundation.blog/jakarta-ee-java-trademarks, there are two major areas of impact on the Jakarta EE projects:

  • Java Trademarks
  • The javax.* Namespace

Java Trademarks

One part of the agreement is regarding the use of Java trademarks. The implications for Jakarta EE is that we have to rename the specifications and the specification projects. This work is ongoing and is tracked in our specification renaming board on GitHub. The EE4J PMC has published the following Naming Standard for Jakarta EE Specifications in order to comply with the trademark agreement.

The javax Namespace

The major topic of the agreement is around the use of the javax namespace. The agreement permits Jakarta EE specifications to use the javax namespace as is only. Changes to the API must be made in another namespace.

While the name changes can be considered cosmetic changes, the restrictions on the use of the javax.* namespace come with some technical challenges. For example, how are we going to preserve backwards compatibility for applications written using the javax.* namespace?

The Jakarta EE Specifications Committee has come up with the following guiding principle for Jakarta EE.next:

Maximize compatibility with Jakarta EE 8 for future versions without stifling innovation.

With the restrictions on the use of the javax.* namespace, it is necessary to transition the Jakarta EE specifications to a new namespace. The Jakarta EE Specification Committee has decided that the new namespace will be jakarta.*.

How and when this transition should happen is now the primary decision for the Jakarta EE community to make. There are several possible ways forward and the forum for these discussions is the Jakarta EE Platform mailing list.

Mailing List: jakartaee-platform-dev@eclipse.org

Please make sure that you subscribe to the mailing list and join in on the discussion. We hope that we will be able to reach some form of consensus within a month that can be presented to the Specification Committee for approval.

An Opportunity

While the restrictions on the use of Java trademarks and the javax.* namespace impose both practical as well as technical challenges, it is also an opportunity to perform some housekeeping.

By renaming the specifications, we can get a uniform, homogeneous naming structure for the specifications that makes more sense and is easier on the tongue than the existing. By having clear and concise names, we may even get rid of the need for abbreviations and acronyms.

The shift from javax.* to jakarta.* opens up for the possibility to differentiate the stable (or legacy) specifications that have played their role from the ones currently being developed.

Amazon Corretto 8

UPDATE! I have updated the option of running Corretto in Docker to using the amazoncorretto Docker image available from Docker Hub.

Amazon Corretto is a production-ready distribution of OpenJDK with long-term support including performance- and security updates provided by Amazon.

Tweet announcing Amazon Coretto 8

Amazon provides installation packages and instructions for Linux, Windows, and macOS, as well as a Docker. The latest installation package is based on OpenJDK version 1.8.0_202:

$ java -version
openjdk version "1.8.0_202"
OpenJDK Runtime Environment Corretto-8.202.08.2 (build 1.8.0_202-b08)
OpenJDK 64-Bit Server VM Corretto-8.202.08.2 (build 25.202-b08, mixed mode)
$

If you don’t want to, or isn’t able to install Corretto on your workstation, t is pretty straightforward to try it out using Docker:

$docker run -it amazoncorretto

bash-4.2# java -version
openjdk version "1.8.0_202"
OpenJDK Runtime Environment Corretto-8.202.08.1 (build 1.8.0_202-b08)
OpenJDK 64-Bit Server VM Corretto-8.202.08.1 (build 25.202-b08, mixed mode)

bash-4.2#

Amazon Corretto is licensed under the same license as OpenJDK (GPLv2 with CPE) and there are no costs associated with using it. Amazon will provide quarterly security updates to Corretto 8 at least until June 2023.

But Java 8 is sooo old!

Relax, Amazon plans to make Corretto 11 available during the first half of 2019. Corretto 11 will be based on OpenJDK 11.

Oracle Groundbreaker APAC Tour 2018

This year, I was so lucky to get the chance to be part of the Oracle Groundbreaker APAC Tour 2018. The cities that I joined the tour was Perth and Melbourne in Australia as well as Wellington in New Zealand.

Perth, Australia

Copenhagen – (Singapore) – Perth
Gone swimming…

In Perth, I did a talk called Serverless with Java. I demoed various FaaS options available, including running Fn Project on Oracle Cloud. Between the sessions, I also managed to slip outside for a swim in the ocean.

Melbourne, Australia

Perth – Melbourne
New bush hat

In Melbourne, I had two sessions scheduled. The first was an informal Q&A with the local Java User Group. We had great discussions regarding the 6 months release cadence of Java, we discussed Jakarta EE and Eclipse MicroProfile and talked about Java development and Java user groups in general.

Later that afternoon, I did my Serverless with Java talk for a small, but an enthusastic crowd. 

Wellington, New Zealand

Melbourne – Wellington
Installing fn on OKE

The last stop on the journey was Wellington, New Zealand. Even here, it was the Serverless with Java talk that was put on the schedule.

To spice things up a little, I did a last minute try to get fn up and running on a managed Kubernetes cluster in Oracle Cloud Infrastructure.

I was close, so the next time I do this talk this will be part of the demos…

Wrap up

This was a fantastic trip, even considering the busy travel schedule and probably spending more time in the air or at airports than on the ground. The trip home from Wellington took ~36 hours door-to-door with short layovers in Auckland, Perth, and Singapore.

WLG – AKL
AKL – PER
PER – SIN
SIN – CPH

Source Code

The Function Duke project on GitHub contains all the source code for my serverless talks.

While Waiting for Jakarta EE

It is more than a year since Oracle announced the transfer of Java™ EE to Eclipse Foundation at JavaOne 2017. Since then, a lot has happened:

  • Java™ EE 8 API and implementation projects have been set up under EE4J.
  • The Eclipse GlassFish 5.1 release is approaching.
  • A brand new Jakarta EE specification process is right around the corner.
  • Community shows involvement regarding the technical direction of Jakarta EE.
  • The Jakarta EE NoSQL specification project proposal has been created.

This is all very good, excellent actually! When you think about the size of it all, it is actually quite an achievement. We are talking about 7.7 million lines of code! More than 60.000 files and a total of 38 new projects that have been set up at the Eclipse Foundation.

But, as everyone knows, developers are impatient and eager to try out everything new, so there are still a couple of questions that I always get when talking about Jakarta EE:

  • When can I start developing Jakarta EE applications?
  • How does Eclipse MicroProfile fit in this picture?

The answer to the first question is: “not yet”. Until the Jakarta EE specification process is finalized, the technologies are still Java™ EE. 

The answer to the second question differs a little depending on who you ask, but usually is something in the lines of “I am pretty sure that some of the MicroProfile specs will be integrated into Jakarta EE when they have proven to be useful”.

So, what should an eager developer do in the meantime? Switch to Spring Boot…ouch…or…JavaScript…squeal…?

NO, here is what you should do: Use the power of JavaEE 8 and combine it with Eclipse MicroProfile.

Many of the application server vendors have added MicroProfile features to their Java™ EE 8 compliant or certified application servers. Examples are Open Liberty, WildFly, Payara and Apache TomEE. See the respective vendor’s documentation for which versions they have included.

Java EE 8 with Eclipse MicroProfile 2.1

I have put together a simple application called Jakarta EE Duke to demonstrate how to do this. The application uses the @ConfigProperty annotation from MicroProfile Config to configure a message as well as the new @Email annotation from Bean Validation 2.0, which came with Java™ EE 8 to validate input.

While this example is extremely simple, it does indicate how you can combine the full power of Java™ EE 8 with the lightweight APIs of MicroProfile to implement cloud-native microservices using Java™ technology.

One last tip: Make sure to join the Jakarta EE Community Mailing list to always stay up-to-date on the latest development of Jakarta EE.

Running Eclipse MicroProfile on IBM Cloud

In this post, I am following up on the post series about Running Eclipse MicroProfile applications in Oracle Cloud by showing how to do it in IBM Cloud Foundry, which includes runtimes for Java, Node.js, ASP.NET Core, PHP, Python, Ruby, Swift and Go.

I am using the same simple application called CloudEE Duke as in the previous posts and will show how to deploy it in the Liberty for Java™ runtime. Since the liberty  profile is it is already configured to build using the Liberty Maven Plugin, the only thing you need to do is to activate this profile:

mvn clean package -Pliberty

See the complete pom.xml to see the complete configuration.

Since CloudEE Duke is an Eclipse MicroProfile application, you need to use the packaged server deployment option in order to activate the required features of Liberty. This is done by running the server package  command from the Liberty server directory produced by the Liberty Maven Plugin.

target/liberty/wlp/bin/server package defaultServer --include=usr

The server package  command produces a .zip file that can be pushed to IBM Cloud with the Cloud Foundry CLI as shown here:

cf push cloudee-duke -p target/liberty/wlp/usr/servers/defaultServer/defaultServer.zip

When your application is deployed, you should be able to access the hello endpoint

https://cloudee-duke.eu-gb.mybluemix.net/hello
Duke says Hello!

As ususal, you will also have the health and metrics endpoints provided by the MicroProfile implementation

https://cloudee-duke.eu-gb.mybluemix.net/health
{
outcome: “UP”,
checks: [ ]
}

https://cloudee-duke.eu-gb.mybluemix.net/metrics
# TYPE base:classloader_total_loaded_class_count counter
# HELP base:classloader_total_loaded_class_count Displays the total number of classes that have been loaded since the Java virtual machine has started execution.
base:classloader_total_loaded_class_count 10744
# TYPE base:gc_global_count counter

Running Eclipse MicroProfile on Microsoft Azure

In this post, I am following up on the post series about Running Eclipse MicroProfile applications in Oracle Cloud by showing how to do it in Microsoft Azure Web Apps for Containers.

I am using the same simple application called CloudEE Duke as in the previous posts. The only difference is that I now package the applications as Docker Images. In this example, I show how to use the fabric8 Maven Plugin to produce a docker image for WildFly Swarm.

<plugin>
    <groupId>io.fabric8</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>${version.docker-maven-plugin}</version>
    <configuration>
        <images>
            <image>
                <alias>${project.artifactid}</alias>
                <name>ivargrimstad/${project.artifactId}:swarm</name>
                <build>
                    <maintainer>Ivar Grimstad (ivar.grimstad@gmail.com)</maintainer>
                    <from>jboss/base-jdk:8</from>
                    <assembly>
                        <basedir>/</basedir>
                        <inline>
                            <files>
                                <file>
                                    <source>${project.build.directory}/${project.build.finalName}-hollow-swarm.jar</source>
                                    <outputDirectory>/opt</outputDirectory>
                                </file>
                                <file>
                                    <source>${project.build.directory}/${project.build.finalName}.war</source>
                                    <outputDirectory>/opt</outputDirectory>
                                </file>
                            </files>
                        </inline>                                   
                    </assembly>       
                    <entryPoint>
                        <arg>java</arg>
                        <arg>-Djava.net.preferIPv4Stack=true</arg>
                        <arg>-jar</arg>
                        <arg>/opt/${project.build.finalName}-hollow-swarm.jar</arg>  
                        <arg>/opt/${project.build.finalName}.war</arg>  
                    </entryPoint>
                </build>
            </image>
        </images>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The configuration is similar for the other Eclipse MicroProfile implementations. See the full pom.xml for examples. To produce the docker image for the WildFly Swarm implementation of CloudEE Duke, use the following command:

mvn clean package docker:build -Pswarm

Once the image is produced, you need to publish it to a container registry. In my case I simply push it to my public Docker Hub.

In order to deploy the CloudEE Duke application in Microsoft Azure, log in to your Azure Portal and create a new Web App for Containers as shown below.

Since WildFly Swarm runs on port 8080 by default (and I am using all defaults here), the port number for the application needs to be configured. This can be done either in the UI, or using Cloud Shell as shown here:

When your application is deployed, you should be able to access the hello endpoint.

https://cloudee-duke-swarm.azurewebsites.net/hello
Duke says Hello!

https://cloudee-duke-swarm.azurewebsites.net/health
{
outcome: “UP”,
checks: [ ]
}

https://cloudee-duke-swarm.azurewebsites.net/metrics
# HELP base:classloader_total_loaded_class_count Displays the total number of classes that have been loaded since the Java virtual machine has started execution.
# TYPE base:classloader_total_loaded_class_count counter
base:classloader_total_loaded_class_count 13697.0

KumuluzEE on Oracle Application Container Cloud

In this blog post, I will describe how to deploy the CloudEE Duke application packaged in a Kumuluz EE über-jar to Oracle Application Container Cloud.

The deployment artifact required for deployment in Oracle Application Container Cloud is a ZIP archive containing the application über-jar and a manifest file (manifest.json). The Kumuluz EE version of the manifest.json for CloudEE Duke is listed below.

{
    "runtime": {
        "majorVersion": "8"
    },
    "command": "java -Dkumuluzee.server.http.port=$PORT -jar cloudee-duke.jar",
    "release": {
        "version": "1.0",
        "build": "1",
        "commit": "123"
    },
    "notes": "Dukes says hello from Kumuluz EE"
}

You need to specify the port for Kumuluz EE in the startup command. This is done by using the $PORT environment variable.

The über-jar is produced by using the Kumuluz Maven Plugin:

<plugin>
    <groupId>com.kumuluz.ee</groupId>
    <artifactId>kumuluzee-maven-plugin</artifactId>
    <version>${version.kumuluz}</version>
    <executions>
        <execution>
            <id>package</id>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

See the complete pom.xml for an example on how to produce the deployable ZIP archive with the maven command:

mvn clean package assembly:single -Pkumuluz

This will produce a file called cloudee-duke-oracle-kumuluz.zip  in the target folder. This is the ZIP archive you will deploy to Oracle Application Container Cloud as shown in the screenshot below.

When your application is deployed, you should be able to access the hello endpoint

https://<dependsonyouraccount>.oraclecloud.com/hello
Duke says Hello!

You will also have the health and metrics endpoints provided by the MicroProfile implementation

https://<dependsonyouraccount>.oraclecloud.com/health
{
outcome: “UP”,
checks: [ ]
}

https://<dependsonyouraccount>.oraclecloud.com/metrics
# TYPE base:gc_ps_mark_sweep_count counter
# HELP base:gc_ps_mark_sweep_count Displays the total number of collections that have occurred. This attribute lists -1 if the collection count is undefined for this collector.
base:gc_ps_mark_sweep_count{serviceVersion=”1.0.0″,environment=”dev”,instanceId=”110cd814-3d12-4198-80eb-694196f58993″,serviceName=”UNKNOWN”} 2
# TYPE base:classloader_total_loaded_class_count counter

Liberty on Oracle Application Container Cloud

In this blog post, I will describe how to deploy the CloudEE Duke application packaged in a Liberty über-jar to Oracle Application Container Cloud.

The deployment artifact required for deployment in Oracle Application Container Cloud is a ZIP archive containing the application über-jar and a manifest file (manifest.json). The Liberty version of the manifest.json for CloudEE Duke is listed below.

{
    "runtime": {
        "majorVersion": "8"
    },
    "command": "java -jar cloudee-duke.jar",
    "release": {
        "version": "1.0",
        "build": "1",
        "commit": "123"
    },
    "notes": "Dukes says hello from Liberty"
}

You need to specify the port for Liberty to use. This cam be done by configuring it in the server.xml using the environment variable ${env.PORT}  as shown here:

<server description="Sample Liberty server">
    <featureManager>
        <feature>microprofile-1.2</feature>
    </featureManager>

    <httpEndpoint  httpPort="${env.PORT}" 
                   httpsPort="9443"
                   id="defaultHttpEndpoint" 
                   host="*" />

    <quickStartSecurity userName="duke" userPassword="duke"/>

    <keyStore id="defaultKeyStore" password="Liberty"/>
</server>

The über-jar is produced by using a combination of the Maven Resources Plugin as well as the Liberty Maven Plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.0.2</version>
    <executions>
        <execution>
            <id>copy-app</id>
            <phase>package</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/liberty/wlp/usr/servers/defaultServer/dropins</outputDirectory>
                <resources>
                    <resource>
                        <directory>${project.build.directory}</directory>
                        <includes>
                            <include>${project.build.finalName}.war</include>
                        </includes>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>net.wasdev.wlp.maven.plugins</groupId>
    <artifactId>liberty-maven-plugin</artifactId>
    <version>2.2</version>
    <extensions>true</extensions>
    <configuration>
        <install>
            <type>webProfile7</type>
            <version>2018.+</version>
        </install>
        <configFile>${basedir}/src/main/liberty/config/server.xml</configFile>
        <serverEnv>${basedir}/src/main/liberty/config/server.env</serverEnv>
        <jvmOptionsFile>${basedir}/src/main/liberty/config/jvm.options</jvmOptionsFile>
        <packageFile>${project.build.directory}/${project.build.finalName}.jar</packageFile>
        <include>runnable</include>
    </configuration>     
    <executions>
        <execution>
            <id>install-liberty</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>install-server</goal>
            </goals>
        </execution>
        <execution>
            <id>package-app</id>
            <phase>package</phase>
            <goals>
                <goal>package-server</goal>
            </goals>
        </execution>
    </executions>               
</plugin>

See the complete pom.xml for an example on how to produce the deployable ZIP archive with the maven command:

mvn clean package assembly:single -Pliberty

This will produce a file called cloudee-duke-oracle-liberty.zip  in the target folder. This is the ZIP archive you will deploy to Oracle Application Container Cloud as shown in the screenshot below.

When your application is deployed, you should be able to access the hello endpoint

https://<dependsonyouraccount>.oraclecloud.com/hello
Duke says Hello!

You will also have the health and metrics endpoints provided by the MicroProfile implementation

https://<dependsonyouraccount>.oraclecloud.com/health
{
outcome: “UP”,
checks: [ ]
}

https://<dependsonyouraccount>.oraclecloud.com/metrics
# TYPE base:classloader_total_loaded_class_count counter
# HELP base:classloader_total_loaded_class_count Displays the total number of classes that have been loaded since the Java virtual machine has started execution.
base:classloader_total_loaded_class_count 9430
# TYPE base:cpu_system_load_average gauge

 

Payara Micro on Oracle Application Container Cloud

In this blog post, I will describe how to deploy the CloudEE Duke application packaged in a Payara Micro über-jar to Oracle Application Container Cloud.

The deployment artifact required for deployment in Oracle Application Container Cloud is a ZIP archive containing the application über-jar and a manifest file (manifest.json). The Payara Micro version of the manifest.json for CloudEE Duke is listed below.

{
    "runtime": {
        "majorVersion": "8"
    },
    "command": "java -jar cloudee-duke-microbundle.jar --port $PORT",
    "release": {
        "version": "1.0",
        "build": "1",
        "commit": "123"
    },
    "notes": "Dukes says hello from Payara"
}

You need to specify the port for Payara Micro in the startup command. This is done by using the $PORT environment variable.

The über-jar is produced by using the Payara Micro Maven Plugin:

<plugin>
    <groupId>fish.payara.maven.plugins</groupId>
    <artifactId>payara-micro-maven-plugin</artifactId>
    <version>1.0.1-SNAPSHOT</version>
    <executions>
        <execution>
            <goals>
                <goal>bundle</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <payaraVersion>${version.payara.micro}</payaraVersion>
        <autoDeployEmptyContextRoot>true</autoDeployEmptyContextRoot>
    </configuration>
</plugin>                

See the complete pom.xml for an example on how to produce the deployable ZIP archive with the maven command:

mvn clean package payara-micro:bundle assembly:single -Ppayara

This will produce a file called cloudee-duke-oracle-payara.zip  in the target folder. This is the ZIP archive you will deploy to Oracle Application Container Cloud as shown in the screenshot below.

When your application is deployed, you should be able to access the hello endpoint

https://<dependsonyouraccount>.oraclecloud.com/hello
Duke says Hello!

You will also have the health and metrics endpoints provided by the MicroProfile implementation

https://<dependsonyouraccount>.oraclecloud.com/health
{
outcome: “UP”,
checks: [ ]
}

https://<dependsonyouraccount>.oraclecloud.com/metrics
# TYPE vendor:system_cpu_load gauge
# HELP vendor:system_cpu_load Display the “recent cpu usage” for the whole system. This value is a double in the [0.0,1.0] interval. A value of 0.0 means that all CPUs were idle during the recent period of time observed, while a value of 1.0 means that all CPUs were actively running 100% of the time during the recent period being observed. All values betweens 0.0 and 1.0 are possible depending of the activities going on in the system. If the system recent cpu usage is not available, the method returns a negative value.
vendor:system_cpu_load 0.005405405405405406

WildFly Swarm on Oracle Application Container Cloud

UPDATED!

In this blog post, I will describe how to deploy the CloudEE Duke application packaged in a WildFly Swarm über-jar to Oracle Application Container Cloud.

Über-jar approach

The deployment artifact required for deployment in Oracle Application Container Cloud is a ZIP archive containing the application über-jar and a manifest file (manifest.json). The WildFly Swarm version of the manifest.json for CloudEE Duke is listed below.

{
    "runtime": {
        "majorVersion": "8"
    },
    "command": "java -Dswarm.http.port=$PORT -Dswarm.bind.address=$HOSTNAME -jar cloudee-duke-swarm.jar",
    "release": {
        "version": "1.0",
        "build": "1",
        "commit": "123"
    },
    "notes": "Dukes says hello from Swarm"
}

You need to specify the port and host for WildFly Swarm in the startup command. This is done by using the $PORT and $HOSTNAME environment variables.

The über-jar is produced by using the WildFly Swarm Maven Plugin:

<plugin>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>wildfly-swarm-plugin</artifactId>
    <version>${version.wildfly.swarm}</version>
    <executions>
        <execution>
            <goals>
                <goal>package</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Hollow-jar approach

It is also possible to package the CloudEE Duke application as a hollow-jar using the WildFly Swarm Maven Plugin:

<plugin>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>wildfly-swarm-plugin</artifactId>
    <version>${version.wildfly.swarm}</version>
    <executions>
        <execution>
            <goals>
                <goal>package</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <hollow>true</hollow> <!-- Tells the plugin to produce a hollow-jar rather than a über-jar -->
    </configuration>
</plugin>

The command configuration in the manifest.json needs to be updated accordingly:

{
    "runtime": {
        "majorVersion": "8"
    },
    "command": "java -Dswarm.http.port=$PORT -Dswarm.bind.address=$HOSTNAME -jar cloudee-duke-hollow-swarm.jar cloudee-duke.war",
    "release": {
        "version": "1.0",
        "build": "1",
        "commit": "123"
    },
    "notes": "Dukes says hello from Swarm"
}

When using the hollow-jar approach, you will need to package both the hollow-jar and the application-war in the zip file together with the manifest.json file.

See the complete pom.xml for an example on how to produce the deployable ZIP archive with the maven command:

mvn clean package assembly:single -Pswarm

This will produce a file called cloudee-duke-oracle-swarm.zip  in the target folder. This is the ZIP archive you will deploy to Oracle Application Container Cloud as shown in the screenshot below.

When your application is deployed, you should be able to access the hello endpoint

https://<dependsonyouraccount>.oraclecloud.com/hello
Duke says Hello!

You will also have the health and metrics endpoints provided by the MicroProfile implementation

https://<dependsonyouraccount>.oraclecloud.com/health
{
outcome: “UP”,
checks: [ ]
}

https://<dependsonyouraccount>.oraclecloud.com/metrics
# HELP base:classloader_total_loaded_class_count Displays the total number of classes that have been loaded since the Java virtual machine has started execution.
# TYPE base:classloader_total_loaded_class_count counter
base:classloader_total_loaded_class_count 14170.0