Sunday, May 28, 2017

JavaEE: Reloading with TomEE Maven Plugin

On a previous post, we learned how to run a simple JaveEE code using a TomEE Maven Plugin.  As a developer, we often change codes and want to see the change immediately.  The TomEE maven plugin provides a <reloadOnUpdate> and a <synchronization> configuration.

Synchronization is a block defining a source and target folder, which will be synchronized. Configuration of the plugin shown on a previous post needs to be updated.

In addition to the <reloadOnUpdate> and <synchronization> configuration, the plugin need to use some internal beans called a openejb for the reloading.  This is an updated <plugin> element in the pom.xml.

<plugin>
   <groupId>org.apache.tomee.maven</groupId>
   <artifactId>tomee-maven-plugin</artifactId>
   <version>${tomee.version}</version>
   <configuration>
      <tomeeVersion>${tomee.version}</tomeeVersion>
      <tomeeClassifier>plus</tomeeClassifier>
            
      <webapps>
         <webapp>${project.groupId}:${project.artifactId}:${project.version}?name=${project.artifactId}</webapp> 
      </webapps>
                    
      <synchronization>
         <extensions>
            <extension>.class</extension>
         </extensions>
      </synchronization>
      <reloadOnUpdate>true</reloadOnUpdate>
      <systemVariables>
         <tomee.serialization.class.blacklist>-</tomee.serialization.class.blacklist>
         <!-- When TomEE starts it starts an internal application (called openejb). 
             The goal is to offer some internal beans mainly used by TomEE tooling 
             (TomEE deployer, reload feature of TomEE maven plugin…).
             Don't use it if it is not necessary
         -->
         <openejb.system.apps>true</openejb.system.apps>
      </systemVariables>
   </configuration>
</plugin>

Now, restart the tomee plugin.
mvn clean install tomee:run

Then, open a URL again as shown on a previous posthttp://localhost:8080/demo/hello

Now, update the String in the sayHello method shown on a previous post.  Then, recompile the changes by running this:  mvn compile
On a command console, you will see that TomEE plugin restarts, but the change is not visible on http://localhost:8080/demo/hello

In fact, you can see the update on this url: http://localhost:8080/demo-0.1-SNAPSHOT/hello

So, the added <webapp> element to change the context name didn't work during the reloading.  To avoid this issue, I will use a <finalName> element provided by the maven instead of using a tomee plugin configuration.

<build>
   <finalName>${project.artifactId}</finalName>
   <plugins>
      <plugin>
         <groupId>org.apache.tomee.maven</groupId>
         <artifactId>tomee-maven-plugin</artifactId>
         <version>${tomee.version}</version>
         <configuration>
            <tomeeVersion>${tomee.version}</tomeeVersion>
            <tomeeClassifier>plus</tomeeClassifier>
            <!-- Removed   
            <webapps>
 <webapp>${project.groupId}:${project.artifactId}:${project.version}?name=${project.artifactId}</webapp> 
             </webapps>
             -->
       
             <synchronization>
                  :
                  :
          </configuration>
       </plugin>
   </plugins>
</build>

Now, the changed code will be auto reloaded when the codes are compiled, and be visible on a url http://localhost:8080/demo/hello

If you use an IDE that can build a project automatically, the changed code will be reloaded even without running the mvn compile  It can be convenient, but frequent reloading may annoy developers too.

Tuesday, May 23, 2017

JavaEE: TomEE and TomEE Maven Plugin

TomEE makes JavaEE development much easier.  On this post, I will show a simple and concise pom.xml file for TomEE configuration.

On a previous post, I included a javaee-api to write a simple RESTful web service.  Instead of including individual dependency, we can include a tomee-embeded, which includes all jars included in the TomEE server.

TomEE maven plugin is also included here to run an application with a maven command.


<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.jihwan.jee</groupId>
   <artifactId>demo</artifactId>
   <version>0.1-SNAPSHOT</version>
   <packaging>war</packaging>
 
   <properties>
     <tomee.version>7.0.2</tomee.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <failOnMissingWebXml>false</failOnMissingWebXml>
     <maven.compiler.target>1.8</maven.compiler.target>
     <maven.compiler.source>1.8</maven.compiler.source>
   </properties>
 
   <dependencies>
      <dependency>
         <groupId>org.apache.tomee</groupId>
         <artifactId>tomee-embedded</artifactId>
         <version>${tomee.version}</version>
         <scope>provided</scope>
      </dependency>
    </dependencies>
    
    <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomee.maven</groupId>
        <artifactId>tomee-maven-plugin</artifactId>
        <version>${tomee.version}</version>
        <configuration>
          <tomeeVersion>${tomee.version}</tomeeVersion>
          <tomeeClassifier>plus</tomeeClassifier>
        </configuration>
      </plugin>
    </plugins>
    </build>
</project>

After changing the pom.xml from the previous post, we can run the following maven command to run the maven plugin TomEE server.

mvn clean install tomee:run

Let's look at some logs shown later parts of the logs.

1
2
3
4
5
INFO [localhost-startStop-1] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints REST Application: http://localhost:8080/demo-0.1-SNAPSHOT/       -> org.apache.openejb.server.rest.InternalApplication@1abb025c
INFO [localhost-startStop-1] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints      Service URI: http://localhost:8080/demo-0.1-SNAPSHOT/hello  -> Pojo work.rest.HelloService
INFO [localhost-startStop-1] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints               GET http://localhost:8080/demo-0.1-SNAPSHOT/hello/ ->      String message()
INFO [localhost-startStop-1] sun.reflect.DelegatingMethodAccessorImpl.invoke Deployment of web application archive /Users/jihwan/workspace/TomEE/demo/target/apache-tomee/webapps/demo-0.1-SNAPSHOT.war has finished in 106 ms
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Server startup in 819 ms

As shown on the line 4 and 5, the deployment is done in 106 ms and the server started in 819 ms. Simple and fast!
TomEE also shows available service URIs as shown on the line 3.  If you are a careful reader, you may notice that the URI is http://localhost:8080/demo-0.1-SNAPSHOT/hello instead of http://localhost:8080/demo/hello 


Having a project version in your context path is very annoying.  To avoid this, we need to define a custom context path in an <webapp> tag under the <configuration> of the tomee-maven-plugin. : This is a way of using the tomee maven plugin configuration, but it has a limitation, which will be addressed on another post.

   <plugin>
      <groupId>org.apache.tomee.maven</groupId>
      <artifactId>tomee-maven-plugin</artifactId>
      <version>${tomee.version}</version>
      <configuration>
         <tomeeVersion>${tomee.version}</tomeeVersion>
         <tomeeClassifier>plus</tomeeClassifier>
         <webapps>
            <webapp>${project.groupId}:${project.artifactId}:${project.version}?name=${project.artifactId}</webapp> 
         </webapps>
      </configuration>
   </plugin>


JavaEE: Restful Web Service in 5 minutes on TomEE

Let's create a simple REST service with TomEE and Eclipse
- Setup
(You may not need to download TomEE if you use a TomEE Maven plugin as shown here)


1.  Download TomEE.  To create a REST service, download TomEE Plus
     http://tomee.apache.org/downloads.html

2.  Include the TomEE server to Eclipse.  TomEE 7 uses a tomcat v8.5 server. On the Eclipse 'Servers' view, right click --> New --> Server.

Then, click the Finish.

3.  On Eclipse, create a Maven project. File --> New --> Other --> Maven Project.

Check 'Create a simple project'.  Specify a group id and artifact id.  Then, click a Finish button. (I assume you already have a maven Eclipse plugin)

4.   On the pom.xml, we need to add a javaee jar file.  This is the basic contents in the pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.jihwan.jee</groupId>
   <artifactId>demo</artifactId>
   <version>0.1-SNAPSHOT</version>
   <packaging>war</packaging>
   <name>JEE_Work</name>
   <description>work on JEE</description>
 
   <properties>
      <failOnMissingWebXml>false</failOnMissingWebXml>
     <maven.compiler.target>1.8</maven.compiler.target>
     <maven.compiler.source>1.8</maven.compiler.source>
   </properties>
 
   <dependencies>
      <!-- https://mvnrepository.com/artifact/org.apache.tomee/javaee-api -->
      <dependency>
         <groupId>org.apache.tomee</groupId>
         <artifactId>javaee-api</artifactId>
         <scope>provided</scope>
         <version>7.0-1</version>
      </dependency>
   </dependencies>
</project>

- Writing RESTful service

RESTful web services are loosely coupled, lightweight web services that are particularly well suited for creating APIs for clients spread out across the internet.  In the REST architectural style, data and functionality are considered resources and are accessed using URIs
Root resource classes are POJOs that are either annotated with @Path or have at least one method annotated with @Path.  This class is a simplest RESTful web service.

package work.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/hello")
public class HelloService {
    @GET
    public String message() {
        return "Hello RESTful world!";
    }
}

- Running the service

Run TomEE server after adding the 'demo' resource via Eclipse.
Open http://localhost:8080/demo/hello
You will see a "Hello REST world!" message.


Java 9: Flow - Reactive Programming

Programming world has always been changed fast enough and many programming / design paradigms have been introduced such as object oriented p...