June 17, 2016

Java EE Guardians moving EE 8 forward at JavaOne 2016 San Francisco

The Java EE Guardians is a group of individuals and organizations from all around the world who stand in support of an open standard for Java enterprise development and are committed to moving Java EE forward.  The group started the first quarter of 2016 in response to Oracle's apparent lack of commitment to Java EE 8.  On the Java EE Guardians website, http://javaee-guardians.io, the group has published evidence showing that the activity of EE 8 JSRs lead by Oracle have slowed significantly (Lack of.., 2016).
Sadly, this lack of commitment to Java EE 8 seems to extend to JavaOne 2016 in San Francisco.  The Java EE Guardians have attempted to contact the EE 8 JSRs specification leads about their intentions to present at JavaOne on the progress of their JSRs.  They have either responded in silence or by saying no.  So the Java EE Guardians have rallied the community to make sure EE 8 has a good representation at JavaOne.  The community actions are summarized in the table below, showing the community members who have stepped up and submitted proposals to JavaOne to ensure the JSRs are represented.
If the current situation remains unchanged, it will be the first time active JSR specification leads from the Java steward will not be presenting their progress to the community in such high numbers; an unprecedented, never-before-seen situation in JavaOne history.  We sincerely hope that most, if not all, of the session proposals put forth by the community are accepted if Oracle specification leads do not step up in time.  It is critical for all the people attending JavaOne to know that standards-based Java enterprise development is moving forward.
Table 1: Java EE 8 JSR JavaOne 2016 Session Proposals
Description
Java EE 8 JSR
Version
Specification Lead
JavaOne 2016 Session Proposal
Java™ Platform, Enterprise Edition Specification
8
Linda Demichiel (Oracle)
William Shannon (Oracle)
Java EE 8 Community Panel
  • Reza Rahman
  • Werner Keil (JCP Executive Committee)
  • Michael Remijan
  • Mark Little (Red Hat)
  • Kevin Sutter (IBM)
  • Oracle contacted to participate, no response so far
Aligning Java EE 8 with Java SE 8 - The Missing Links
  • Reza Rahman
  • Ryan Cuprak
  • Michael Remijan
Java EE 8 Recipes
  • Josh Juneau
Rapid Development Tools for Java EE 8
  • Gaurav Gupta
Java™ Servlet Specification
4.0
Edward Burns (Oracle)
Shing Wai Chan (Oracle)
What’s Coming in Servlet 4
  • Murat Yener
  • Alex Theedom
Java™ Message Service (JMS)
2.1
Nigel Deakin (Oracle)
What’s new with JMS 2.1
  • Ivar Grimstad
JMS BOF
  • Ivar Grimstad
JAX-RS: The JavaTM API for RESTful Web Services
2.1
Santiago Pericasgeertsen (Oracle)
Marek Potociar (Oracle)
JAX-RS 2.1
  • Sebastian Daschner
JavaServer Faces (JSF)
2.3
Edward Burns (Oracle)
Manfred Riem (Oracle)
JSF or MVC, What do I Use?
  • Josh Juneau
JSF 2.3 in Action
  • Kito Mann
Model-View-Controller (MVC)
**NEW**
1.0
Santiago Pericasgeertsen (Oracle)
Manfred Riem (Oracle)
What's new with MVC 1.0?
  • Ivar Grimstad
Modern Web Apps with HTML5 Web Components, Polymer, Java EE MVC 1.0 and JAX-RS
  • Kito Mann
JSF or MVC, What do I Use?
  • Josh Juneau
Java Persistence (JPA)
2.1 MR
Linda Demichiel (Oracle)
Lukas Jungmann (Oracle)
What's Next for JPA? (BOF)
  • Patrycja Wegrzynowicz
  • Michael Remijan
Contexts and Dependency Injection (CDI)
2.0
Antoine Sabot-Durand (Red Hat)
CDI 2.0 in live coding
  • Antoine Sabot-Durand
Micro services and more with CDI on Java SE
  • Antoine Sabot-Durand
Mutate Java EE 7 DNA with CDI portable extensions
  • Antoine Sabot-Durand
Java API for JSON Processing (JSON-P)
1.1
Kinman Chung (Oracle)
What's New in JSON-P 1.1?
  • Werner Keil
Java API for JSON Binding (JSON-B)
**NEW*
1.0
Dmitry Kornilov (Oracle)
JSON-B 1.0
  • Dmitry Kornilov (has submitted)
Java™ EE Security API
Alexander Kosowski (Oracle)
What's new with Java EE Security?
  • Ivar Grimstad
  • Werner Keil
Concurrency Utilities for Java EE 1.0
No change from EE 7
Liberating EJB Concurrency Features for the Community
  • Reza Rahman
JavaOne, and similar conferences, are a critical part in keeping Java strong (Krill, 2015).  They help showcase new technologies and the direction of the industry.  They also allow the community to voice how the trends of today will become the standards of tomorrow.  This has been especially true of EE 7, which brought to the community standards for developing with: HTML5, WebSockets, JSON, Messaging, Batch, Concurrency, Dependency Injection, RESTful Web Services, and non-blocking I/O (Krill, 2013).  EE 7 was released in 2013 (JSR 342, 2011) and it has had a lot to celebrate over the last few years.   It has been well supported by the major application server providers and well adopted by the community (Rahman, 2015).  Modern EE 7 servers are lightweight, fast, and quickly evolving to support architectural changes in the industry (Daschner, 2016; JAX Editorial Team, 2016).  EE 8 promises to bring an MVC standard, JSON binding, more support for HTML 5 and HTTP 2, better CDI integration, and more (Gupta, n.d.).  But this won't happen without community involvement organized by strong leadership from Oracle.    
Visit the Java EE Guardians website, http://javaee-guardians.io, or its Google group, https://groups.google.com/forum/#!forum/javaee-guardians, and add your voice in support of Java EE.
References
JSR 366: Java Platform, Enterprise Edition 8 (Java EE 8) Specification. (2014, August 26).  jcp.org. Retrieved June 1, 2016, from https://jcp.org/en/jsr/detail?id=366
JSR 342: JavaTM Platform, Enterprise Edition 7 (Java EE 7) Specification. (2011, March 01).  jcp.org. Retrieved June 1, 2016, from https://www.jcp.org/en/jsr/detail?id=342
Rahman, R. (2015, June, 08). The Ghosts of Java EE 7 in Production: Past, Present and Future.  blogs.oracle.com. Retrieved June 1, 2016, from https://blogs.oracle.com/reza/entry/the_ghosts_of_java_ee
Lack of Java EE 8 Progress. (2016, May). javaee-guardians.io. Retrieved May 31, 2016 from http://javaee-guardians.io/lack-of-java-ee-8-progress/
Krill, P. (2015, October, 23). Java developers carry hopes and fears to JavaOne. infoworld.com. Retrieved June 2, 2016 from http://www.infoworld.com/article/2996549/java/java-developers-carry-hopes-fears-to-javaone.html
Krill, P. (2013, June, 13). 11 hot improvements to Java EE 7. infoworld.com. Retrieved June 2, 2016 from http://www.infoworld.com/article/2606994/java/105268-11-hot-improvements-to-Java-EE-7.html#slide13
Daschner, S. (2016, April, 9). Stop Saying "heavyweight". blog.sebastian-daschner.com. Retrieved April 11, 2016 from https://blog.sebastian-daschner.com/entries/stop_saying_heavyweight
JAX Editorial Team. (2016, May, 19). “Java EE’s heavyweight label is just mythology”. jaxenter.com. Retrieved May 20, 2016 from https://jaxenter.com/java-ees-heavyweight-label-is-just-mythology-126363.html
Gupta, A. (n.d.). Java EE 8 Status. blog.arungupta.me. Retrieved June 1, 2016 from http://blog.arungupta.me/javaee8

June 14, 2016

VBS Script for Outlook Email Message

Simple tip, this Visual Basic (VBS) script is used to open a new Outlook email message and automatically populate to: and subject:.

' Sleep for 3 minutes
WScript.Sleep(1000 * 60 * 30)
Set oolApp = CreateObject("Outlook.Application")
Set email = oolApp.CreateItem(0)
email.Recipients.Add("user@somedomain.org")
email.Subject = "Subject for email"
email.Display()


Enjoy!

April 12, 2016

My TAR incremental backup strategy

Quick tip:

Here is my TAR incremental backup strategy.  I have been using rsync for a long time but recently ran into a number of permission and symlink issues rsync’ing from an Ubuntu guest to a Windows host.

A few comments on the bash script below:

1.    The do_backup() function is a common function and it does all the work of the backup.
2.    The do_backup() function has to take 4 parameters
a.    $1 is the source directory.  This is the directory you want to backup, OR, this is the directory that has stuff in it you want to backup.
b.    $2 is the destination directory.  This directory is relative to ${backupHome}, but still starts with the / character.  This is where you want the TAR balls to end up.
c.    $3 is a name for the backup.  This is used to create the names of the TAR balls and the SNAR indexes.
d.    $4 is a command to run inside the source directory ($1) which will be piped to the `tar` command for backup.
3.    This strategy makes a full backup (level 0) and a single incremental backup (level 1).  The level 1 backup is (correctly) overwritten each time a backup is performed.
4.    A full backup is performed if:
a.    A backup has never been done before
b.    The size of the incremental backup is greater than 10% of the size of the full backup.

Bash script

#!/bin/bash
backupHome=/mnt/hgfs/Backup

#
# First check to see that that backup directory exists.
# If it does, continue. Otherwise, exit with error code.
#
if [ ! -d "${backupHome}" ]; then
        echo "Directory ${backupHome} does NOT exist, exit."
        exit 1;
else
        echo "Directory ${backupHome} exists, continue."
fi

# do_backup "/etc/postfix" "/etc/postfix" "main" 'echo main.cf'
function do_backup {
    local backupSrc=$1
    local backupDst=${backupHome}${2}
    local backupNme=$3
    local backupDir=$4

    local fullSnarFile=${backupDst}/${backupNme}_full.snar
   local fullTarFile=${backupDst}/${backupNme}_full.tar.gz
    local level1SnarFile=${backupDst}/${backupNme}_level_01.snar
    local level1TarFile=${backupDst}/${backupNme}_level_01.tar.gz

    echo "Backup: ${backupNme} from: ${backupSrc} to: ${backupDst}"
    mkdir -p ${backupDst}
    cd ${backupSrc}

    # Check file percentages and see if full backup is needed
    if [ -f ${fullTarFile} ] && [ -f ${level1TarFile} ]
    then
        local fullSize=$(stat -c%s ${fullTarFile})
        echo "  Size of ${fullTarFile} is ${fullSize}"

        local level1Size=$(stat -c%s ${level1TarFile})
        echo "  Size of ${level1TarFile} is ${level1Size}"

        local percentChange=$(echo "scale=2; (${level1Size}/${fullSize}) * 100" | bc)
        percentChange=$(printf "%.0f" ${percentChange})
        echo "  Percent change is ${percentChange}"

        if [ ${percentChange} -gt 10 ]
        then
            echo "  Prepare for a new full backup"
            rm -f ${fullSnarFile}
            rm -f ${level1SnarFile}
            rm -f ${level1TarFile}
        fi
    fi

    # If file does not exist, perform full backup
    if [ ! -f ${fullSnarFile} ]
    then
        echo "  Performing full backup"
        eval ${backupDir} | tar --listed-incremental ${fullSnarFile} -cpzf ${fullTarFile} -T -
    else
        echo "  Performing level 1 backup"
        cp -f ${fullSnarFile} ${level1SnarFile}
        eval ${backupDir} | tar --listed-incremental ${level1SnarFile} -cpzf ${level1TarFile} -T -
    fi
}


Examples

Let’s take a look at a few usage examples.  For these examples, assume that ${backupHome} is /mnt/hgfs/Backup/ like in the script.

Example 1:

do_backup "/home/apache" "/home/apache" "apache" 'echo .'

Example 1 means you want to backup the /home/apache directory to the /mnt/hgfs/Backup/home/apache directory. The parameter “apache” means the following files will be created:

/mnt/hgfs/Backup/home/apache/apache_full.snar
/mnt/hgfs/Backup/home/apache/apache_full.tar.gz
/mnt/hgfs/Backup/home/apache/apache_level_01.snar
/mnt/hgfs/Backup/home/apache/apache_level_01.tar.gz

Finally, ‘echo .’ means the TAR ball will contain everything inside the /home/apache directory

Example 2:

do_backup "/etc/postfix" "/etc/postfix" "main" 'echo main.cf'

Example 2 means you want to backup the /etc/postfix directory to the /mnt/hgfs/Backup/etc/postfix directory. The parameter “main” means the following files will be created:

/mnt/hgfs/Backup/etc/postfix/main_full.snar
/mnt/hgfs/Backup/etc/postfix/main_full.tar.gz
/mnt/hgfs/Backup/etc/postfix/main_level_01.snar
/mnt/hgfs/Backup/etc/postfix/main_level_01.tar.gz

Finally, ‘echo main.cf’ means the TAR ball will ONLY contain the /etc/postfix/main.cf file!

Example 3:

do_backup "/home/michael" "/home/michael" "michael" 'find . -type f -name ".forward" -o -type d -name "cron" -o
-type d -name "Applications" -o -type d -name ".ssh"'

Example 3 means you want to backup the /home/michael directory to the /mnt/hgfs/Backup/home/michael directory. The parameter “michael” means the following files will be created:

/mnt/hgfs/Backup/home/michael/michael_full.snar
/mnt/hgfs/Backup/home/michael/michael_full.tar.gz
/mnt/hgfs/Backup/home/michael/michael_level_01.snar
/mnt/hgfs/Backup/home/michael/michael_level_01.tar.gz

Finally, 'find . -type f -name ".forward" -o -type d -name "cron" –o -type d -name "Applications" -o -type d -name ".ssh"' means the TAR ball will ONLY contain the following:

/home/michael/.forward
/home/michael/cron/
/home/michael/Applications/
/home/michael/.ssh/

Enjoy!

References

Whipp, Paul. (2010, December). Using tar for full and incremental backups. paulwhippconsulting.com. Retrieved April 4, 2016, from http://paulwhippconsulting.com/blog/using-tar-for-full-and-incremental-backups/

February 25, 2016

Reading MANIFEST.MF Values From a JAR File on your Class Path

Abstract
Recently, I was looking at building a simple "about" page for my newest application (See project Riviera, a database versioning source code management tool).  I started to build a properties file Maven would filter values into, but then I realized it was not necessary.  The JAR MANIFEST.MF file had almost all the metadata already.  So all I had to do was read the properties from MANIFEST.MF, which I found more difficult than I thought it should be. Here's my solution.

Code
Listing 1 shows the code.

Listing 1: Code to read MANIFEST.MF from JAR file on the class path

Attributes attributes;
try {
    URL jarURL 
        = this.getClass().getProtectionDomain().getCodeSource().getLocation();
    
    URI manifestUri 
        = new URI(String.format("jar:%s!/%s", jarURL, JarFile.MANIFEST_NAME));
    
    InputStream is 
        = manifestUri.toURL().openStream()
    
    Manifest manifest 
        = new Manifest(is);
    
    attributes 
        = manifest.getMainAttributes();            

    is.close();
} catch (Exception e) {
    attributes = new Attributes();
}

Let's take a look at this code in a bit more detail.

The URI object is the key to being able to read the MANIFEST.MF file from a JAR.  To read the contents of a JAR file, a properly formatted URI string looks like this:

"jar:file:/C:/path/to/file.jar!/META-INF/MANIFEST.MF"

The jar:file and ! parts are required in the URI.  The rest of the URI depends on the specific location of the JAR file on your file system and what file in the JAR you want to stream.  Knowing what file you want to read is a given, but how do you get the fully-qualified location of the JAR file?

It stands to reason that if the JVM is executing code from a class it got from a JAR file then the JVM should be able to tell you where that JAR file is located. After all, the JVM needs to know where the JAR file is in order to load the class!  Turns out its simple to find this information.  You get the fully-qualified location of the JAR file from a class's ProtectionDomain that comes from the JAR file.  Once you have the fully-qualified location, you can build a properly formatted URI string.  Then once you have a URI object, then the magic happens.

From the URI object you can get a URL object by using URI#toUrl().  Then after you have a URL object you get an InputStream to the resource using the URL#openStream() method. Under the covers, the URL object determines it needs a JarURLConnection to open the stream.

Once you have the InputStream, pass it along to the Manifest constructor and you're done!  Use Manifest#getMainAttributes() to get the Attributes and then use Attributes#getValue(key) to get the value you want.

Let's it!  Now you can read the the name/value attributes from the MANIFEST.MF file.

Enjoy!

References
Bozho. (2010, February 16). How to read a file from a jar file?. stackoverflow.com. Retrieved January 27, 2016 from http://stackoverflow.com/questions/2271926/how-to-read-a-file-from-a-jar-file.



December 04, 2015

GlassFish Jersey JAX-RS REST Service Client with Cookies and HTTP Proxy Example

Abstract
Working with JAX-RS, I found most people tend to focus on the server side of things.  But there is a client side as well which doesn't involve JavaScript.  I found it difficult finding client-side examples which involved some more advanced, yet very common requirements, such as how to use an HTTP proxy for your client and how to send cookies to the server.  This article consolidates my research into one example.  As I bring in more requirements, I'll update this example.

System Requirements
This example was developed and run using the following system setup. If yours is different, it may work but no guarantees.
  • jdk1.8.0_65_x64
  • NetBeans 8.1 version 6.3
  • Maven 3.0.5 (Bundled with NetBeans)
  • Jersey 2.22.1 (From GlassFish)
The rest of the software dependencies can be found in this article.

Download 


Git code example from GitHub

Maven 
One of the first challenges is trying to determine which version of JAX-RS you're working with. Jersey is the reference implementation of JAX-RS, and there are a lot of examples showing how to do things with Jersey.  But Jersey has gone through a lot of changes.  Version 1.x is "Sun Jersey" then version 2.x was completely repackaged as "GlassFish Jersey".  As Jersey has evolved, a lot of breaking changes have occurred, so examples may not work anymore.

This is my Maven dependency configuration for Jersey 2.22.1.

 
  org.glassfish.jersey.core
  jersey-client
  2.22.1
 
 
  org.glassfish.jersey.connectors
  jersey-apache-connector
  2.22.1
 
javax.ws.rs.client.Client 
To create a JAX-RS client, the first thing you need is an instance of javax.ws.rs.client.Client.  Getting one of these is not as easy as you might think. I probably ran across a half dozen different ways of getting a Client instance, so it's very confusing.  Listing 1 shows my ClientFactory.  Let's take a look at it in more detail.

Listing 1: ClientFactory

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;

public class ClientFactory {
    public static Client create() 
    {       
        System.out.printf("ClientFactory%n%n");
        
        ClientConfig config = new ClientConfig();
        {        
            config.property(ClientProperties.PROXY_URI, "http://localhost:7777");        
        }
        
        ApacheConnectorProvider provider = new ApacheConnectorProvider();
        {
            config.connectorProvider(new ApacheConnectorProvider());        
        }
        
        Client client 
            = ClientBuilder.newClient(config);
        
        return client;
    }
}

Let's take a look at line 23 first. ClientBuilder.newClient(config) is a standard way to create a Client object.  Line 23 only uses classes from the JAX-RS API.  The config object however, created on line 12 is a Jersey-specific implementation of a JAX-RS interface.  Line 14 is where we set a property in the config object to specify the HTTP Proxy.  This configuration, however, doesn't do anything by itself because the default JAX-RS implementation doesn't understand HTTP Proxies.  This is why in the pom.xml we have a dependency on jersey-apache-connector.  This allows the defaults to be overridden with Apache HttpClient.  Lines 17-20 create an ApacheConnectorProvider and put it in the config object.  Without the ApacheConnectorProvider, the HTTP Proxy won't be used.  Now that we have a Client object, Let's see how to use it.

main(String [] args) 
Getting a  Client object was the first step. Now let's use the  Client object to make a REST-ful service call.  The main() application in listing 2 does this.

Listing 2: A main(String [] args) application

import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

public class Main {
    public static void main(String[] args) throws Exception {
        Client client 
            = ClientFactory.create();
        
        WebTarget target = client
            .target("http://jsonplaceholder.typicode.com")
            .path("posts/1")
        ;
        
        Response response = target
            .request(MediaType.TEXT_HTML)
            .accept(MediaType.APPLICATION_JSON)
            .header("User-Agent", "Java/1.8.0_65)
            .cookie("name1","value1")
            .cookie("name2","value2")
            .get(Response.class)
        ;
        
        System.out.printf("Response: %s%n%n", response);        
        System.out.printf("AllowdMethods: %s%n%n", response.getAllowedMethods());
        System.out.printf("Class: %s%n%n", response.getClass());
        System.out.printf("Cookies: %s%n%n", response.getCookies());
        System.out.printf("Date: %s%n%n", response.getDate());
        System.out.printf("Entity: %s%n%n", response.getEntity());
        System.out.printf("EntityTag: %s%n%n", response.getEntityTag());
        System.out.printf("Headers: %s%n%n", response.getHeaders());
        System.out.printf("Language: %s%n%n", response.getLanguage());
        System.out.printf("LastModified: %s%n%n", response.getLastModified());
        System.out.printf("Length: %s%n%n", response.getLength());
        System.out.printf("Links: %s%n%n", response.getLinks());
        System.out.printf("Location: %s%n%n", response.getLocation());
        System.out.printf("MediaType: %s%n%n", response.getMediaType());
        System.out.printf("Metadata: %s%n%n", response.getMetadata());
        System.out.printf("Status: %s%n%n", response.getStatus());
        System.out.printf("StatusInfo: %s%n%n", response.getStatusInfo());
        System.out.printf("StringHeaders: %s%n%n", response.getStringHeaders());
        System.out.printf("hasEntity: %b%n%n", response.hasEntity());
        System.out.printf("readEntity(String): %s%n%n", response.readEntity(String.class));
    }
}

On lines 8-9 I use my custom ClientFactory to get a Client object.  From the Client object, the next step is to get a WebTarget.  Lines 11-14 show this.  The target() method call is typically the base URL and the path() method call adds path information to the base.  The WebTarget is then used to make the call and get the response, and this can be done in many different ways.  In my example, I make the call and get the response on lines 16-23.  First it uses the request() method to configure what type of data the request is being sent to the server, then the accept() method configures what type of data the server will be sending back to the client.  The header() method is then used to override the default value for "User-Agent". Proxies are usually sensitive to the "User-Agent" header and will reject requests from JAX-RS clients using the default value.  So change the "User-Agent" value to something your proxy will accept.  Next, the cookie() method calls add cookies to the request.  Finally the get(Response.class) method call makes an HTTP GET call to the server and wraps the response from the server into a Response object.  Fun!

The rest of the code is just logging what's in the Response object.

That's it, enjoy!

References
NGloom. (2015, May 15). How to add a http proxy for Jersey2 Client. stackoverflow.com. Retrieved December 3, 2015 from http://stackoverflow.com/questions/18942648/how-to-add-a-http-proxy-for-jersey2-client.

theotherian. (2013, August 11). setting up jersey client 2.0 to use httpclient, timeouts, and max connections. theotherian.com. Retrieved December 3, 2015 from http://www.theotherian.com/2013/08/jersey-client-2.0-httpclient-timeouts-max-connections.html.


November 01, 2015

Payara/GlassFish DataSource JNDI Lookup Reference

Introduction

This article is more of a reference than a how-to.  Setting up a JDBC Connection Pool and JDBC Resource in Payara/GlassFish is easy. However remembering how to do the JNDI lookups from your application is a little harder because, let's face it, we don't have to do it that often so its easy to forget.  So here is a reference.

Create "JDBC Connection Pool"

The first thing you'll need to do is create a "JDBC Connection Pool". As shown in Figure 1, Payara/GlassFish have a simple wizard for this. 

Figure 1: Wizard to start a new "JDBC Connection Pool"

PostgreSQL is my database of choice.  So during the setup I choose "Postgresql" and add the following configuration:

Datasource classname: org.postgresql.ds.PGSimpleDataSource
 
PropertyValue
userelephant
passwordjafj2r@#Rhh
serverNamelocalhost
portNumber5432
databaseNameemail

Remember, after creating a "JDBC Connection Pool", your application cannot use it because the pool has yet to be bound to JNDI.  To do the binding, let's look at the next step, which is to create a JDBC Resource.

Create "JDBC Resource"

This steps creates a JNDI binding for the "JDBC Connection Pool" so your application is able to perform a lookup and find it.  Payara/GlassFish again provides a nice simple wizard for you, and you start the wizard as shown in figure 2.

Figure 2: Wizard to start a new "JDBC Resource"

The Wizard can't get any simpler.  You need to supply a "JNDI Name"for the "JDBC Resource" and select a "JDBC Connection Pool" from the dropdown box.  That's it!  Well not quite.  Let's look at the "JNDI Name" value in a bit more detail.

JNDI can get really confusing.  In general, JNDI is a tree-like structure with a number of special contexts (java:global, java:app, java:module, java:comp) and some special paths (java:comp/env).  It gets even more confusing because in some cases a context - like java:comp/env - is assumed and prepended for you but in other cases it's not. So let's consider what "JNDI Name" really means for a "JDBC Resource" by looking at some examples.
 
JNDI Name@Resource(lookup = "%s")
OR
InitialContext.lookup("%s")
ResultComments
"EmailDS""EmailDS"SUCCESSLookup and "JNDI Name" match!
"EmailDS""/EmailDS"FAILSLookup does not match "JNDI Name"!  Lookup name has a leading "/" character!
"EmailDS""java:global/EmailDS"FAILSLookup does not match "JNDI Name"! Payara/Glassfish does not prepend the global context when binding to JNDI.
"EmailDS""java:comp/env/EmailDS"FAILSLookup does not match "JNDI Name"! The "java:comp/env" context and path is application specific.  We'll cover how to do this application specific configuration below.
"jdbc/app/EmailDS""jdbc/app/EmailDS"SUCCESSLookup and JNDI Name match!
"jdbc/app/EmailDS""/jdbc/app/EmailDS"FAILSLookup does not match "JNDI Name"!  Lookup name has a leading "/" character!
"jdbc/app/EmailDS""java:global/jdbc/app/EmailDS"FAILSLookup does not match "JNDI Name". Payara/Glassfish does not pre-pend the global context when binding to JNDI.
"jdbc/app/EmailDS""java:comp/env/jdbc/app/EmailDS"FAILSLookup does not match "JNDI Name". The "java:comp/env" context and path is application specific.  We'll cover how to do this application specific configuration below.

So, if your application has a Payara/GlassFish "JDBC Resource" and your code is performing a direct JNDI lookup, the above table should give you enough information to figure out what will succeed and what will fail.  When you create the "JDBC Resource", Payara/GlassFish will use the "JNDI Name" you give as the exact path in the JNDI tree to make the binding.  Payara/GlassFish does not prepend any contexts or paths onto the name you give.  So your code needs to do a lookup on the exact "JNDI Name" value.

Now you may be asking yourself, what about JNDI redirection?  It's always good practice to have your application JNDI lookup names to be decoupled from the real JNDI locations of the resources.  In other words, I want my application to lookup "java:module/env/jdbc/MyDS" but I want that lookup to be redirected/mapped to the real JNDI location - "EmailDS" - which in Payara/GlassFish is the "JNDI Name" value of the "JNDI Resource".  We'll take a look at how to do this next.


Redirection with web.xml and glassfish-web.xml

The web.xml and glassfish-web.xml files are used to accomplish JNDI redirection.  In general, inside of web.xml you specify what JNDI lookup your application will use to lookup a resource and then inside of glassfish-web.xml you map your application's lookup with the "JNDI Name" of the "JDBC Resource".  But with multiple context rules and automatic prepending of contexts, this too can get confusing so let's take a look at some examples.

Listing 1 shows a fully-qualified example.  In this example, the web.xml says the JNDI lookup used in your application is fully-qualified to "java:comp/email/database".  The glassfish-web.xml says "java:comp/email/database" is mapped to the real JNDI resource "EmailDS".

Listing 1: Fully-qualified redirect example

web.xml

  java:comp/email/database
  javax.sql.DataSource
    
glassfish-web.xml

  java:comp/email/database 
  EmailDS
    
For this example, let's consider some application lookups and see what happens.
 
@Resource(lookup = "%s")
OR
InitialContext.lookup("%s")
ResultComments
"java:comp/email/database"SUCCESSLookup matches what's in web.xml.  Successful redirection to real JNDI resource "EmailDS"
"java:comp/env/email/database"FAILSLookup does not match what's in web.xml!  Lookup has an "/env/" path which is not in web.xml.  Redirection fails.
"java:module/email/database"SUCCESSLookup does not match what's in web.xml, however, lookup succeeds because in a WAR the "java:comp" and "java:module" contexts are treated as the same thing for backward compatibility with previous EE versions. Successful redirection to real JNDI resource "EmailDS"
"EmailDS"SUCCESSRedirection avoided altogether, this is a direct lookup of the real JNDI resource.

Listing 2 shows a relative example.  In this example, the web.xml says the JNDI lookup used in your application is the relative name "Puppy".  The glassfish-web.xml says the relative name "Puppy" is mapped to the real JNDI resource "EmailDS".

Listing 2: Relative redirect example

web.xml

  Puppy
  javax.sql.DataSource
glassfish-web.xml

  Puppy 
  EmailDS

Now the big question is, this JNDI lookup name is relative to what?  Well, in this case it is relative to "java:module/env" or "java:comp/env" because remember in a WAR file the "java:comp" and "java:module" contexts are treated as the same thing for backward compatibility with previous EE versions.  These contexts are automatically prepended onto your relative name "Puppy".  Let's consider some application lookups and see what happens.
 
@Resource(lookup = "%s")
OR
InitialContext.lookup("%s")
ResultComments
"java:comp/env/Puppy"SUCCESSThe web.xml says "Puppy" which get's automatically prepended with "java:comp/env/".  Successful redirection to real JNDI resource "EmailDS"
"Puppy"FAILSLookup matchs what's in web.xml, but lookup forgot about the automatic context prepending.  Redirection fails.
"java:module/env/Puppy"SUCCESSThe web.xml says "Puppy" which get's automatically prepended with "java:comp/env/".  But remember, in a WAR the "java:comp" and "java:module" contexts are treated as the same thing for backward compatibility with previous EE versions. Successful redirection to real JNDI resource "EmailDS"
"EmailDS"SUCCESSRedirection avoided altogether, this is a direct lookup of the real JNDI resource.

So far, all these examples assume your application doing JNDI resource lookups itself.  However what if you are using a framework like JPA and the lookup of the JNDI resource is done for you?  What do you do then?  We'll look at this next.

A note about JPA persistence.xml
If you are using JPA, you specify the JNDI lookup using one of the "jta-data-source" tags like this:

EmailDS

However, the big question is what JNDI lookup string to use for this tag's value?  Well as far as I can make out, JPA does not use any of the redirection configured in web.xml and glassfish-web.xml.  Which means the value for <jta-data-source> must be the exact Payara/GlassFish "JNDI Name" value of the "JDBC Resource".  This of course couples the JPA configuration to the Payara/GlassFish EE server which may not be desirable.  Hopefully, this will be something the JPA expert group addresses in the next JPA spec update.

A note about @DataSourceDefinition
Java EE has the @DataSourceDefinition annotation which allows your application to create a data source by itself instead of relying on an EE server administrator to create the data source prior to your application's deployment.  This cuts down on some administration steps.  It has its advantages and disadvantages which I won't go into.  But what I do want to look at is how JNDI lookups work with a data source created by the @DataSourceDefinition annotation.

Redirection with web.xml and glassfish-web.xml
The @DataSourceDefinition annotation does not support redirection by web.xml and glassfish-web.xml.  If you think about it, this makes sense.  The @DataSourceDefinition is hard-coded in your source code so you know exactly what JNDI Name you used to create it so there is no need to redirect since the value is already in your code.
JPA data source 
There seemed to be a debate on whether or not @DataSourceDefinition support the JPA persistence.xml file.  The last word of the debate states it should be supported, that the JSR specification will be updated to make it more clear, and that a test will be added to the TCK to verify it. 
At this time (03 Nov 2015), in Payara/GlassFish, the @DataSourceDefinition annotation does not support the JPA persistence.xml file.  In other words, you cannot use the JNDI Name you used for the @DataSourceDefinition annotation in the JPA persistence.xml file.  I will continue to monitor this and will make an update to this article if anything changes.
Listing 3 shows a fully-qualified example.  In this example, the @DataSourceDefinition annotation has a JNDI Name which is fully qualified.  This exact, fully-qualified name, needs to be used in lookups in order for the lookup to succeed.

Listing 3: Fully-qualified @DataSourceDefinition example 
@DataSourceDefinition(
    name="java:global/jdbc/MyApplicationDS",
    className = "org.postgresql.ds.PGPoolingDataSource",
    url = "jdbc:postgresql://localhost:5432/email",
    user = "elephant",
    password = "jafj2r@#Rhh"
)

For this example, let's consider some application lookups and see what happens.
 
@Resource(lookup = "%s")
OR
InitialContext.lookup("%s")
ResultComments
"java:global/jdbc/MyApplicationDS"SUCCESSLookup matches what's in the @DataSourceDefinition#name annotation.
"java:global/env/jdbc/MyApplicationDS"FAILSLookup does not exactly match what's in the @DataSourceDefinition#name annotation.  The lookup has an "/env/" path which is not in the annotation

Listing 4 shows a relative example.  In this example, the @DataSourceDefinition annotation has a JNDI Name which is relative path.

Listing 4: Relative @DataSourceDefinition example

@DataSourceDefinition(
    name="MyApplicationDS",
    className = "org.postgresql.ds.PGPoolingDataSource",
    url = "jdbc:postgresql://localhost:5432/email",
    user = "elephant",
    password = "jafj2r@#Rhh"
)

Now the big question is, this JNDI lookup name is relative to what?  Well, in this case it is relative to "java:module/env" or "java:comp/env" because remember in a WAR file the "java:comp" and "java:module" contexts are treated as the same thing for backward compatibility with previous EE versions.  These contexts are automatically prepended onto your relative name "MyApplicationDS".  Let's consider some application lookups and see what happens.
 
@Resource(lookup = "%s")
OR
InitialContext.lookup("%s")
ResultComments
"java:comp/env/MyApplicationDS"SUCCESSThe @DataSourceDefinition says "MyApplicationDS" which get's automatically prepended with "java:comp/env/".  "
"MyApplicationDS"FAILSLookup matches what's in @DataSourceDefinition, but lookup forgot about the automatic context prepending.  So the lookup fails.
"java:module/env/MyApplicationDS"SUCCESSThe @DataSourceDefinition says "MyApplicationDS" which get's automatically prepended with "java:comp/env/".  But remember, in a WAR the "java:comp" and "java:module" contexts are treated as the same thing for backward compatibility with previous EE versions.

Finaly, listing 5 shows a special condition of a fully-qualified example.  In this example, the @DataSourceDefinition annotation has a JNDI Name which is fully qualified, but to special "java:comp/env/" context and path.

Listing 5: Special case fully-qualified @DataSourceDefinition example 
@DataSourceDefinition(
    name="java:comp/env/jdbc/WebAppDS",
    className = "org.postgresql.ds.PGPoolingDataSource",
    url = "jdbc:postgresql://localhost:5432/email",
    user = "elephant",
    password = "jafj2r@#Rhh"
)

For this example, let's consider some application lookups and see what happens.
 
@Resource(lookup = "%s")
OR
InitialContext.lookup("%s")
ResultComments
"java:comp/env/jdbc/WebAppDS"SUCCESSLookup matches what's in the @DataSourceDefinition#name annotation.
"java:module/env/jdbc/WebAppDS"SUCCESSLookup does not exactly match what's in the @DataSourceDefinition#name annotation.  The lookup uses the "module" context which is not in the annotation.  But remember, in a WAR the "java:comp" and "java:module" contexts are treated as the same thing for backward compatibility with previous EE versions.


That's it,
Enjoy!




July 15, 2015

Begin and end index of a regular expression pattern matched string

This is a quick tip on regular expressions.  Nothing too exciting, but something I use often enough but can never remember so I always have to look it up.

The String.indexOf("match me") method is handy for finding the beginning index of some pattern within a String you want to match.  Combine this beginning index with "match me".length() and you can get the ending index as well.  This works for finding simple substrings, but what if the pattern is more complicated and needs a regular expression?  Let's take a look at the code in listing 1.

Listing 1: Simple pattern matching.
package pattern.matching;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PatternMatching {

    public static void main(String[] args) throws Exception {
        StringBuilder searchMe = new StringBuilder();
        searchMe.append("hello").append("\n");
        searchMe.append(" package doctor;  ").append("\n");
        searchMe.append("name // comment").append("\n");
        searchMe.append("/* continue */").append("\n");
        searchMe.append("int yesterday = 9;").append("\n");
        searchMe.append("tomorrow!").append("\n");
        
        System.out.printf("BEFORE\n------\n%s", searchMe.toString());
        
        final Pattern pattern = Pattern.compile("^ *package .*; *$", Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(searchMe.toString());

        if (matcher.find()) {
            System.out.println();
            System.out.printf("Start index: %d\n", matcher.start());
            System.out.printf("End index:   %d\n", matcher.end());
            System.out.printf("Match found: [%s]\n", matcher.group());            
            searchMe.replace(6, 24, "I've been replaced...so sad :(");
        } else {
            System.out.println("Matcher matched nothing! ");
        }
        
        System.out.println();
        System.out.printf("AFTER\n-----\n%s\n", searchMe.toString());       
    }
}
Listing 2: Output
BEFORE
------
hello
 package doctor;  
name // comment
/* continue */
int yesterday = 9;
tomorrow!

Start index: 6
End index:   24
Match found: [ package doctor;  ]

AFTER
-----
hello
I've been replaced...so sad :(
name // comment
/* continue */
int yesterday = 9;
tomorrow!
Listing 1 shows the code for a simple regular expression pattern matching of a String.  The Matcher is looking for a simple pattern.  If found, the Matcher.start and Matcher.end methods are used to get the beginning and ending indices within the String.  The StringBuilder.replace method is then used to replace the matched pattern with another String.  As you can see in Listing 2, the output of the application shows the before state, the matcher information, and the after state.

So pretty simple :)
Enjoy!

June 23, 2015

Bamboo, maven-release-plugin, public/private key SSH access to SVN, password access to Nexus

Introduction

Bamboo is great for performing builds.  The maven-release-plugin is great at releasing new versions of your software. SVN is a great source code repository. SSL public/private keys are great for keeping everything secure, and Nexus is great for Maven artifacts.  What's not so great is trying to get all these things working together!  What we'll look at in this blog is how to configure Bamboo build steps for both the repository host and the Maven configuration. Also, we'll look at how to configure your project's pom. Let's start with the Bamboo repository host build step.

Bamboo repository host build step

First, you need to configure the Bamboo repository host build step so Bamboo can checkout your source code:

Figure 1: Repository host build step

Looking at figure 1, the repository host setup is pretty easy: 

(A)
The URL.  It will need to be in the form "svn+ssh" instead of "https". 

(B)
The username.  It's a good idea to create an account specifically for bamboo to use. 

(C)
The authentication type...no big deal. 

(D)
A variable reference to the fully-qualified location of the SSL key.

Next let's take a look at the Maven configuration build step.

Maven configuration build step

Figure 2: Maven configuration build step
Let's take a look at this configuration one field at a time.

(A)
The version of Maven to use for this build. I did this research using 3.0.5.  No guarantees other versions of Maven will work.

(B)
The Maven goal to perform along with some additional attributes.

--batch-mode release:clean release:prepare release:perform
This runs the release plugin in batch mode so there is no user interaction and all defaults are used.

-s /home/bamboo_builder/.m2/bamboo_builder-settings.xml
This configures Maven to use a specific settings file.  In most cases the same Maven settings will be used for all builds in your organization. But, if you have builds which require unique settings, this is how to configure which settings file to use.  The main purpose of this file is to contain the username and encrypted password to access Nexus  (Maven Encryption, 2015, June 21), which will look something like listing 1.

Listing 1: Nexus username & password in settings.xml

  
    nexus
    bamboo_builder
    {lAHiuyjiu4387y5jKLHE29kjlkahyr/=}
  

(C)
The version of Java to use.

(D)
The environment varibles for the build. This is most important field.  After much research, I found these values MUST BE CONFIGURED HERE (not in goals) otherwise the build will fail.

SVN_SSH="ssh -v -l bamboo_builder -i /home/bamboo_builder/.ssh/id_rsa"
This environment variable configures ssh to use the bamboo_builder user and the id_rsa private key when establishing an SSL connection with SVN.  Now, Maven itself has a number of different ways to configure a username and private key both within a settings.xml file and within the pom.xml for a project.  I tried them all and they all failed.  This was the only way I got it to work.

MAVEN_OPTS="-Dsettings.security=/home/bamboo_builder/.m2/bamboo_builder-security-settings.xml"
This configures Maven with a master password used to encrypt the other passwords in the settings.xml file (Maven Encryption, 2015, June 21).  Though not strictly necessary, it's good to have this file.  If you do have it, this is where you put the configuration for the build. Listing 2 shows what this looks like

Listing 2: Maven master password

    {jj498POHIU4HRUhj2rjpu2ajkshdfur/YI=}

(E)
If your project does not have unit tests, uncheck this box so the build won't fail.

Finally, your project's pom.xml needs a bit of special configuration so let's take a look at that next.

Project pom.xml

The project's pom.xml needs a couple configurations: The <scm> tag and the maven-release-plugin version.

First the <scm> tag needs to be configured so Maven knows where the project is located in SVN.  Listing 3 shows what this tag will look like. 

    NOTE: All 3 properties are needed...don't skip any!

Listing 3: The pom <scm> tag 

    scm:svn:svn+ssh://my.subversion.com/data1/svns_repo/path/to/my/project/trunk
    scm:svn:svn+ssh://my.subversion.com/data1/svns_repo/path/to/my/project/trunk
    scm:svn:svn+ssh://my.subversion.com/data1/svns_repo/path/to/my/project/trunk

Next the maven-release-plugin version needs to be configured. The default version of the maven-release-plugin for Maven 3.0.4 has some bugs in it, most notibly when trying to use this configuration to perform mult-module reactor builds.  So your project pom.xml must be configured to use a more recent version of the maven-release-plugin.  Listing 4 shows this.

Listing 4: The maven-release-plugin version

  
    
      
        org.apache.maven.plugins
        maven-release-plugin
        2.5.1
        
          false
        
      
    
  

Hopefully this fully documents everything that's needed.  Enjoy!

References
Maven Encryption. (2015, June 21). maven.apache.org. Retrieved June 23, 2015 from https://maven.apache.org/guides/mini/guide-encryption.html





June 10, 2015

Mocking properties of super classes in different packages for unit testing

Suppose I have the following reusable abstract class.
package org.ferris.io;
import org.apache.log4j.Logger;  
import javax.inject.Inject;
public abstract class AbstractPropertiesFile extends File {
  @Inject
  protected Logger log; 
  // . . .
}
Also suppose my application has a concrete implementation of this abstract class.
package org.ferris.application.preferences;
import  org.ferris.io.AbstractPropertiesFile;
public class PreferencesPropertiesFile extends AbstractPropertiesFile{
// . . .
} 
When unit testing PreferencesPropertiesFile, the challenge is to mock the protected Logger property of the super class.  It's a challenge because:
  1. The concrete class in in a different package than the abstract class
  2. The Logger property is being injected by CDI for you so there is no setter method.
Let's look at the first challenge.  A possible solution is to repackage my application and unit test to use the org.ferris.io package, but this means moving the PreferencesPropertiesFile to a package which doesn't make much sense for it to be in. Now let's look at the second challenge.  Adding a setter method would solve it, but do you really want to add a method just for unit testing purposes?  Neither of these solutions seem right.

A better solution is for the unit test to set the property of the super class using reflection. Though I'm sure many would argue against this solution, I'm OK with it because let's face it, every framework nowadays is using reflection or byte code manipulation, or proxying.  So a little more won't hurt.

Here is how you would setup the unit test.
@Mock
Logger logMock;
// . . .
@Test
public void someTest() {
    PreferencesPropertiesFile props = new PreferencesPropertiesFile ();
    {
        Field logField = AbstractPropertiesFile.class.getDeclaredField("log");
        logField.setAccessible(true);
        logField.set(props, logMock);
    }
    // . . .
} 
Enjoy!