Friday, October 18, 2013

JEUS application server: The story continues

In a previous blog post I wrote about JEUS, a Java EE 7 certified application server that is popular in Korea but pretty much unknown elsewhere. In this follow up I'll report about the latest findings and take a look at how to deploy an application to JEUS and do some debugging.

The previous installment was quite a story, but there's more. The us domain that was previously just gone briefly flickered into existence again, and it indeed offered the much sought after JEUS 7 download link; jeus70_linux_x86.bin. In order to get this I once again had to register a new account, and this time the signup process limited my password to 12 characters and did not allow capitals and non-alphanumerics (the 4 other signup processes that I went through did allow this). Unfortunately after a few hours the site suddenly featured completely different content. It's now largely, but not entirely, identical to the main corporate site, and doesn't feature the JEUS 7 download link anymore.

The tech site appeared to have a forum "hidden" behind the Q & A link. With some 5 to 10 posts per day it's clear that JEUS is definitely very much alive in Korea. (Google translate unfortunately stops working after you click on a post, so the forum is best viewed directly using the Chrome auto-translation).

Just as the entire site, the forum posts are mainly about JEUS 5 (J2EE 1.4, 2003) and JEUS 6 (Java EE 5, 2006). Apparently Java EE 6 (2009) hasn't fully penetrated the Korean market yet, although occasionally Korean users too wonder why JEUS 7 is not out there in the open. After asking on the forum the kind people from TmaxSoft where friendly enough to upload a JEUS 7 trial version again, this time on the English variant of the tech site ((which is rather empty otherwise, but now does feature this unique download)

There appears to be an Eclipse plug-in available after all on the download page, called JMaker, which in the typical ancient versions trend is of course for Eclipse 3.2 (2006) and supports JEUS 5. Next to the download page there's also a "resource room", which has a download page as well that has another Eclipse plug-in called the Jeus Bridge. This one supports Eclipse 3.5 (2009), which is slowly creeping towards the modern world, but unfortunately it too only supports JEUS 5. I got in touch with JEUS' lead developer Yoon Kyung Koo and he let me know they're attempting to open up the plug-in, which I take as meaning it will eventually appear in the Eclipse marketplace and such.

Downloads

So far I've found the following download links:

JEUS binary Size Initial release refJava EE versionDocumentation Dev preview Public download Site
jeus50-unix-generic.bin 265 MB May 2005 J2EE 1.4 JEUS 5 X X Korean tech site
jeus50-win.exe 205 MB X X
jeus60-winx86-en.exe 147 MB June, 2007 Java EE 5 JEUS v6.0 Fix8 Online Manual (11/2011) X X
jeus60-winx64-ko.exe 190 MB X X
jeus60_unix_generic_ko.bin 268 MB X X
jeus70_linux_x86.bin 133 MB June, 2012 Java EE 6 JEUS v7.0 Fix#1 Korean Online Manual (04/2013)

JEUS v7.0 Fix#1 English PDF set (08/2013)
V X US corporate site (dead link, no other source)
jeus70_unix_generic.bin 546 MB X X English tech site
jeus70_win_x86.exe 441 MB X X
jeus70_win_x64.exe 445 MB X X
jeus80_unix_generic_ko.bin 165 MB Est. Q4 2014 Java EE 7 [no documentation yet] V V Int. corporate site

 

Deploying to JEUS 8

Just as GlassFish, WebLogic and Geronimo among others, it seems it's only possible to deploy an application to JEUS via a running server. The simplicity that JBoss, TomEE and Tomcat offer by simply copying an archive to a special directory is unfortunately not universally embraced by Java EE implementations.

In order to deploy an app to JEUS 8 we first start it again:

./bin/startDomainAdminServer -domain jeus_domain -u administrator -p admin007
After it's started we connect to the running instance via the jeusadmin command:
./bin/jeusadmin -u administrator -p admin007
In my home directory I have a small war that I normally use for quick JASPIC tests. In order to deploy this we first have to install it via the admin console that we just opened:
[DAS]jeus_domain.adminServer>installapp /home/arjan/abc.war
Successfully installed the application [abc_war].
This command will copy the .war to [jeus install dir]/domains/jeus_domain/.uploaded and [jeus install dir]/domains/jeus_domain/.applications. After this kind of pre-staging step we can do the actual deploy:
[DAS]jeus_domain.adminServer>deploy abc_war -all
deploy the application for the application [abc_war] succeeded.
Note that the first argument for the deploy command is "abc_war". This is the application ID that is assigned to the application when it was installed and defaults to the full archive name with all periods replaced by underscores. There is more information available for each command via the help command, e.g. help deploy will list all arguments with some short explanation.

The deploy command will add a new entry to [jeus install dir]/domains/jeus_domain/config/domain.xml:

<deployed-application>
    <id>abc_war</id>
    <path>/home/arjan/jeus8/domains/jeus_domain/.applications/abc_war/abc.war</path>
    <type>WAR</type>
    <targets>
        <all-target/>
    </targets>
    <options>
        <classloading>ISOLATED</classloading>
        <fast-deploy>false</fast-deploy>
        <keep-generated>false</keep-generated>
        <shared>false</shared>
        <security-domain-name>SYSTEM_DOMAIN</security-domain-name>
    </options>
</deployed-application>

Requesting http://localhost:8808/abc/index.jsp?doLogin=true in a browser did load the correct test page, but JASPIC itself didn't work as expected. We should see the authenticated user's name and role, but this didn't happen:

This is not entirely unexpected as most servers need a special configuration (typically a vendor specific group-to-role mapping) before JASPIC starts working and I haven't added any such configuration for JASPIC yet.

Debugging JEUS 8

In order to find out where things go wrong it's always handy to do a little debugging. Maybe it's not the configuration at all, but perhaps the @WebListener isn't called that installs the SAM, or maybe it is, but then the SAM isn't called, etc. But without any tooling support, how do we debug an application running on JEUS? Using good-old System.out debugging gave me some hints. The SAM is not called for public pages (it should be) but it is indeed called for protected pages. Unfortunately despite being called for a protected page there still wasn't any sight of the authenticated name nor roles. Obviously we need some -real- debugging.

The most straightforward method to do that in this case is via remote debugging, which means we need to add a special agentlib parameter when starting up JEUS. [jeus install dir]/bin/startDomainAdminServer seemed like an obvious place as this starts a Java application that looks to be the server. Unfortunately it appeared to be only a launcher that launches a new process representing the real server and then exits. After some digging I found out that additional parameters for this "real server" can be specified in the same [jeus install dir]/domains/jeus_domain/config/domain.xml file that we saw before via the jvm-option element:


    
        adminServer
        
        
            
                -Xmx1024m -XX:MaxPermSize=128m 
                -agentlib:jdwp=transport=dt_socket,address=1044,server=y,suspend=y
            
        
        
    

Starting JEUS 8 again will cause it to halt and wait for a debug connection:

[launcher-1] [Launcher-0012] Starting the server [adminServer] with the command
 /opt/jdk1.7.0_40/jre/bin/java -DadminServer -Xmx1024m -XX:MaxPermSize=128m -agentlib:jdwp=transport=dt_socket,address=1044,server=y,suspend=y -server -Xbootclasspath/p:/home/arjan/jeus8/lib/system/extension.jar -classpath /home/arjan/jeus8/lib/system/bootstrap.jar -Djava.security.policy=/home/arjan/jeus8/domains/jeus_domain/config/security/policy -Djava.library.path=/home/arjan/jeus8/lib/system -Djava.endorsed.dirs=/home/arjan/jeus8/lib/endorsed -Djeus.properties.replicate=jeus,sun.rmi,java.util,java.net -Djeus.jvm.version=hotspot -Djava.util.logging.config.file=/home/arjan/jeus8/bin/logging.properties -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.util.logging.manager=jeus.util.logging.JeusLogManager -Djeus.home=/home/arjan/jeus8 -Djava.net.preferIPv4Stack=true -Djeus.tm.checkReg=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Djeus.domain.name=jeus_domain -Djava.naming.factory.initial=jeus.jndi.JNSContextFactory -Djava.naming.factory.url.pkgs=jeus.jndi.jns.url -Djeus.server.protectmode=false -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=/home/arjan/jeus8/domains/jeus_domain/servers/adminServer/logs/jvm.log jeus.server.admin.DomainAdminServerBootstrapper -domain jeus_domain -u administrator -server adminServer .
[2013.10.18 23:36:56][2] [launcher-1] [Launcher-0014] The server[adminServer] is being started ...
Listening for transport dt_socket at address: 1044

After this point we can attach to it via Eclipse:

If everything went well, you'll see JEUS 8's thread appearing in the debug view:

Setting a break-point inside the SAM and requesting the protected page again indeed breaks us into the debugger:

Without diving much further in the details it appears that despite passing the JASPIC TCK, the handler (shown in the image above as JeusCallbackHandler) does exactly *nothing*, so a standard JASPIC module can never really work. I confirmed that this is indeed the case with JEUS' lead developer. Remember though that the JEUS version being tested here is just a developer preview and the final version will most likely implement the required behavior correctly.

Interestingly, after playing around with JEUS' authentication some more it appeared that JEUS uses JASPIC auth modules to implement the build-in Servlet authentication methods. This is almost certainly also without using the Callback handler (as it does absolutely nothing, what would be the point?) so it's not in a fully JASPIC compliant way, but it's nevertheless really interesting. All other Java EE servers that I looked at don't actually use Java EE authentication as their native authentication system, but just wrap the JASPIC interfaces on top of whatever else they're using natively. JEUS has an exclusive here by basing their authentication directly on JASPIC. If they only can make it fully compliant JEUS will be one of the most interesting servers for JASPIC our there.

Redeploying

Deploying a single war once that's already in your home is one thing, but how to easily see your changes after editing in your IDE? Unfortunately there's no real easy solution for this without tooling support, but I cooked up the following admittedly very crude script that when executed from the (Maven) project folder somewhat gets the job done:

#!/bin/sh

WAR_HOME=/home/arjan/eclipse43ee/workspace/auth/target/

# Rebuild project
mvn package
cp ${WAR_HOME}/auth-0.0.1-SNAPSHOT.war ${WAR_HOME}/auth.war

# Redeploy to JEUS
~/jeus8/bin/jeusadmin -u administrator -p admin007 "undeploy auth_war"
~/jeus8/bin/jeusadmin -u administrator -p admin007 "uninstall auth_war"
~/jeus8/bin/jeusadmin -u administrator -p admin007 "installapp ${WAR_HOME}/auth.war"
~/jeus8/bin/jeusadmin -u administrator -p admin007 "deploy auth_war -all"

Meanwhile I have a tail on the log in another console:

tail -f domains/jeus_domain/servers/adminServer/logs/JeusServer.log

It works, but it's not exactly the experience you'd normally expect when working with an IDE.

Finally, we stop the server again via the following command:

./bin/stopServer -host localhost -u administrator -p admin007

Conclusion

In this article we haven't really extensively tested JEUS, but we just went through the steps of finding the download links, installing it (see previous article), deploying a really small application, and doing some debugging on the Java EE 7 developer preview. I didn't yet test a bigger application such as the OmniFaces showcase, something I still plan to do for JEUS 7 (the production ready Java EE 6 implementation).

By putting up English documentation and downloadable trial versions of JEUS 7 as well as a developer preview of JEUS 8 TmaxSoft has made some small but important steps to get JEUS out of international obscurity. Still they have some way to go. While we saw that deployment and debugging can be done without tool support, very few developers would consider this a viable option and because of that may not be really eager to try out JEUS.

An important next step for TmaxSoft will be to indeed make the required tooling easily and freely available.

Arjan Tijms

Thursday, October 17, 2013

The most popular Java EE 7 technologies according to ZEEF users

For some time now I'm keeping a page at ZEEF.com about Java EE 7. The page covers pretty much all Java EE 7 technologies, so the amount of clicks on the links of this page may give some indication of what parts of Java EE 7 are most popular with users.

At the moment of writing the top 20 list for the last 8 weeks looks as follows:

Position Link Category
1 Beginning Java EE 7 by Antonio Goncalves Java EE 7 overal
2 The Java EE 7 Tutorial Java EE 7 overal
3 Java EE 7 Essentials by Arun Gupta Java EE 7 overal
4 Java EE 7 code samples Java EE 7 overal
5 What's New in JAX-RS 2.0? (2) JAX-RS 2.0
6 Java EE 7: And Then What? Java EE 7 overal
7 JSF 2.2 new features in context [slides] JSF 2.2
8 CDI 1.1 available :-) CDI 1.1
9 Java EE 7 support in Eclipse 4.3 Java EE 7 overal
10 JSF 2.2: HTML5 friendly markup JSF 2.2
11 A closer look at the JSF 2.2 View Action JSF 2.2
12 What's new in JSF 2.2? JSF 2.2
13 Getting Started with JSON-P Java API for JSON Processing (JSON-P) 1.0
14 JSF 2.2 and HTML5 JSF 2.2
15 An overview of batch processing in Java EE 7 Batch Applications for Java Platform 1.0
16 Method validation in Bean Validation 1.1 Bean Validation 1.1
17 What's new in EJB 3.2 ? EJB 3.2
18 Java EE 7 Delivers Expression Language Enhancements Expression Language 3.0
19 Injecting An ExecutorService With Java EE 7 Concurrency utils for Java EE
20 What's new in Java EE 7's authentication support? JASPIC 1.1

As can be seen the general Java EE 7 topics are by far the most popular. There may be multiple explanations for this though. Is it simply the fact that the block containing the Java EE 7 links is the top left one (which people thus typically see first), or the fact that the page's title is "Java EE 7", so it primarily attracts people looking for general Java EE 7 stuff? Or is it indicative that people are increasingly seeing Java EE 7 as a single platform instead of a mere collection of individual specs?

After Java EE 7, a link about what's new in JAX-RS 2.0 was the most popular one, closely followed by links about JSF 2.2 and CDI 1.1. Aggregated on total clicks per category (not shown in the table) JSF 2.2 was the most popular category after Java EE 7.

With some distance we see JSON-P, JBatch, Bean Validation 1.1, EJB 3.2, EL 3.0, Concurrency utils for Java EE and JASPIC 1.1. Remarkable is that JPA 2.1, JMS 2.0, Servlet 3.1 and WebSocket didn't make it into the top 20 list for the last 8 weeks. Also remarkable is that JASPIC 1.1, which normally doesn't seem to be that well known among users, just barely makes it into the top 20 of most popular links.

Ordered by the highest ranking single link, the most popular Java EE 7 technologies according to ZEEF users thus seem to be the following:

  1. Java EE 7 overal
  2. JAX-RS 2.0
  3. JSF 2.2
  4. CDI 1.1
  5. JSON-P
  6. JBatch
  7. Bean Validation 1.1
  8. EJB 3.2
  9. EL 3.0
  10. Concurrency utils for Java EE
  11. JASPIC 1.1

Conclusion

We can't draw too many conclusions from this list, as the location of the link blocks on the page, the position of the links within each block, as well as the titles of the posted links play a role as well. As I'm active in the JSF community and not in say the JPA one, there may be some bias for JSF as well. Still, the page has a diverse amount of links, a diverse amount of referrals and there were a few thousand visitors over the last 8 weeks so I hope the data gives us at least some insight.

Arjan Tijms

Tuesday, September 24, 2013

Diving into the unknown: the JEUS application server

There are quite a number of Java EE implementations. At the open source front JBoss, GlassFish and increasingly TomEE are very well known. On the commercial side there's WebLogic, WebSphere and increasingly Liberty that are rather well known as well.

A couple of implementations are somewhat less known such as Resin and Geronimo/WASCE, but you'd expect many advanced Java EE developers to have heard of those. Yet another implementation is JOnAS, which arguably is much less known.

Then however, there are also the truly obscure (in the sense of not widely known) ones such as TMax JEUS, Fujitsu Interstage Application Server, Hitachi uCosminexus Application Server and NEC WebOTX Application Server. These seem to be virtually unknown among general Java EE users. The only way I found out that these servers even existed was because of them being mentioned on Oracle's Java EE compatibility page.

The most famous of these unknown servers is JEUS; every ~3 years it makes it into the news as the first server after the RI (GlassFish) to be certified for the new Java EE version. Considering that JEUS is a full Java EE implementation this no small feat. Now Applications Servers have it somewhat easier these days as they rarely have to implement any of the major sub-specs like JSF, CDI, JPA, Bean Validation, etc themselves but can instead choose from one of the readily available open source implementations. Still, there's a lot of extra work into building a complete AS out of them, and for some sub-specs like e.g. JASPIC there isn't a really reusable (open source) implementation available.

As I'm somewhat in the business of testing JASPIC implementations and JEUS should probably ship with its own independent JASPIC implementation, plus the fact that we want to test OmniFaces on as many servers as possible, I found it to be interesting to take a deeper look at it.

The first thing I found out is that JEUS really is obscure. Besides some news articles that JEUS is the first AS to be Java EE 7 certified, there's hardly anything to be found. On StackOverflow for example when you search for "JBoss" there are about 26000 results. Searching for "GlassFish" yields about 16500 results. Searching for "JEUS" however has... 3 results, of which 2 from the same user. Searching on Google gives some results, but nearly all of them are in Korean. The very few (old) posts in English are written by someone who judging by his name is also Korean.

Clearly JEUS is thus very much a Korean thing. It might well be that JEUS enjoys enormous popularity in Korea, but for some reason this popularity doesn't really extend beyond Korea. As mentioned JEUS doesn't really exist on StackOverflow, I've never seen it being mentioned on forums, or in discussions on the various Java (EE) mailing lists (although occasionally TMaxSoft experts do post) and at OmniFaces we have never received any question or bug reports from a JEUS user. The Eclipse marketplace does not carry any plug-in for JEUS and it's not listed among the servers in the "download additional server adapters" dialog either. Yet logic dictates that there must be some user base that justifies the colossal investment of developing and maintaining a full Java EE implementation.

Downloading JEUS proved to be a bit troublesome. There's a company site at tmaxsoft.com, but this is the typical corporate website that contains some nice projections and customer testimonials (indeed mainly Korean companies again) without any real technical information or any kind of download link. Frustrating is that despite the site being composed of static documents, it uses JavaScript to put new content on a page making it impossible to link to anything. Even worse is that a number of links just don't seem to work. At the JEUS section (to which I can't link because of the js issue), there's a link to download the brochure, but after clicking on it simply nothing happens. I tried to register from the JEUS section and got directed to an actual URL (http://tmaxsoft.com/jsp/popup/info_reg.jsp), but after filling out the form nothing happened. When trying to register from the index page I got redirected to another URL (http://tmaxsoft.com/member/memberRegister.do?strMode=INSERT&join_gubun=web) which presented a rather similar but still different form. After I filled this one out I was rewarded with a friendly confirmation:

Register has been completed.
Please authentication with your email address which is registerd when you signing up.
But when I did just that, a got a somewhat less friendly message:
this ID has not been certificated
 with your e-mail for register yet.
Besides the not entirely correct usage of English (which is a sin I also not rarely commit despite being partially of English descent), this was all not really encouraging.

After some Googling, I stumbled upon another TMaxSoft site, a proper technical one this time: technet.tmax.co.kr :) Unfortunately it's all in Korean. You can change to English, but that gives you a rather different site instead: technet.tmaxsoft.com. Luckily Google Translate does a fairly decent job. Reading the content it's weird that for an application server that always wins the certification race for a new Java EE version, the overall description of the server is about J2EE 1.3 features! :( At the bottom of the document it goes on to describe that JEUS 4.2 is compatible with J2EE 1.3, and not a word about JEUS 7 (Java EE 6) let alone JEUS 8 (Java EE 7).

Registering again via this site using the translated Korean version however finally did work! I could now access a download page, which offered me to download JEUS 5 (J2EE 1.4) and JEUS 6 (Java EE 5). After browsing some more through the site I found a JEUS 4.x Development Guide (which should be over a decade old), and clicking on the online manual brought up some JEUS 5 docs (nearly a decade old), and when downloading the manual I would get something for JEUS 6 (still some 6 years old). I checked the JEUS section of their corporate Chinese site, but it too has JEUS 6 listed as the latest version. From here I could downloaded the brochure, but it doesn't say much. There are links to a US site, but the domain seems to be gone. Some clever fiddling with the URL of the online manual at the Korean site revealed that the JEUS 7 online manual is in fact there, namely at technet.tmax.co.kr/kr/edocs/jeus/70/index.html. Why this isn't linked as the default (is it even linked from somewhere at all?) is beyond me.

Just to be sure I also tried the English technet.tmaxsoft.com. Curiously, I had to register again for this one (it really is a separate site). Unfortunately, here too the latest JEUS version that can be downloaded from the Trial Versions section is JEUS 6 and the latest manual is again JEUS 6. Even stranger is that the US version of the TMaxSoft site apparently did mention JEUS 7 and had some clear download links for a jeus60_unix_generic_en.bin and jeus70_linux_x86.bin, according to an archived capture of the domain when it was still up.

This all didn't exactly boost my confidence in JEUS. How can they be the first with a new Java EE version all the time, yet have a website that seems stuck years in the past and inconsistently presents me documentation about different (ancient) versions? It just didn't make a whole lot of sense. At any length the JEUS 7 manual that I found seemed fairly professional and thorough, but it's mainly about the classic Java EE stuff (Servlet, JSP, EJB (including CMP!), JCA, etc). I didn't see JSF and CDI being mentioned anywhere, but it does cover JPA.

After some more Googling I finally landed on a developer preview page at the corporate site again that did contain a direct download link for JEUS 8. (Again, I wonder why this isn't directly linked from the tech site, and why it isn't on the main download page.) Via this I got a 160.5MB large file called jeus80_unix_generic_ko.bin. The first few hundred lines of this file are a shell script that starts some Java based installer that extracts itself. It's a clever trick to have a one file kind of universal installer. Unfortunately it wouldn't run on OS X:

Preparing to install...
Extracting the installation resources from the installer archive...
Configuring the installer for this system's environment...

Launching installer...

Preparing CONSOLE Mode Installation...

===============================================================================
JEUS8.0                           (created with InstallAnywhere by Macrovision)
-------------------------------------------------------------------------------


The installer cannot run on your configuration. It will now quit.
Luckily I have an Ubuntu machine as well, on which the install did work:
Introduction
------------

InstallAnywhere will guide you through the installation of JEUS8.0.

It is strongly recommended that you quit all programs before continuing with 
this installation.
I was of course not going to quit all programs (does anyone seriously do this???) and continued. After accepting the license I could choose a platform:
Choose Platform
---------------

Choose the operating system and architecture :
1)HP-UX PA-RISC
2)HP-UX Itanium
3)Solaris UltraSPARC
4)Solaris x86
5)Solaris x64
6)AIX 5.x, 6.x, 7.x PowerPC
7)Linux Itanium
8)Linux x86
9)Linux x64
Quit) Quit Installer

Choose Current System (DEFAULT: 9): 
And after asking for an installation folder I could choose a type (?):
Installation type
-----------------

Please choose the Install Set to be installed by this installer.

  ->1- Domain Admin Server
    2- Managed Server

ENTER THE NUMBER FOR THE INSTALL SET, OR PRESS  TO ACCEPT THE DEFAULT
As I have no idea what the difference is, I went for the default. After that it asked me for an installation type (production/dev), for a JDK path (interestingly it only accepted a JDK 7 version), an administrator password (it wanted a minimal length and some numbers, I choose "admin007" and a "domain" name (I went for the default "jeus_domain"). This installed 207MB in a folder, with the following layout:
bin    docs     lib      nodemanager  setup      ThirdPartyLicenses.txt
derby  domains  license  readme.txt   templates  UninstallerData
Interestingly setup/lib_native had the following content:
aix5l_32  hp-ux_64       linux_ia64    linux_x86_32  sunos_32   sunos_x86
aix5l_64  hp-ux_ia64_32  linux_ppc_32  linux_x86_64  sunos_64   win32
hp-ux_32  hp-ux_ia64_64  linux_ppc_64  mac           sunos_x64  win64
Note the presence of the mac folder! While setup/bin only contains "binaries" for win and unix, the actual binaries are just shell scripts. E.g. /bin/startDomainAdminServer contains this as its most important part:
#!/bin/sh

[...]

# execute jeus with echo
set -x
"${JAVA_HOME}/bin/java" $VM_OPTION  $SESSION_MEM                            \
    -Xbootclasspath/p:"${JEUS_HOME}/lib/system/extension.jar"               \
    -classpath "${LAUNCHER_CLASSPATH}"                      \
    -Dsun.rmi.dgc.client.gcInterval=3600000                                 \
    -Dsun.rmi.dgc.server.gcInterval=3600000                                 \
    -Djava.library.path="${JEUS_LIBPATH}"                                   \
    -Djava.endorsed.dirs="${JEUS_HOME}/lib/endorsed"                        \
    -Djava.naming.factory.initial=jeus.jndi.JNSContextFactory               \
    -Djava.naming.factory.url.pkgs=jeus.jndi.jns.url                        \
    -Djava.net.preferIPv4Stack=true                                         \
    -Djava.util.logging.manager=jeus.util.logging.JeusLogManager            \
    -Djava.util.logging.config.file="${JEUS_HOME}/bin/logging.properties"   \
    -Djeus.home="${JEUS_HOME}"                                              \
    -Djeus.jvm.version=${VM_TYPE}                                           \
    -Djeus.tm.checkReg=true                                                 \
    -Djeus.properties.replicate=jeus,sun.rmi,java.util,java.net             \
    ${JAVA_ARGS}                                                            \
This all looks like it could possibly run on OS X anyway but I didn't try this for now.

Most of the libraries that make up the server are in lib/system:

activation.jar                                            http.jar                    jeus-omgapi.jar                    resolver.jar
appcompiler.jar                                           jasper.jar                  jeus-servlet.jar                   saaj-impl.jar
bootstrap.jar                                             javaee.jar                  jeus-store.jar                     sasl.jar
classmate-0.8.0.jar                                       javax.json.jar              jeus-tm.jar                        serializer.jar
com.ibm.jbatch-ri-spi.jar                                 jaxb1-impl.jar              jeus-toplink-essentials.jar        shoal.jar
com.ibm.jbatch-runtime-all.jar                            jaxb2-basics-runtime.jar    jeusutil.jar                       sigar-1.6.4.jar
commons-cli.jar                                           jaxb-impl.jar               jeus-websocket.jar                 sjsxp.jar
commons.jar                                               jaxb-xjc.jar                jeus-ws.jar                        snmp_agent.jar
corba-asm.jar                                             jaxrpc-impl.jar             jline.jar                          stax-ex.jar
corba-codegen.jar                                         jaxrpc-spi.jar              jms.jar                            streambuffer.jar
corba-csiv2-idl.jar                                       jaxws-rt.jar                jmx-description.jar                tmaxjce_jdk15x.jar
corba-internal-api.jar                                    jaxws-tools.jar             jmxremote.jar                      TMAX-JEUS7.0-MIB.mib
corba-newtimer.jar                                        jboss-logging-3.1.1.GA.jar  jmxtools.jar                       toplink-essentials-agent.jar
corba-omgapi.jar                                          jeus-ant-util.jar           jsse14_repack.jar                  toplink-essentials.jar
corba-orbgeneric.jar                                      jeusapi.jar                 jxerces.jar                        trilead-ssh2.jar
corba-orb.jar                                             jeusasm.jar                 libCUtility.so                     weld-api.jar
deploy.jar                                                jeus-concurrent.jar         libJeusNet.so                      weld-core.jar
derby.jar                                                 jeus-config.jar             libjtiagent.so                     weld-spi.jar
derbynet.jar                                              jeus-console2.jar           libNSStream.so                     woodstox.jar
ecj.jar                                                   jeus-console-executor.jar   libRunner.so                       wsit.jar
eclipselink.jar                                           jeus-eclipselink.jar        libsigar-amd64-linux.so            xalan.jar
el-impl.jar                                               jeus-gms.jar                libsigar-universal64-macosx.dylib  xercesImpl.jar
extension.jar                                             jeus-hotswap.jar            libWebtoBAdmin.so                  xml-apis.jar
FastInfoset.jar                                           jeus.jar                    mail.jar                           xml_resource.jar
hibernate-validator-5.0.1.Final.jar                       jeusjaxb.jar                message-bridge.jar                 xmlsec.jar
hibernate-validator-annotation-processor-5.0.1.Final.jar  jeus-launcher.jar           mimepull.jar                       xsltc.jar
hibernate-validator-cdi-5.0.1.Final.jar                   jeus-network.jar            Module-Version-Info.txt
We see the usual suspects here, like Hibernate Validator as implementation for Bean Validation, the IBM JBatch implementation (it's Java EE 7, remember ;)), EclipseLink for JPA, Weld for CDI etc. Here we see again a Mac OS X artifact libsigar-universal64-macosx.dylib. It might be that TMaxSoft is working on OS X support, but just hasn't finished it (this is a developer preview after all).

Some additional "system" dependencies are in lib/shared:

jax-rs-ri-2.0  jsf-injection-provider.jar  jsf_ri_1.2  jsf_ri_2.2  jsf-weld-integration.jar  jstl_1.2  libraries.xml
The directories contain jars like jax-rs-ri-2.0.jar (Jersey), jsf-ri.jar (Mojarra) and jstl-impl.jar. (I wonder though why these aren't also in the lib/system directory with the other Java EE dependencies.) While JEUS is definitely not GlassFish it's clear that it uses the exact same set of dependencies.

The readme.txt is luckily in English and explains how to start the server. I used the following command from the JEUS installation directory:

./bin/startDomainAdminServer -domain jeus_domain -u administrator -p admin007
And lo it behold, it started at the first attempt:
***************************************************************
  - JEUS Home         : /home/arjan/jeus8                           
  - Java Vendor       : Sun                         
  - Added Java Option :                            
***************************************************************
+ /opt/jdk/bin/java -server -Xmx512m -Xbootclasspath/p:/home/arjan/jeus8/lib/system/extension.jar -classpath /home/arjan/jeus8/lib/system/jeus-launcher.jar:/home/arjan/jeus8/lib/system/xalan.jar:/home/arjan/jeus8/lib/system/xsltc.jar:/home/arjan/jeus8/lib/system/jaxb-impl.jar:/home/arjan/jeus8/lib/system/woodstox.jar:/home/arjan/jeus8/lib/system/xml_resource.jar:/home/arjan/jeus8/lib/system/commons-cli.jar:/home/arjan/jeus8/lib/system/jaxb2-basics-runtime.jar:/home/arjan/jeus8/lib/system/javaee.jar:/home/arjan/jeus8/lib/system/tmaxjce_jdk15x.jar -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.library.path=/home/arjan/jeus8/lib/system -Djava.endorsed.dirs=/home/arjan/jeus8/lib/endorsed -Djava.naming.factory.initial=jeus.jndi.JNSContextFactory -Djava.naming.factory.url.pkgs=jeus.jndi.jns.url -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=jeus.util.logging.JeusLogManager -Djava.util.logging.config.file=/home/arjan/jeus8/bin/logging.properties -Djeus.home=/home/arjan/jeus8 -Djeus.jvm.version=hotspot -Djeus.tm.checkReg=true -Djeus.properties.replicate=jeus,sun.rmi,java.util,java.net jeus.launcher.Launcher -domain jeus_domain -u administrator -p admin007

================ JEUS LICENSE INFORMATION ================
=== VERSION : JEUS 8.0 (Fix#0) (8.0.0.0-b1)
=== EDITION: Enterprise (Trial License)
=== NOTICE: This license restricts the number of allowed clients.
=== Max. Number of Clients: 5
==========================================================
[2013.09.24 22:48:11][2] [launcher-1] [Launcher-0012] Starting the server [adminServer] with the command
 /opt/jdk1.7.0_40/jre/bin/java -DadminServer -Xmx1024m -XX:MaxPermSize=128m -server -Xbootclasspath/p:/home/arjan/jeus8/lib/system/extension.jar -classpath /home/arjan/jeus8/lib/system/bootstrap.jar -Djava.security.policy=/home/arjan/jeus8/domains/jeus_domain/config/security/policy -Djava.library.path=/home/arjan/jeus8/lib/system -Djava.endorsed.dirs=/home/arjan/jeus8/lib/endorsed -Djeus.properties.replicate=jeus,sun.rmi,java.util,java.net -Djeus.jvm.version=hotspot -Djava.util.logging.config.file=/home/arjan/jeus8/bin/logging.properties -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.util.logging.manager=jeus.util.logging.JeusLogManager -Djeus.home=/home/arjan/jeus8 -Djava.net.preferIPv4Stack=true -Djeus.tm.checkReg=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Djeus.domain.name=jeus_domain -Djava.naming.factory.initial=jeus.jndi.JNSContextFactory -Djava.naming.factory.url.pkgs=jeus.jndi.jns.url -Djeus.server.protectmode=false -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=/home/arjan/jeus8/domains/jeus_domain/servers/adminServer/logs/jvm.log jeus.server.admin.DomainAdminServerBootstrapper -domain jeus_domain -u administrator -server adminServer .
[2013.09.24 22:48:11][2] [launcher-1] [Launcher-0014] The server[adminServer] is being started ...
[2013.09.24 22:48:17][2] [adminServer-1] [SERVER-0248] The JEUS server is STARTING.
[2013.09.24 22:48:17][0] [adminServer-1] [SERVER-0000] Version information - JEUS 8.0 (Fix#0) (8.0.0.0-b1).
[2013.09.24 22:48:17][0] [adminServer-1] [SERVER-0001] java.specification.version=[1.7], java.runtime.version=[1.7.0_40-b43], vendor=[Oracle Corporation]
[2013.09.24 22:48:17][2] [adminServer-1] [SERVER-0002] Domain=[jeus_domain], Server=[adminServer], baseport=[9736], pid=[7151]
[2013.09.24 22:48:17][2] [adminServer-1] [SERVER-0004] The current system time zone : sun.util.calendar.ZoneInfo[id="Europe/Amsterdam",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=180,lastRule=java.util.SimpleTimeZone[id=Europe/Amsterdam,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
[2013.09.24 22:48:17][2] [adminServer-1] [SERVER-0571] All JEUS system properties have been confirmed.
[2013.09.24 22:48:17][2] [adminServer-1] [SERVER-0568] [Network] service ip:port = [0.0.0.0 : 9736], representation ip = [0.0.0.0], hostname = [java.local], inetAddress = [java.local/0.0.0.0]
[2013.09.24 22:48:17][2] [adminServer-1] [SERVER-0561] The default RMI export port = 9743.
[2013.09.24 22:48:17][2] [adminServer-1] [UNIFY-0102] There's no selectors count setting for Non-blocking listener 'BASE', applying available processors count 1 instead of it.
[2013.09.24 22:48:17][2] [adminServer-1] [NET-0002] Beginning to listen to NonBlockingChannelAcceptor: /0.0.0.0:9736.
[2013.09.24 22:48:17][2] [adminServer-1] [UNIFY-0102] There's no selectors count setting for Non-blocking listener 'http-server', applying available processors count 1 instead of it.
[2013.09.24 22:48:17][2] [adminServer-1] [NET-0002] Beginning to listen to NonBlockingChannelAcceptor: /0.0.0.0:8808.
[2013.09.24 22:48:17][2] [adminServer-1] [UNIFY-0102] There's no selectors count setting for Non-blocking listener 'jms-internal', applying available processors count 1 instead of it.
[2013.09.24 22:48:17][2] [adminServer-1] [NET-0002] Beginning to listen to NonBlockingChannelAcceptor: /0.0.0.0:9941.
[2013.09.24 22:48:17][2] [adminServer-1] [GMS-0100] The GMS instance for the cluster group jeus_domain_1111111111 has been successfully initialized.
[2013.09.24 22:48:18][2] [adminServer-1] [JNSS-0009] The JNDI naming server has been successfully initialized.
[2013.09.24 22:48:18][2] [adminServer-1] [JNDI.Local-0001] Starting JNDI Local Client...
[2013.09.24 22:48:18][2] [adminServer-1] [JMXR-0138] JMXConnector service URL : service:jmx:jmxmp://0.0.0.0:9736/JeusMBeanServer
[2013.09.24 22:48:18][2] [adminServer-1] [JMXR-0138] JMXConnector service URL : service:jmx:jmxmp://0.0.0.0:9736/JEUSMP_adminServer
[2013.09.24 22:48:18][2] [adminServer-1] [JMX-0051] JMXConnector started with the JNDI name [mgmt/rmbs/adminServer].
[2013.09.24 22:48:18][2] [adminServer-1] [GMS-1000] The member adminServer has joined the cluster group jeus_domain_1111111111.
[2013.09.24 22:48:21][2] [adminServer-1] [CORBA-1002] ORB(SE-ORB) started.
[2013.09.24 22:48:22][2] [adminServer-1] [JMS-7374] The persistence store manager for the JMS broker 'adminServer' has been started.
[2013.09.24 22:48:22][2] [adminServer-1] [JMS-6822] The JMS engine with the broker named adminServer has started.
[2013.09.24 22:48:22][2] [adminServer-1] [WEB-1003] Socket send buffer size of this operating system = [8192]
[2013.09.24 22:48:24][2] [adminServer-1] [WEB-1030] The web engine has started successfully.
[2013.09.24 22:48:24][2] [adminServer-1] [Deploy-0095] Distributing the application[webadmin].
[2013.09.24 22:48:24][2] [adminServer-1] [WEB-3857] 
- session descriptor -
    - timeout           : 30(min)
    - shared            : false
    - reload-persistent : false
- session tracking mode -
    - Cookie     : true
    - URL Rewrite: false
    - SSL        : false

- session cookie config -
    - cookie-name : JSESSIONID
    - version         : 0
    - domain          : null
    - path            : null
    - max-age         : -1 (browser-lifetime)
    - secure          : false
    - http-only       : true

[2013.09.24 22:48:24][2] [adminServer-1] [WEB-1032] Distributed the web context [webadmin] information
- Virtual host    : DEFAULT_HOST
- Context path    : /webadmin
- Document base   : /home/arjan/jeus8/lib/systemapps/fakeWebadmin_war

[2013.09.24 22:48:25][2] [adminServer-1] [WEB-3480] The web module [webadmin] has been successfully distributed.
[2013.09.24 22:48:25][2] [adminServer-1] [Deploy-0096] Successfully distributed the appliacion[webadmin].
[2013.09.24 22:48:25][2] [adminServer-1] [WEB-3484] ServletContext[name=webadmin, path=/webadmin, ctime=Tue Sep 24 22:48:24 CEST 2013] started successfully.
[2013.09.24 22:48:25][2] [adminServer-1] [SERVER-0248] The JEUS server is STANDBY.
[2013.09.24 22:48:25][2] [adminServer-1] [SERVER-0248] The JEUS server is STARTING.
[2013.09.24 22:48:25][2] [adminServer-1] [WEB-3413] The web engine is ready to receive requests.
[2013.09.24 22:48:25][2] [adminServer-1] [SERVER-0602] Successfully sent the JoinedAndReady event. JEUS GMS=[Group=jeus_domain_1111111111,ServerToken=adminServer]
[2013.09.24 22:48:25][2] [adminServer-1] [UNIFY-0100] Listener information
                                    BASE (plain, 0.0.0.0 : 9736) - VIRTUAL - SecurityServer
                                                                           - FileTransfer
                                                                           - BootTimeFileTransfer
                                                                           - ClassFTP
                                                                           - JNDI
                                                                           - JMXConnectionServer/JeusMBeanServer
                                                                           - JMXConnectionServer/JEUSMP_adminServer
                                                                           - GMS-NetworkManager
                                                                           - TransactionManager
                                                                 - HTTP Listener
                             http-server (plain, 0.0.0.0 : 8808) - VIRTUAL
                                                                 - HTTP Listener
                            jms-internal (plain, 0.0.0.0 : 9941) - VIRTUAL - JMSServiceChannel-internal

[2013.09.24 22:48:25][0] [adminServer-1] [SERVER-0242] Successfully started the server.
[2013.09.24 22:48:25][2] [adminServer-1] [SERVER-0248] The JEUS server is RUNNING.
[2013.09.24 22:48:25][2] [adminServer-1] [SERVER-0401] The elapsed time to start: 13779ms.
[2013.09.24 22:48:25][2] [launcher-10] [Launcher-0034] The server[adminServer] initialization completed successfully[pid : 7151].
[2013.09.24 22:48:25][0] [launcher-1] [Launcher-0040] Successfully started the server. The server state is now RUNNING.
The server listens on port 8808 by default. While 8080 seems to be sort of the universal default, there are certainly more servers that deviate from this (e.g. WebLogic defaults to 7001). There doesn't seem be a web app configured on the root, as requesting localhost:8808 yields the following result:

You can enable a web console by adding <enable-webadmin>true</enable-webadmin> to [jeus install dir]/domains/jeus_domain/config/domain.xml as a child of the domain node, e.g. :



    false
    1111111111
    
    adminServer
    true

After this I should have been able to request http://localhost:9736/webadmin, but unfortunately this didn't work:

After some investigation it looks like this web app should have been in [jeus install dir]/jeus8/lib/systemapps/webadmin, but in my case this directory only contained a WEB-INF folder with empty lib and classes folders. When I created an a.jsp file with just the content "hello" in the [jeus install dir]/jeus8/lib/systemapps/webadmin folder and requested the URL again, I got a result :)

Most likely TMaxSoft is doing an overhaul of their web console and it's not added to this developer preview yet. I assume that on the current production version JEUS 7 this would just have worked.

Finally with the command ./stopServer -host localhost -u administrator -p admin007 JEUS can be stopped. Luckily, it indeed stopped correctly.

Conclusion

For a seasoned Java EE developer and library writer it's rather intriguing that there's a complete Java EE server out there that's virtually unknown outside Korea, or at the very least seems to be completely unknown in the West. JEUS may be a very capable server going from the impressive list of testimonials, but there are very high barriers for the casual Java EE developer to come into contact with JEUS.

The most direct issue is that people outside Korea just don't know about JEUS. It's as simple as that. News postings about JEUS being certified is probably the only thing people ever hear about it. JEUS should really have an Eclipse plug-in in the Eclipse marketplace or in the list of "download additional server adapters", if only to raise awareness that it exists. A few (English) blog posts now and then wouldn't hurt either (a very good example is how David Blevins is raising awareness of TomEE's existence).

For the curious developer who is interested in discovering what JEUS is, the current TmaxSoft websites are a VERY high barrier as well. The USA domain which is just gone, the mandatory login to see documentation or access the download page and above all the absence of links to the most recent versions of JEUS (JEUS 7) are HUGE barriers that will probably shoe away even the more enthusiastic developers.

But JEUS -always- winning the Java EE certification race and the fact that they have been working on their server since at least 2001 (the year JEUS 3 was released) must mean they're doing something right. In a next article I hope to actual run some code on JEUS. My main goal is run the OmniFaces showcase application (which intensively tests JSF, CDI and some BeanValidation), my JASPIC test suite (which obviously tests JASPIC) and our Java EE kickstart application (which tests JSF, EJB, JPA, and the default datasource among others).

Arjan Tijms



References: Further reading:

Sunday, August 11, 2013

Testing JASPIC implementations using Arquillian and full wars

In a previous article about JASPIC we saw that not all servers behaved the same. In fact there were rather large differences between implementations with respect to JASPIC.

From time to time new servers come out, e.g. since the last article JBoss has released JBoss EAP 6.1, Oracle has released GlassFish 4 and WebLogic 12.1.2 and even Geronimo has released a new version of its server; Geronimo 3.0.1.

I previously tested via a series of handcrafted web applications that I would deploy manually, do some tests with it and then observe its behavior. This initially worked fine, but it's a bit laborious and perhaps even brittle to retest again some time later. It also makes it harder for others to verify the tests. So automation was the key, but how to automatically deploy several wars to a variety of application servers?

There are a couple of options for starting & stopping a Java EE application server, plus deploying and undeploying an archive (web, ear, ...) to it:

  • JSR-88
  • Arquillian containers
  • Eclipse WTP server runtimes
  • Creating an ANT script or task for each server

JSR-88 is the universal Java EE API/SPI to do exactly this in a universal way. Every Java EE server should fully support it because it's in the spec. Except not every server does this. In fact, only 2 servers really seem to have implemented it: Geronimo and WebLogic. Because of this and even though the feature itself seems hugely useful, it has been removed from Java EE 7. A shame perhaps (especially since there's no immediately replacement as there was with JAX-RPC and Entity Beans), but not much to do about it now.

Arquillian containers seem be able to do the trick as well. They are available for a multitude of servers, but not all. Although many containers have been available for a few years now, they all have alpha or at most CR versions. Some of them can only deploy to a server but not start or stop it. There are some newer versions available on GitHub for some containers, but they seem to sit there for months on end or even years without being officially released. Since Arquillian is 99% build for Maven (theoretically it isn't, practically yes it is) not having those containers in Maven Central or another repository is a bit troublesome. Interesting though is that the newer JBoss servers contain Arquillian connectors natively.

Eclipse WTP server runtimes are available for pretty much every server imaginable and they don't have all those alpha version numbers that the Arquillian Containers have. They all have the logic embedded to start & stop a server and deploy & undeploy an archive. Unfortunately Eclipse WTP server runtimes are very strongly tied to UI actions. There doesn't even seem to be a way to programmatically control them from within Eclipse.

Creating an ANT script per server that simply scripts the shell commands that pretty much each server provides was the last option I considered. Initially I thought of it as crude workaround, but I remembered that the Mojarra test harness uses exactly this method. Unfortunately Mojarra only has a very few servers already covered (basically GlassFish and WebLogic, and some level of coverage for Tomcat).

To actually create several web applications (war archives) for testing I had a couple of options as well. Using Arquillian's ShrinkWrap to create those archives programmatically from within a single project would have been an option, but I wanted those web applications to still be actual separate applications that I could deploy manually and standalone as well. A multi-module Maven project seemed to be quite suited for this; you can build them all from a master pom.xml, but also build them separately. In Eclipse each module is recognized as a separate web application and can be deployed independently from the other modules.

The project layout in Eclipse looks as follows:

Except for "common" and the Maven build folder "target", all sub-directories represent web applications. If needed they can be deployed individually by WTP as the following image shows:

As I was using Maven now, Arquillian seemed to be a logical choice. One issue though is that Arquillian predominantly focusses on unit testing so-called micro archives, which are archives that are assembled at the start of a unit test. In this case I just wanted to deploy the full war and not fuss around with programmatically adding each file. Another issue was that Arquillian unit tests run during the test phase of Maven, which means the code is compiled but the war archive isn't created yet.

As it appeared Maven can also run tests after the artifact has been assembled. For this the plugin named maven-failsafe-plugin had to be used instead of the well known maven-surefire-plugin one, and test classes by convention have to end with "IT" instead of "Test". Arquillian luckily also provided a solution; it can create the war to be deployed from a zip file on the filesystem as well. In other words, if Arquillian runs via failsafe, it can import the war archive that Maven just created. This happens via code such as:

@Deployment(testable = false)
public static WebArchive createDeployment() {
    return ShrinkWrap.create(ZipImporter.class, "mywar.war")
                     .importFrom(new File("target/mywar-1.0.war"))
                     .as(WebArchive.class);
}

The following challenge was configuring the containers. The most important piece of configuration is the location of the actual application server. GlassFish embedded is an exception here; it's downloaded as a dependency of the Arquillian container (meaning it thus ends up in your local .m2 directory) and the full server runs within the same JVM as the test classes. It's completely zero-config. JBoss AS 7.2/EAP 6.1 can theoretically run embedded as well, but you still have to point the container to an already installed JBoss instance and unfortunately if you do that it still doesn't work.

Configuration is maybe not 100% intuitive. The issue is that an Arquillian container is not some kind of Maven plug-in orso, but it's just a dependency on the classpath following the highlander rule: There Can Be Only One. You can switch between them using Maven profiles. However, you can't directly configure a dependency in Maven; it's just a bunch of jars on the classpath after all. So you have to use a file called arquillian.xml that you also put on the classpath, somewhere... Then there's the issue that containers in arquillian.xml are given names via a qualifier attribute. Unfortunately a Maven profile for a given container doesn't automatically select the corresponding container in arquillian.xml; you have to make the connection yourself by setting an environment variable called arquillian.launch. Unfortunately again, a Maven profile cannot directly set an environment variable, but it can set a Maven variable. The failsafe plugin can set environment variables, so we can use it to do the conversion. This looks as follows:

First define a profile for a container in the parent pom.xml:


    arquillian-jbossas72-managed
   
    
        arquillian-jbossas72-managed
    

    
        
    

Second let the failsafe plugin convert the Maven property to a system/environment property:

    maven-failsafe-plugin
    
    
        
            ${arquillian.launch}
        
    

Finally define a container in arquillian.xml where its qualifier attribute corresponds to the value of the system property we just set ("arquillian-jbossas72-managed"):

    
        
        /opt/jboss72
    

Granted, it's a bit convoluted and more than a little verbose but it does do the trick. However, it's not perfect yet. arquillian.xml does not sit neatly near pom.xml, but has to be put into some source folder. Since the parent project doesn't have any source, it has to be put into some common sub-module that's included with all other sub-modules. For such an important configuration file this is less than ideal. Files like this should be directly in the root of the project or at most in a /config sub-directory of the root, and not buried away 10 directories deep.

After some fiddling it appeared the failsafe plug-in can load an external .properties file and luckily the newer versions of Arquillian can process placeholders in arquillian.xml. One particular Maven problem I encountered is that the combined parent/sub poms run in the context of the sub-module. So a reference in the parent pom to the project directory (${project.basedir}) will 'magically' point to the project directory of the sub-module when this sub-module is being build and tested. There's a trick to work around this.

In the parent project's pom.xml define a variable to point to parent's basedir as follows:


    ${project.basedir}

And in the pom.xml of every sub-module define the following:

    ${project.basedir}/..

Now we can put a .properties file next to the pom.xml, e.g. a containers.properties:
# JBoss AS 7.2 and JBoss EAP 6.1
JBOSS72_HOME = /opt/jboss-eap-6.1

#GlassFish 4.0
GLASSFISH4_HOME = /opt/glassfish4

# ...
We then let the failsafe plugin load this .properties file:

    maven-failsafe-plugin
    
    
        ${main.basedir}/containers.properties
        
    

And finally we put placeholders in the arquillian.xml file shown before:

    
        ${JBOSS72_HOME}
    

Again it's a bit more verbose as it could have been but also once again it does do the trick.

To actually execute tests against a deployed web application there's a variety of choices as well. There's HttpUnit, Selenium and Arquillian Drone. HttpUnit allows you to do requests to a URL and then programmatically inspect the results. It's kind of an embedded virtual browser. Selenium is basically a layer on top of HttpUnit with extra options for using real browsers like Firefox and Chrome. Arquillian Drone is again a layer on top of Selenium, but with the extra option to inject the base URL of the deployed archive into the test class. Maybe there are more differences, but it didn't looked into them. I picked Arquillian Drone here since I was already using Arquillian and the injected URL was really convenient (saving us the trouble of configuring for each server on which HTTP port it listens by default).

Some words about the actual application servers and how they performed with Arquillian; as already mentioned GlassFish 3 embedded was the easiest. Nothing to install and zero-config. GlassFish 4 embedded unfortunately failed when running JSP pages, but the managed variant was easy to setup. GlassFish 4 is download & unzip, then point Arquillian to the unzip location. JBoss is a tiny bit more troublesome. JBoss AS 7.2 couldn't be downloaded (you can build it yourself if needed) and JBoss EAP 6.1 requires you to create an account and accept a restrictive license. Otherwise it too is download & unzip, then point Arquillian to the unzip location.

WebLogic 12.1.2 was a bit more trouble. It too required the creation of an account to download, but the unzip version required a little more effort than just an unzip. You have to set a bunch of environment variables, run configure and setup scripts, then create domains and set username and passwords before you can do the simplest thing like deploying a simple .war. Luckily Arun Gupta got it all covered, but it's a mystery to me why the WebLogic guys can't default all of this stuff. GlassFish and Liberty also have a concept of domains resp. servers, but they both DO default it. Worse, when you create this "domain" thing, apparently WebLogic hardcodes the JAVA_HOME that happened to be set when this domain was created. When you subsequently start up WebLogic using Eclipse and have a completely different JDK set for WebLogic, it keeps running on the other JDK. Took me some time to figure this out and its quite unintuitive.

The WebLogic Arquillian container was problematic too. It's a so-called "remote container" which means it can only do deploy & undeploy, but not start & stop. This has to be done manually. The behavior of either the Arquillian container or WebLogic (or the combination of those two) was erratic too. A bunch of deploys would succeed and then suddenly they would start failing. Finally, the configuration of the Arquillian Container was more involved too. Where the other containers just needed the path where the server was installed, the Arquillian WebLogic container needs no less than 6(!) properties, ranging from a URL, to a path, another path, a server (besides "domains", WebLogic also has "servers"), etc.

So what about the results of the actual JASPIC testing? I haven't added all tests yet, so I'll leave that for a next article. The intermediate results though are that GlassFish 4 passes all tests, WebLogic doesn't pass all tests, and JBoss EAP still has a lot of problems but does pass a few more tests without needing patches. I created a new path for JBoss EAP that makes it pass even more tests.

The tests themselves can be found at Gitbub.

Arjan Tijms

Saturday, July 13, 2013

Java EE 8 wish list

Java EE 7 has been recently released and is a truly great release. While for most vendors the job to implement Java EE 7 has just started or may even still has to start ideas for the next version, Java EE 8, may already be shaping.

If history is anything to go by; last time Java EE 6 was released Dec 10, 2009 and we saw the first real Java EE 7 events about a year later, so we may have some time till Java EE 8 is really kicking off. Around the Java EE 7 kickoff time, Antonio Goncalves, presented a very interesting wish list of things that should be in Java EE 7. Interestingly 2 of his 4 items (flows and batch) indeed made it in Java EE 7, while a 3rd item (caching) would have been included but was dropped at the very last moment.

It's a bit early days, but in this article I'd like to present my wish list for Java EE 8:

  • CDI everywhere
  • More thorough Pruning & Deprecating
  • A standardized caching API
  • In-app alternatives for all "administrative objects"
  • General modernized security framework
  • Platform wide configuration

These items are discussed in more detail below.

CDI everywhere


This really means two separate things: making CDI available from places where it isn't available now, and implementing or retrofitting technology from other specs on top of CDI.

Make CDI available at more places


In Java EE 7 CDI was made available in a lot more places than before in Java EE 6. For instance CDI injection now works in most JSF artifacts and in e.g. the constraint validator from bean validation. Unfortunately, it thus only works in *most* JSF artifacts, not all. Missing are the converters and validators (OmniFaces 1.6 will add support for this, but it should really work out of the box).

JASPIC artifacts are not CDI aware either; injection doesn't work in them and even though the http request and session are available in a Servlet Profile SAM, the corresponding CDI scopes haven't been set up when a SAM is called. This means it's not even possible to retrieve request or session scoped beans programmatically using the bean manager.

A special case is that an assortment of platform artifacts have to be injected with alternative annotations (like @PersistenceUnit) and that the older general injection annotation (@Resource) is still required for many things such as a DataSource. Striking is that even artifacts introduced in Java EE 7, like the managed executor service, have to be injected with the ancient @Resource instead of @Inject.

Other specs building on top of CDI


CDI should definitely not try to absorb in its spec everything that other specs already address, but of course those other specs can implement their functionality on top of CDI, which typically means as a CDI extension. In Java EE 7 JSF 2.2 for instance provides a CDI compatible view scope as a CDI extension and its new flow scope was implemented right away as a CDI extension (there is no "native" variant anymore, a strong signal that JSF is likely to deprecate its own native managed bean facility).

Furthermore JTA 1.2 now provides a CDI extension via which transactions can be declaratively applied to CDI managed beans. Previously similar functionality was provided by EJB, which also used JTA behind the scenes but kept the declarative part inside the EJB specification. In this case however JTA directly implements the declarative transaction handling itself, but uses CDI to base this implementation on.

Although EJB beans since EJB 3 are very simple to use and at the same time very powerful, they have one big problem: it's simply a different component model than the one offered by CDI. No matter how useful the various EJB bean types are, having two component models within a single platform is very confusing for users and probably implementors as well. With the CDI component model you mix and match capabilities ala carte, with each annotation giving you extra capabilities. EJB is more of a "one off" model where a single annotation defines a specific bean type that gives you a lot of capabilities that typically work well together. You can partially disable the capabilities that you don't want. E.g. all bean types give you transactional support, but this can be turned off. For @Stateful beans passivation can be disabled, for @Singleton beans container managed locks can be disabled, etc.

Ultimately it would probably be better if EJB were to be retrofitted as a set of CDI extensions. There would only be one component model then but with effectively the same functionaly.

This means that EJB services like the timer service (@Schedule, @TimeOut), @Asynchronous, @Lock, @Startup/@DependsOn and @RolesAllowed should all be made to work with CDI managed beans. Furthermore the implicit features offered by the existing EJB bean types should then be broken down into individually applicable capabilities. Examples would be an @Pooled to mimic the container pooling offered by @Stateless beans and something like an @CallScoped to mimic the effect that every call to an @Stateless bean goes to a (potentially) different instance.

Of course very few people would like to annotate each class with @Pooled @CallScoped @Transactional @..., but this can be prevented by creating a couple of CDI stereotypes. It's a question though whether these should be given the same name as the existing EJB "bean defining" annotations but in a different package, or whether they should be given totally different names. The same names would make migration more straightforward, but some new users will undoubtedly choose the wrong variant at times (as can be seen today with the JSF @RequestScoped annotation vs the CDI one with the same name).

More thorough Pruning & Deprecating


Pruning is a process that was introduced in Java EE 6 and describes how deprecated functionality can be removed from the platform. In Java EE 7 a variety of technologies was pruned (made optional), meaning vendors can still include it if they want but they don't have to.

There is however more to prune. My personal favorite would be the JSF native managed bean facility (which ties in nicely with the "CDI everywhere" theme), the JSP view handler (which was effectively deprecated back in 2009) and an assortment of functionality in JSF that has been described as being deprecated in the spec document for quite some time.

It would maybe be nice if the EJB component model would be pruned as well (in favor of the CDI based version), but most likely this is much too early. A safer bet would be to first continue pruning everything related to the EJB 2 programming model, like the home interfaces that still linger around in Java EE 7.

A standardized caching API


This item can be kept short; a standardized caching API called JCache was set to be included into Java EE 7, but unfortunately it missed a few important deadlines. Hopefully it will make it into Java EE 8. If this spec finishes early in the Java EE 8 timeframe then it would be great if some of the other specs (like JPA) could rebase their own caching API on top of JCache.

In-app alternatives for all "administrative objects"


Java EE has a concept called an "administrative object". This is a resource that is configured on the AS side as opposed to from within the application itself. The concept is sometimes controversial. For application servers that run many external applications inside big enterprises, it can be a big advantage to have them. You typically don't want to open an externally obtained application to change the details of which database it connects to. If there's a strong separation between developers and operations in a traditional enterprise it can be benificial as well to have this separation reflected in the system setup.

However, for agile teams that deploy a single in-house developed application to its own application server (which is thus not shared by other applications) this separation is a big hurdle that only gets in the way and doesn't help at all.

Likewise for beginners, educational usage and even cloud deployments, this setup is highly undesirable as well. For beginners and educational usage specifically it means one part of the explanation of setting something up can be in general Java EE terms, and then another part has to say something like "see your own server for details on how to do ...". This is rather confusing to say the least.

Starting with the @DataSourceDefinition in Java EE 6 many resources that were previously "administrated objects" only can now be defined from within the application. These include JMS destinations, email sessions, and more.

Unfortunately this is still not true for all administrated objects. Striking is that the brand new Concurrency Utils for Java EE spec has explicitly opted to make its resources administrative objects only. It would be great if these could be configured in a portable way from within the application as well in Java EE 8. Even better would be if the platform would define a kind of guideline that strongly discourages resources to be administrative only. If a spec thinks a developer of whatever type can not be trusted with some resource type, and it should thus be administrative only, then the spec should be required to have a very good reason for this. "xyz does not belong with developers, period!" is of course not a valid reason.

General modernized security framework


Security has always been a thorny issue in Java EE. The lack of an overall and comprehensive security framework is not rarely mentioned as one of the main disadvantages of Java EE, especially in discussions or evaluations of Java EE against competing frameworks such as Spring.

It's not that Java EE doesn't have any provisions for security at all. In fact, it has a whole slew of them. There's JAAS, there's JASPIC, there's JACC, portions of the Servlet spec deal with security, portions of the EJB spec do as well, JAX-RS has its own API and if I'm not mistaken even JCA has some of its own security provisions.

There are however several problems with all of this. The first is simply that security is spread over so many specs, and that not all of those specs are available in the important Java EE Web Profile. This makes it hard to reason about -the- Java EE security framework, since there just isn't a single one.

This results in a number of practical problems. For instance, the recently introduced '*' role had to be specified and implemented individually in the Servlet, EJB and JACC specs. Checking if a user has a specific role is done inside a Servlet via HttpSerletRequest#isUserInRole, but inside an EJB it has to be done via EJBContext#isCallerInRole. Inside JAX-RS resources it's SecurityContext#isUserInRole, and how it has to be done from within a CDI bean is anyone's guess (in practice; via obtaining an HttpServletRequest in some way). It would probably be much clearer if there was something like a single SecurityContext that could be used by artifacts from all other specs instead of each spec having its own way to do the exact same thing.

Another example is asking the container for all roles that a given user has. This is supposedly possible via JACC, so other specs aren't eager to implement this (perhaps for the better to prevent more duplication). Unfortunately JACC is not available everywhere, so in practice this is not an optimal solution. Worse, the JACC code to do this is not really terse to say the least. I wonder how many people, even the more advanced Java EE developers, would be able to come up with such code themselves.

This brings us to the second main issue; the various security APIs haven't been modernized for quite some time. This holds especially for JASPIC and JACC. There have been various maintaince updates which fixed small but important issues, but never a full modernization like was done recently for JMS 2. JASPIC for example still targets Java SE 1.4 and as mentioned above has no knowledge whatsoever of things like CDI.

A third issue is that the individual security APIs JAAS, JASPIC and JACC are all rather abstract and low-level. This gives them great flexibility for vendors, but makes them not optimally suited to be used by regular application developers (who weren't already super thrilled to use them because of the non-modernized API). JAAS is especially troublesome here as its more aimed at providing priviledges to specific code bases for doing low-level operations (like reading a file, opening a URL, etc). This doesn't match well to Java EE, where it's extremely rare to run untrusted code and the emphasis is more on allowing resource access to (logged-in) users on a much higher level.

A fourth and very major issue is that security in Java EE has suffered from the same problem as the "administrative objects"; for a long time the so called declarative security model of Java EE assumed that the actual "how" of mainly the authentication process was solely configured and implemented in a vendor specific way at the AS side. This again made setting up security unnecessary hard for agile teams, beginners and educators. Indicative for this issue is that some of the great books about the Java EE platform as a whole, like Arun Gupta's Java EE 6 Pocket Guide and Antonio Goncalves' Beginning Java EE 7 do not address security at all! There is just hardly any "Java EE way" to do these tasks, but only a "JBoss way", a "GlassFish way" and a "Vendor XYZ way".

Specifically problematic is that many servers require a process often called "group to role mapping". This process is not always needed but mandated anyway, plus it's server specific meaning a user has to relearn it for every Java EE server he or she has to work with. This Java EE approach of having a "security view" of an application, which declares roles, and a deployer who maps and configures security at the application server is an approach that maybe nicely scales up to large enterprises, but doesn't scale down well to the level of an individual developer who is just trying out Java EE or even to small and agile devops teams who only deploy a single application to a single application server. It's again also not always ideal for cloud deployments.

In the perception of a user, the actual authentication modules are thus a bit of a black box. They are specific for a server, which hurts portability and requires a user to learn how they work for every other Java EE implementation. This hurts the perception of the Java EE security system being an integrated thing (different vendors have their own API styles, there own documentation, their own way of doing things, etc). JASPIC theoretically solves this problem, but not yet in practice.

As a consequence of the fourth issue, most vendors have elaborate but proprietary security frameworks in place and their own interfaces for external authentication modules. Perhaps because of this existing investment, vendors have been slow to pickup JASPIC. As JASPIC is mandatory for compliance with the full Java EE 6 profile vendors have implemented it, but some implementations that were actually certified were a bit incomplete and diverged at quite a number of points from the JASPIC spec. It's hard to imagine those vendors having really put a lot of effort into JASPIC at that point. Lately the situation has started to improve, but even after more than 3 long years none of the available JASPIC implementations do everything that the spec requires them to do. This thus means not only the spec and APIs need to improve, but most likely the TCK needs a big update as well. We'll have to see if this didn't already happen for Java EE 7, as currently only GlassFish 4 has been certified for Java EE 7 and GlassFish has a reasonably compliant JASPIC implementation (but it too is not 100% compliant, e.g. request wrapping doesn't work from a SAM).

All together these are quite some issues. Partially they could be addressed by how things have been going for the last few releases: gradually add small features and fix or clarify small issues. My wish for Java EE 8 is however that the issues will be addresses more thoroughly by a single overarching and modern security framework (building as much as possible on the existing security foundation).

Platform wide configuration


Java EE applications can be configured using deployment descriptors (such as web.xml), but it's painful to change these settings easily for various stages (such as DEV, BETA, LIVE, etc). The traditional way to configure a Java EE application for such stages is via the above mentioned "administrative objects" that reside at a specific server instance. Following this method, it are the servers that are configured instead of the application. Since the server corresponds to a stage, the setting automatically change between stages.

There are a number of issues with this approach though. First of all by its very nature configuring resources at the AS side is server specific. Looking up those resources may be standardized, but configuring them sure is not. This again makes things difficult for beginners, makes things difficult to explain and makes it difficult to publish (explanatory) ready-to-run applications. It also makes things unnecessarily difficult for small and agile devops teams, who now have to separate the configuration from the application for no good reason. For developers this situation is difficult too; with the JNDI approach it's necessary to have multiple duplicate instances of the AS used for developing each with their own configuration. This works, but is not exactly lightweight. Furthermore, when new or updated configuration is made available this typically has to be applied manually; someone sends an email around with instructions and then developers often have to apply these instructions to all their AS instances by interacting with a web console or CLI. This is MUCH more involved and error prone than just pulling in a new revision from e.g. Git.

Even if JNDI based configuration is used, there's the issue that not everything can be configured via JNDI. Setting e.g. the JSF staging mode or the Facelets refresh time are web.xml settings and not JNDI resources. Adding an extra debug Filter into the Servlet filter chain is not something that can be easily done via JNDI either. There are crude workarounds, but none of them are really optimal.

There are various possible alternative ways to configure a Java EE application, such as using (expression language based) placeholders in the deployment descriptors and making deployment descriptors themselves (or fragments) switchable. A number of specifications already allow for additional deployments descriptors to be specified (e.g. web.xml can specify additional faces-config.xml files and persistence.xml can specify additional orm.xml files), but there's no unified mechanism to do this for all available descriptors and no way to parameterize which extra files are to be included or excluded.

It would be great if Java EE 8 addresses these configuration issues in a thorough and platform unified way. It seems that something like this is indeed being planned. It will be interesting to see how this will develop.

Conclusion


As mentioned at the beginning of this article, it's still early days for Java EE 8 planning and anything can still happen. Hopefully some (or most ;)) of the points on the above presented wish list will be addressed in some way. I think "CDI everywhere" in particular stands a good chance as there seems to be much support for that and things are already moving in that direction. The big question is to what extend Java EE 8 can address that particular issue. The standardized caching API probably stands a very good chance as well, it was almost included in Java EE 7 and is still making good progress. Strange things would have to happen if with the current scope it again wouldn't be ready for Java EE 8. However, with the enormous amount of extra time available for JCache may come the risk (and even the expectation) to expand the scope and if the functionality associated with that expanded scope isn't ready on time, could it miss the deadlines again? Hopefully not! The portable in-app mechanism (read annotations) to declare resources fits in very well with the cloud theme and I guess has a reasonable chance as well.

The one I'm least sure about is the general modernized security framework. This has indeed been mentioned now and then by several EG members, but as far as I know nothing for this has been started yet. It'll most likely require a rather big effort needing support from quite a number of other specs, making this an overall difficult issue. Incidentally, security was the 4th item that Antonio Goncalves put on his wish list for Java EE 7 and the only one that didn't got addressed. Let's hope Java EE 8 will finally pick this one up!

Arjan Tijms


Further reading: