Java

JDJ Readers are clearly out of touch

Or is JDJ’s list of contenders tainted by marketing money? Maybe we just had some electronic ballot stuffing. The so-called “Reader’s Choice” awards, just released by SYS-CON Media, publisher of Java Developer’s Journal (JDJ) are so completely out of touch with the reality of the current Java development community, I can’t even begin to guess how they arrived at their conclusions. Either the readers are clinically insane, they Christmas treed the survey, or they just sat through a bunch of marketing presentations from these vendors before responding.

It’s called journalistic integrity, and perhaps JDJ ought to look into it before they put together their list of contenders next year.

Best Java Application Server
Winner: BEA WebLogic Server, BEA Systems (www.bea.com)
First Runner-up: JBoss 3.x Application Server, JBoss Group (www.jboss.com)
Second Runner-up: IBM WebSphere Application Server v5.0, IBM (www.ibm.com)
Third Runner-up: Fiorano ESB, Fiorano Software (www.fiorano.com)
No problem with the top 3, but what is Fiorano ESB? I can honestly say that I’ve never heard of it, and I’ve heard of a TON of Java App servers. I wouldn’t be surprised to see an ad for this product between the articles of JDJ. I don’t dispute that it may be a good product, but find it quite hard to believe that an unknown product would be a readers’ choice.

Best Java Data Access Tool
Winner: IBM WebSphere Studio (Application Developer v5.0), IBM (www.ibm.com)
First Runner-up: Fiorano ESB Data Access Service, Fiorano Software (www.fiorano.com)
Second Runner-up: Kodo JDO, SolarMetric (www.solarmetric.com)
Third Runner-up: Oracle TopLink, Oracle (www.oracle.com)
Once again – Fiorano as the #2 choice?! Where is the fervent yet mute community of users that loves this product so much? And what about ANY of the open source data access tools (Hibernate, OJB, etc)? Or was this description tweaked to only accomodate vendor products?

Best Java Persistence Architecture
Winner: Oracle TopLink, Oracle (www.oracle.com)
First Runner-up: Kodo JDO, SolarMetric (www.solarmetric.com)
Second Runner-up: Describe, Embarcadero Technologies (www.embarcadero.com)
Third Runner-up: The Open For Business Project, The Open For Business Project (www.ofbiz.org)
Once again, was this category designed to omit almost all the open source options? I’ll buy that TopLink and Kodo belong here, but ofbiz? I’ve looked at it – it’s a set of applications, based on (I think) Castor for persistence. Good project? possibly. But it’s not a “Persistence Architecture”.

Best Java IDE Environment
Winner: JBuilder, Borland (www.borland.com)
First Runner-up: Eclipse, Eclipse.org (www.eclipse.org)
Second Runner-up: IBM WebSphere Studio v5.0, IBM (www.ibm.com)
Third Runner-up: IntelliJ IDEA, JetBrains (www.intellij.com)
No big gripe here, though based on the pulse of the Java community, I’d expect IDEA and Eclipse to outpace the other two.

Best Java Web Services Toolkit
Winner: BEA WebLogic Workshop, BEA Systems (www.bea.com)
First Runner-up: IBM WebSphere SDK for Web Services, IBM (www.ibm.com)
Second Runner-up: Oracle9i JDeveloper, Oracle (www.oracle.com)
Third Runner-up: Advantage Plex, Computer Associates (www.ca.com)
Ever heard of Apache’s Axis? What about Glue? I’ve heard more people rave about Glue than the rest of the “winners” combined. Or were they drinking from the vendor fire hose again?

Most Innovative Java Product
Winner: IntelliJ IDEA, JetBrains (www.intellij.com)
First Runner-up: Fiorano ESB, Fiorano Software (www.fiorano.com)
Second Runner-up: Eclipse, Eclipse.org (www.eclipse.org)
Third Runner-up: WebSphere Application Server Enterprise, IBM (www.ibm.com)
Innovative, eh? An IDE, the unheard of Fiorano, another IDE, and a J2EE app server. Wow, if that’s innovation…

Best Java Virtual Machine
Winner: BEA WebLogic JRockit, BEA Systems (www.bea.com)
First Runner-up: IBM Developer Kit, Java 2 Technology Edition, version 1.4.0, IBM (www.ibm.com)
Second Runner-up: Oracle JVM, Oracle (www.oracle.com)
Third Runner-up: Excelsior JET, Excelsior (www.excelsior-usa.com)
So you mean to tell me that Sun’s JVM isn’t even the 4th favorite JVM out there? Or did Sun neglect to pay for placement?

Best Enterprise Database
Winner: Oracle9i Database, Oracle (www.oracle.com)
First Runner-up: DB2 Universal Database v 8.1, IBM (www.ibm.com)
Second Runner-up: JDataStore 6, Borland (www.borland.com)
Third Runner-up: Advantage Ingres, Computer Associates (www.ca.com)
How much did Borland and CA pay to get on this list?

Best Java Profiling/Testing Tool
Winner: JProfiler, ej-technologies (www.ej-technologies.com)
First Runner-up: Quest JProbe, Quest Software (www.quest.com)
Second Runner-up: IBM WebSphere Studio (Application Developer v5.0), IBM (www.ibm.com)
Third Runner-up: Oracle9i JDeveloper, Oracle (www.oracle.com)
A couple of IDEs in the mix? Even if they did come in 3rd and 4th, are they truly better for testing/profiling than JUnit, OptimizeIt, or DevPartner?

Best Java Producer Platform
Winner: IBM WebSphere Application Server v5.0, IBM (www.ibm.com)
First Runner-up: BEA WebLogic Workshop, BEA Systems (www.bea.com”)
Second Runner-up: Sun ONE Web Server, Sun (www.sun.com)
Third Runner-up: Compuware OptimalJ,`Compuware (www.compuware.com)
A producer platform is… what? A J2EE app server, an IDE, or an MDA tool? This category seems to exist as nothing more than a place to repeat vendors’ names. There’s no one category of problem that all of these solve

Best Java Messaging Tool
Winner: Fiorano MQ, Fiorano Software (www.fiorano.com)
First Runner-up: IBM WebSphere MQ 5.3, IBM (www.ibm.com)
Second Runner-up: SwiftMQ 4.0, IIT Software (www.swiftmq.com)
Third Runner-up: Oracle9i Application Server, Oracle (www.oracle.com)
Ahhh, one last dose of Fiorano. Once again they get the nod of inclusion over several more common players, such as SpiritSoft, OpenJMS…

It’s not that I don’t expect this sort of thing from Gartner, Forester, etc. It’s that I expect better out of a publication that purports to be for the developers. Don’t give me marketing BS, give me straight talk, a real reflection of what Java developers are actually choosing when they’re in the trenches building apps. THAT would be a true “Reader’s Choice”.

Java

J2EE Security is superior, but you aren't using it

An OnJava Article points out the advantages of J2EE’s security as compared to .NET. What I’ve found, though, is that most J2EE developers are completely ignorant of this security, and end up building their own, putting in ten times the effort to get half the functionality.

If your app server provides decent support for JAAS, you can plug in a variety of security providers, validating passwords and extracting roles from flat files, LDAP, a relational database, and more. The advantage here is that your mechanism for getting passwords and roles is fully decoupled from your applications, can be shared by multiple applications, and is already written for you.

On the web application side of things, you can declare the security configuration in your web.xml – you can specify login pages, login failure pages, which pages to secure, which to omit. Frankly, the declaration of which pages to secure is a bit lacking, when compared to ANT’s include/exclude functionality, but it’s worth the intrusion to get all this functionality for free. Your EJBs can also be secured declaratively. That’s not going to address every situation, so you can add some programmatic security on top of that. The current user and their ability to perform certain roles are built into the HttpServletRequest object, and so you can easily further lock down functionality that way.

For as much work as vendors have done to implement this, time and again I see developers failing to use it. Most of the time it is failure to understand what is available to them. The rest of the time, reasons are created why J2EE Container Managed Security is inadequate. While there are certainly occasions where this is true, I believe that most of the time, the core needs could be met using the built-in security. The biggest deficiency I see is that there’s no way to add additional metadata to your authentication. You can provide a user credential, and an authentication credential (password, certificate, etc), but that’s it. What if you wanted to run multiple companies off of a single security repository? You’d want usernames to only be unique per company, but possibly otherwise duplicated. Or what if you wanted to provide 2 security credentials, such as a password and a challenge/response code? As it stands, the JAAS interfaces have no place to put this data, so there’s not even an option to build extensions to manage it without gutting your app server. This is something that should be remedied ASAP as a part of the JAAS spec.

Other than that gripe, I can’t urge you strongly enough to investigate the best J2EE feature that you’re probably not using.

Java

Axis vs. Glue vs. ???

We’re diving into spike solutions to our need for J2EE Web Services (not a big XP shop, just something I realized is a habit of mine that happens to also be an XP practice). The big players in this area that I’ve heard of are Apache Axis and Glue. As an Apache project, Axis has a certain air of ubiquity and authority as the open source standard, but I’ve heard talk of it being a bit hard to use. On the other hand, Glue has a reputation for ease-of-use, but since TheMindElectric was purchased by webMethods, I ponder how much longer the free Standard Edition will be available with license terms that can handle heavy traffic.

I’ll try and keep this up to date with anything that I discover. In the interim, thoughts, experiences, rants, and suggestions of other tools for the job are more than welcome.

General

John Kerry – Affair Allegations Exploding

The Drudge Report is reporting that John Kerry is fighting off allegations and investigations of infidelity. Earlier this week, Wesley Clark said in an off the record interview with a dozen reporters, “Kerry will implode over an intern issue.”

This is also theorized as the reason that Dean decided to stay in the race after Wisconsin. This news is about to go nuclear (or is it nuc-u-lar?).

— Ongoing —

It’s worth noting that Drudge also broke the story on Bill Clinton & Monica Lewinsky – he’s a fairly credible source.

Also interesting is that Drudge’s servers have since collapsed under the load of this breaking story.

Looks like Drudge got some more servers up. WorldNetDaily has picked up the story.

Java

Tracking User Sessions Made Simple(r)

Knowing which users are logged into your applications, what they’re accessing, and when they might leave can be invaluable. In our environment, we have multiple applications fronted by a thin, portal-like front end. For the purposes of the example, we want to know who’s using which webapp, and when they logged in. We’ll also track the session timeout, just for kicks.

The bulk of the problem is finding a common place to store the information, and accessing and structuring that data. In this case, we have a shared application configured for the root context (e.g. http://localhost/), but you can really choose any app you have deployed. The core of this feature is the Http Servlet event model, particularly the javax.servlet.http.HttpSessionBindingListener, which fires an event when it is attached to a session (in our case, at login), and when it is detached from the session (at session invalidation, unless removed/replaced by other code). An example listener follows:

public class PortalSessionBindingListener implements HttpSessionBindingListener
{
   private org.apache.commons.logging.Log log =
   org.apache.commons.logging.LogFactory.getLog(this.getClass());
  
   private String username;
   private String appname;
  
   public PortalSessionBindingListener( String username, String appname )
   {
     this.username = username;
     this.appname = appname;
   }

   public void valueBound(HttpSessionBindingEvent event)
   {
     String sessionId = event.getSession().getId();
     String sessionTimeout = Integer.toString(event.getSession().getMaxInactiveInterval());
     String timeLoggedIn = (new Date()).toString();
     // ServletContext of shared app
     ServletContext sharedContext = event.getSession().getServletContext().getContext(“/”);
    
     Map userMap = (Map) sharedContext.getAttribute(“userMap”);
     if (userMap == null)
     {
       userMap = new HashMap();
       sharedContext.setAttribute(“userMap”, userMap);
     }
     //Get active sessions for this user
     Map userSessionMap = (Map) userMap.get(username);
     if (userSessionMap == null)
     {
       userSessionMap = new HashMap();
       userMap.put(username, userSessionMap);
     }
     SessionListEntry entry = (SessionListEntry) userSessionMap.get(sessionId);
     if ( entry == null)
     {
       entry = new SessionListEntry(username, appname, timeLoggedIn,
           sessionTimeout, sessionId);
       userSessionMap.put(sessionId, entry);
     }
   }
  
   public void valueUnbound(HttpSessionBindingEvent event)
   {
     String sessionId = event.getSession().getId();
     // ServletContext of shared app
     ServletContext sharedContext = event.getSession().getServletContext().getContext(“/”);
    
     Map userMap = (Map) sharedContext.getAttribute(“userMap”);
     Map userSessionMap = (Map) userMap.get(username);
     if (userSessionMap != null)
     {
       SessionListEntry entry = (SessionListEntry) userSessionMap.get(sessionId);
       if (entry != null)
       {
         userSessionMap.remove(sessionId);
         if (userSessionMap.isEmpty())
         {
           userMap.remove(userSessionMap);
         }
       }
     }
   }
}

SessionListEntry is just a simple JavaBean style object (except with no setters) that can easily be extended to hold any info you might need. You’ll probably want to wrap the whole userMap/UserSessionMap in some objects so it’s cleaner and more OO, but it’s easier to illustrate this way. We’re using struts in all of our apps, so we have defined a struts action, SessionTrackerAction, with the following execute method:

   public ActionForward execute(
     ActionMapping mapping,
     ActionForm form,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception
   {
     //Appname must be configured in parameter
     String appname = mapping.getParameter();
     String username = request.getUserPrincipal().getName();
     PortalSessionBindingListener listener = new PortalSessionBindingListener( username, appname);
     request.getSession().setAttribute(“portalListener”, listener);
     return mapping.findForward(“success”);
   }

If you have control over the links users use to access the application (as we do), you can route all users through a single link for each application. For each application, we use an index.do as the entry point to the app, and we define that action as:

   <action path=”/index”
       type=”com.acme.portal.action.SessionTrackerAction”
       parameter=”appName”>
     <forward name=”success” path=”.index”/> <!– forwarded to tiles template –>
   </action>

If you don’t have this level of control, you could easily put a servlet filter on the application that executes the code we’ve embedded in the struts action when session.isNew() [== true] and request.getUserPrincipal() != null. Another application of a servlet filter could be to update the SessionListEntry each time the user requests a page, in order to precisely know when their session is due to expire. While I question whether that’s worth the overhead, it IS an interesting application of the code.

Java

Yet Another JBoss ClassLoader Rant

I really thought I had it all out of my system, but with each passing day, another aspect of the stupidity that is JBoss’ Unified Class Loader comes out and bites me.

The culprit this time? Precompiled JSPs. You see, we have this lovely Ant task that helps us precompile our JSPs – it looks something like this:

<java classname=”org.apache.jasper.JspC” classpathref=”jsp.precompile.path”>
<arg value=”-v4″/>
<arg value=”-die”/>
<arg value=”-d”/>
<arg value=”${jsp.precompile.dir}” />
<arg value=”-webinc”/>
<arg value=”${gen.mappings}”/>
<arg value=”-webapp”/>
<arg value=”${web.root}”/>
<arg value=”-uriroot”/>
<arg value=”${web.root}”/>
</java>

(You also need to merge the generated servlet definitions into your web.xml)

Things are all well and good until I begin combining all of our applications into a single JBoss instance as a part of our not-a-portal application gateway. Then, I begin seeing some very strange errors when I first access one of the applications. Kindly, Tomcat gives me an error, albeit in the form of an IllegalDispatchAction, and a line number in the translated JSP source. Strangely, however, the JSP source doesn’t contain the offending method at the specified line. And then it hits me.

That evil JBoss Universal ClassLoader has taken the precompiled index.jsp from another application and tried to use it in this application!

Now I’m sure that It-seemed-like-a-good-idea-at-the-time to design the JBoss ClassLoader the way it is. To their credit, it is very consistent in its application of these heinous rules, but this is yet another unintended consequence of this decision. I can think of very few situations where what I REALLY want is to have a precompiled JSP from a different application loading into my app. Those few situations are actually inconsistent with typical JSP behavior – if I can’t share non-precompiled JSPs between apps, why should I be able to share them in precompiled (i.e. servlet) form?

The solution is simple, but the beast of it all is tracking down the problem in the first place. All you have to to is give each app a unique package for its JSPS by adding a parameter to that JspC command:

<arg value=”-p”/>
<arg value=”uniquePackageName”/>

And voila! Another heinous consequence of the UCL worked around.