Hey folks,

The general purpose of this note is to explore refactoring some of our jars to reduce some problems that have come about due to our signing of jars.

So, let me start with a description of the problem.   Essentially, the core issue is around the simple replacement of an EAP signed jar with an unsigned jar.  While we have a system in place to have QE get one-off patches signed in a relatively responsive manner, we are still left with cases such as a diagnostic jar created by support to track down problems, or a customer that, understanding that it would not be supported, wishes to make a change for their system (one of the advantages of OSS, of course).

The problem with such a substitution is the fact that a classloader will not load classes from a packages that appear in differently signed jars.  So, for example, even though class org.jboss.A may only occur in an unsigned A.jar, loading it will cause a security exception if class org.jboss.B was loaded from a signed B.jar.  Now, the first step to resolve this would be to replace both A.jar and B.jar with unsigned versions.  But, we then often run into a transitive entanglement.  B.jar may contain classes from package org.jboss, but also org.hibernate.  So, you have to have unsigned versions of C.jar and D.jar that contain the hibernate packages.  But, they have an org.apache package, and so on.

Using TattleTale with some custom reports, I generated "signed jar groups" identifying clusters of jars that would need to all be replaced as unsigned if any one is unsigned.  For the largest group, I created a graph of the dependencies shown in http://community.jboss.org/wiki/SignedJarDependenciesExample (getopt_jar_Group.png, named by the first jar listed in the group from the report.)

The figure shows the jars with a line connecting them if they have one or more packages in common (I also generate detailed plots with a labelled line for each package in common if anyone wants to see them, but for the "getopt" group, the detailed plot is quite large and hard to read.)  Clearly, lots of unrelated jars are wound up in this group.  But, we can chip away at this with a bit of analysis.  I'll give three examples.

First, consider the set of jar files just to the right of the center grouped around jboss-ejb3-core.jar.  This set of jars is tied into the rest of the graph through the connection between jboss-as-ejb3-deployer.jar and jboss.jar. The package that ties them is  org.jboss.as.javaee.  In this case there appears to be only two classes involved.  In jboss.jar there is org.jboss.as.javaee.SimpleJavaEEModuleIdentifier and in jboss-as-ejb3-deployer.jar there is org.jboss.as.javaee.SimpleJavaEEModuleInformer (which has an inner class).  So, in this case, we can break off a chunk of the signed jar group by, for example, changing a package name: org.jboss.as.javaee.ejb3.SimpleJavaEEModuleInformer

Next, from the graph, we can see that there is a group of jar files on the far left that is tied in by a connection between the jboss-system-jmx.jar and the jboss.jar.  In this case, the package is org.jboss.deployment.  There are several classes in jboss.jar and a handful in jboss-system-jmx.jar that are in this package.  So, options might include renaming the package for the classes in the jboss-system-jmx.jar, moving them to jboss.jar, or separating the org.jboss.deployment classes between them into a new jar: jboss-deployment.jar.

Finally, staying on the far left of the graph we see that run.jar and shutdown.jar are tied into some third party jars such as getopt.jar, hsqldb.jar and jdom-1.0.jar.  These are due to use of classes in the default package.  Further, the default package is included because the contents of the getopt.jar are incorporated into run.jar and shutdown.jar.  So, this connection to third party jars can be broken out by removing the GetOpt related classes from run.jar and shutdown.jar and relying on the Class-Path: attribute in their manifests.

So, in the end, it would seem to be beneficial to refactor package locations such that there is not such widespread entanglement.  From the signed jar perspective, it would be best if each package only appeared in one jar.  Of course, there are often engineering reasons to separate classes in the same package into different jars.  However, I think it's not unreasonable that these should be relatively small in number and they should be functionally coherent.  At any rate, it would appear to be something we could attack incrementally as indicated by the three examples above.

Originally, when discussing this with other folks, we thought perhaps we should just open jiras to address the problem.  But, on considering that, it seemed that perhaps a discussion on a larger game plan would be a better approach, even if it just ended up with the original plan of opening some jiras to "chip away" at the problem.

So, I apologize for a long, dense note.  For those of you that made it through, any thoughts, suggestions?

Cheers,
Mike C.