Extreme Java When vanilla Java is not enough


Using JBoss as a remote datasource provider

After some trial-and-error, I managed to use a JBoss 5 as a JNDI server and a Tomcat as a JNDI client. If you plan to make a JBoss DataSource public, just add a "<use-java-context>false</use-java-context>" to your "<local-tx-datasource>".

Tomcat is easy to configure. You need to add a resource like this one ("look mom! no password!"):

<Resource name="jdbc/myds"
    URL="jnp://jboss-host:1099/jdbc/mydsOnJboss" />

The "jdbc/mydsOnJBoss" part is the same as the "<jndi-name>" on JBoss datasource. The real trick is the classpath. Go to JBOSS_HOME/client and copy these files:

  • jboss-logging-jdk (or jboss-logging-log4j)
  • jboss-logging-spi
  • jnp-client
  • jboss-client
  • jboss-common-core
  • jboss-integration
  • jboss-remoting
  • jboss-security-spi
  • jboss-serialization
  • jbosscx-client
  • jboss-javaee (optional if your Tomcat has the javax.transation.* already)

The first three (jnp-client, jboss-logging-*) are obvious, since they are explicit dependencies (i.e. you receive a "ClassNotFoundException"). The others are implicit - you don't receive a CNFE, you get a "ClassCastException" (cannot cast javax.naming.Reference to javax.sql.Datasource). It is evil - no docs, no log, only "-verbose:class" helped me.

With the right libs and the right configuration, you can use @Resource (or Spring's JNDI lookup) the same way as a locally defined datasource - without any sensitive information exposed.

As a final note, you don't need the JDBC driver on client.


JBossAS + JBossWS + JDK 6 = problems

Years ago, a lot of applications did not support JDK 5, even with the incredible range of new features. Today, the history repeats itself with JDK 6. A lot of applications do not support it. For my surprise, I added a big one to the list: JBoss.

How did I found it? By publishing a webservice using JBossWS (included in JBossAS). Deployment works, but when I consume the WS, I got this exception:

java.lang.UnsupportedOperationException: setProperty must be overridden by
all subclasses of SOAPMessage

After researching it on Google, I found this bug report. They tell JBoss is not supported on JDK 6, but, since I follow the "upgrade-or-bust" philosofy, I decided to put it to work.

It was pretty simple (on JBoss 4.2.2GA): grab a copy of "jboss-saaj.jar" from "server/default/lib" and copy it to "JBOSS_HOME/lib/endorsed". Works like a charm!


The quest for the Java Portal – Profiling Liferay

It's time to run the Profiler. I start JBoss with "run-nbprofiler.bat" (created by NetBeans) and ask NB to attach profiler. I'm using "analyze performance", filtering Java core classes. JBoss runs very slow, but this is normal, since profiler is collecting execution of every method.

My first try showed that Lucene is called a lot of times, even when server is on "idle" state. Maybe it is a background job that should have a smaller frequency.

The second try filters out Lucene classes (using NB Profiler options). I found two bootlenecks: com.liferay.portal.lucene.IndexWriterFactory.decrement (takes 58% of startup time) and JBoss classloaders. And I found that Liferay auto deploy is running too often (~5 seconds of delay). Nice for develoment, awful for production use.

I had to remove JBoss classes from profiling, and I got amazed on things I discovered. I got a OutOfMemoryError (perm gen space) - solved by adding "-XX:MaxPermSize=256m" to run script - but I could find a lot of interesting things:

  1. getResourceAsStream was called 12068 times;
  2. Xerces' ChildNode was instantiated 853808 times (does anybody imagine why Java is "slow"?);
  3. Stacktrace got really deep. About 50 levels or more, not including JBoss, Lucene and JDK classes;
  4. A chain of 7 filters was called before hitting Liferay's MainServlet. If you consider a little forward made after MainServlet, we reach 14 filters before hitting a JSP file;
  5. JSP compilation took 19s on this environment - total execution was 180s;
  6. LR's VelocityTaglib has 8 iconXXX() methods that took 8 seconds each - detail: each one forwards another request;
  7. Everytime a "include" is made, the chain of 7 filter is called. And there's a LOT of includes.

Remember that this was only ONE hit and the request wasn't complete, because of the OOM error. After that, I'm going to have some fun in the "real world". I'll try to go deeper tomorrow. Maybe I can send a RFE to Liferay team after I organize the arguments.


The quest for the Java Portal – Running Liferay

Now, I have a profiled environment. But, when I tried to run JBoss (without profiling), I got an error in counter-ejb module. Its classpath is not correctand, so, I added this line to my build.[user|computer].properties:

classpath.manifest=[original line in build.properties]

I reported this bug on Liferay JIRA [#LEP-2406]. After another 16 minutes of compilation, I forgot to initialize the database. I had two options: use a diferent connection pool or initialize it before deploying Liferay. I prefer the second, so, the easiest way was to create a MBean that depends on LiferayPool. Hypersonic is smart enough to allow multiple SQL commands in one Statement. I will upload the code later, but it is a matter of create a MBean that reads the script provided by Liferay and runs it on the poll.

This leads to an strange error about Spring transactions with EJB, Hibernate, JBoss and all. I don't remember the details, but the solution is to change the debug attribute of CachedConnectionManager. This is something I can't do in my shared JBoss server, so, I used an dirty trick:

  1. Start JBoss with no Liferay, but with the original data source (liferay-db.xml configured);
  2. JBoss translates your -ds file into and -service file and logs it with debug level;
  3. Grab the translated file in log, create the -service, delete the -ds and indent the file - this will help you understand its structure;
  4. Now, the funny part: copy CacheConnectionManager definition from jboss-jca.xml, paste into liferay-service.xml (inside the "CachedConnectionManager" optional attribute), and rename the MBean to an unique name - I put a ",name=xxx" suffix.

This will create a custom CCM to Liferay, without violating the original instance. That's what I love in Java (specially in JBoss): you can create a Lego-like software that is just a matter of do the bindings.

Liferay runs fine, but I found two bugs: a ClassNotFoundException about ical4j, and the contents of Guest community are blank. The first, I solve by adding lib/ical4j.jar to manifest classpath (as above). The second I don't care, since I will clean everything when I deploy the real application.


The quest for the Java Portal – Compiling Liferay

I got some weird exceptions with JBoss Portal, so, I decided to play around with Liferay. I have it running on my shared JBoss, and I have some ideas to their structured articles feature, so I will try harder on Liferay.

I've decided to check the bootlenecks on Liferay, because it is too slow. I'll use NetBeans Profiler. Using NB's ability to create projects using existing Ant scripts, I've done some setup:

  1. Create an Java Application project using an already existing Ant script;
  2. Add all "src" folder to the source folders list - about 20 of them (I guess this isn't necessary unless we want to change anything);
  3. Adjust compilation build to the "start" target and run to "deploy" (Liferay does not set "start" as dependency to "deploy");
  4. Create a "build.[user|computer].properties" and "app.server.[user|computer].properties" to customize some build parameters. I dislike Jikes, so, I'm using "javac.compiler=modern". The rest of properties are straighforward to customize, but folders on app.server must be correctly configured - JBoss predefined values does not work on an out-of-box installation;
  5. After building a lot of modules (about 10 minutes on an almost empty Windows box powered by an Athlon XP 3200+), more than 2000 classes - yes, two thousands - are compiled without errors. Running the "deploy" target will install Liferay on JBoss. It installs some JARs on server's lib folder - I will change this later, before uploading to the real server.

Now, you can run JBoss. But first, some one-time configuration:

  1. Add a datasource. To use profiling, I created a memory-only HSQLDB:
    <?xml version="1.0" encoding="UTF-8"?>
  2. Use NetBeans Profiler (Profile | Attach Profiler) to prepare a special run script to active profiling on JBoss - this file will be called "run-nbprofiler".

Now, we have an working environment. Next step is test and profile.


The quest for the Java Portal – Testimonial

I was supposed to be an user of Java Portals, not a developer. Things like JBoss management portlet are annoying, but it is just a matter of user experience. At least JBoss Portal deploys with minimal changes. Actually, I only need to change deployment descriptors.

Portals like Gridsphere, Jetspeed and others are unusable to normal users, since they need to know Java very well. How can I replace Zope/Plone in my job if every environment admin will need to know how to use Maven/Ant/etc?

Is that hard to develop an JavaEE application that makes users' life easier?

If I need to do any developer task, I prefer to develop my own portal that conforms to JSR-168 without violating JavaEE specifications.

BTW, I'm talking as a Java Portal user (i.e. portal deployer/admin). I'm not talking as the user of the portal I will create with a Java Portal (i.e. my "costumers").

End note: I'll try JBoss Portal beta-1, since it was released this week, but I won't use it if I still needs that buggy management layout.

Tagged as: , No Comments

The quest for the Java Portal – JBoss Portal 2.6 live

No changes in JBoss Portal 20070307 nightly build. I saw JBoss ajax4jsf and JBoss Rich Faces and could not imagine why these incredibly cool components aren't used by JBoss Portal.

Tagged as: , 2 Comments

The quest for the Java Portal – JBoss Portal 2.6

JBoss Portal version 2.6 is still alpha, but I tryed it (since it claims to have a better user experience). I've downloaded its binary version - a JBoss' SAR archive. Out-of-box installation was a matter of copy datasource definition and the SAR file to my deploy folder.

It has the same limitations as 2.4:

  • Delete the management portlet and your layout is locked;
  • You can delete ALL users and have a nice NPE;
  • The layout arrangement is not inline (needs the management portlet).

But, as I expected, it is pretty light. Unlink Liferay, the startup was really quick. If it was more AJAX-aware, JBoss Portal could be my portal of choice. Well, according to Grog, beta 1 will be released soon. I'm downloading a nightly build and I'll try it again.

Tagged as: , 1 Comment

The quest for the Java Portal – JBoss Portal

Today mission: JBoss Portal. My first impression: negative. I've tryed its live demo and, after two minutes, I render it useless. How? Follow the steps:

  1. Login as admin/admin
  2. Go to the admin page
  3. Remove the administration portlet

What you got? A portal with a layout that can't be changed... That's typical from JBoss community: they create a simple kernel and everything is extension. JBoss Application Server is a microkernel that manages JMX beans. Everything else is JMX. Likewise, JBoss Portal is just a portlet container. You need that ugly and unintuitive manager (as ugly and unintuitive as AS managers) to manage everything.

BTW, that management portlet does a lot of roundtrips to the server (yep, no AJAX). If you plan to use it on your server, create a page that contains only the manager portlet.

JBoss Portal 2.4 is off my list. I will try 2.6alpha2.

Tagged as: , 2 Comments