Issue Details (XML | Word | Printable)

Key: GLASSFISH-11764
Type: Improvement Improvement
Status: Open Open
Priority: Critical Critical
Assignee: Hong Zhang
Reporter: ljnelson
Votes: 0
Watchers: 5

If you were logged in you would be able to see more operations.

EJBContainer#createEJBContainer() does not consider full classpath

Created: 08/Apr/10 05:21 AM   Updated: 02/May/11 02:01 PM
Component/s: deployment
Affects Version/s: v3.0.1
Fix Version/s: future release

Time Tracking:
Not Specified


Issuezilla Id: 11,764
Tags: 3_1-exclude
Participants: Alexis MP, Amy Roh, Hong Zhang, ksak, ljnelson, marina vatkina and sirajg

 Description  « Hide

The contract for EJBContainer#createEJBContainer() says:

"JVM classpath is searched for all ejb-jars or exploded ejb-jars in directory

The "JVM classpath" in this documentation is presumably intended to be what the
EJB 3.1 specification says:

"By default, the embeddable container searches the JVM classpath (the value of
the Java System property java.class.path) to find the set of EJB modules for

That happens to be a really narrow version of what any given JVM classpath
usually is in reality. A pragmatic definition of classpath also includes the
set of all "reachable" classpath entries present in a jar file's MANIFEST.MF
Class-Path entry.

IMHO the classpath scanning mechanism in EJBContainer should take into account
the full set of classpath entries (including those reachable from a Class-Path
manifest header), not just the value in System.getProperty("java.class.path"),
since that is what programmers expect.

Finally, most Maven tests run by building up such a classpath in an otherwise
empty "booter" jar file. Test cases that launch in this manner will not be able
to discover EJBs on the classpath without manual intervention until this bug is

The full discussion of this issue is available at

Alexis MP added a comment - 08/Apr/10 07:42 AM


sirajg added a comment - 08/Apr/10 07:52 AM


Amy Roh added a comment - 08/Apr/10 09:51 AM

assign to marina

ksak added a comment - 08/Apr/10 12:45 PM

Yes, agree this is ambiguous in the EJB spec. It will have to be clarified in the next spec. This should work
the same way manifest-classpath entries are handled for EE modules during deployment. Namely, that
classes in .jars referenced from the manifest-classpath of a module (and their recursive manifest-
classpaths contents, etc.) are logically included in the set of classes for the original module. Note that the
entries referenced from the manifest-classpath do not themselves define new modules. Their classes are
merely processed as if they were physically packaged within the original module that appears on the jvm

ljnelson added a comment - 08/Apr/10 01:27 PM

OK, so take Maven, which when its surefire-plugin (a JUnit runner, basically)
runs in <forkMode>always</forkMode> mode always builds one jar file in /tmp that
contains a Manifest Class-Path entry. This is pervasive throughout commercial
enterprise Java development.

You're saying-and I don't necessarily disagree with this-that as far as
Glassfish is concerned, it will effectively discover the mother of all EJB jars,
which will just happen to be this empty surefire jar? So ejb-jar.xml files
sprinkled throughout the jars it references are ignored?

Coming at this a different way for a moment, I wonder what the value of
ClassLoader.getResources("META-INF/ejb-jar.xml") would be in such a case (never
tried it). I would argue that if it returns many URLs, then the EJB spec should
follow this behavior (i.e. contrary to your assertion I'd expect many modules to
be defined). If it returns one, then I would agree with your assertion.

Having been burned by Manifest Class-Paths in the past, I seem to recall that
the magic that computes the set and the effective classpath doesn't just make it
look like referenced jars are somehow included as though they were packaged in
the original jar file; it is more like it adds URLs to a URLClassLoader (even
though as far as I can recall that's not actually what happens).

ljnelson added a comment - 08/Apr/10 01:48 PM

Retract my previous comment, please; I misread your statement.

marina vatkina added a comment - 12/Apr/10 11:04 AM

Reassign to deployment to verify that they process manifest entry references

Hong Zhang added a comment - 04/Oct/10 07:09 AM

scrubbing issues

Hong Zhang added a comment - 21/Oct/10 12:10 PM

The deployment now supports absolute URL in the Class-Path attribute. Assign to
ejb team to see if there is any remaining work from ejb container to get the
use case work with embedded ejb container.

marina vatkina added a comment - 21/Oct/10 06:13 PM

Reassigning back to deployment to resolve:
a) a jar with a PU referenced in the class-path
b) GenericAnnotationDetector.hasAnnotationInArchive to look at the manifest

Hong Zhang added a comment - 21/Oct/10 06:43 PM

I can fix b) here which is only invoked in the embedded code path.

But for a) to be fixed, we need to look at META-INF/persistence.xml in the
referenced jar. And more general, we need to start looking for deployment
descriptors in the library jars. I am not sure if that's what we want to do.
Let's having more discussions before we decide what to do. I am going to change
the target milestone to 3.2 (if we do decide to support it, we will need quite
some changes).

Hong Zhang added a comment - 21/Oct/10 07:19 PM

Reading the EE 6 spec (section 8.2.1, quoted at the end), it says the
depoloyment descriptor in the library jar must be ignored:
"Any deployment descriptors in referenced .jar files must be ignored when
processing the referencing .jar file."

Top level JAR files that are processed by a deployment tool should not contain
Class-Path entries; such entries would, by definition, reference other files
external to the deployment unit. A deployment tool is not required to process
such external reference

I think the next version of the EJB spec must do some clarifications to
override the above EE spec section before we do something in the implementation
to support the use case.

EE.8.2.1 Bundled Libraries
Libraries bundled with an application may be referenced in the following ways:
A JAR format file (such as a .jar file, .war file, or .rar file) may reference
a .jar file or directory by naming the referenced .jar file or directory in a
Class-Path header in the referencing JAR file’s Manifest file. The
referenced .jar file or directory is named using a URL relative to the URL of
the referencing JAR file. The Manifest file is named META-INF/MANIFEST.MF in
the JAR file. The Class-Path entry in the Manifest file is of the form
Class-Path: list-of-jar-files-or-directories-separated-by-spaces
(See the JAR File Specification for important details and limitations of the
syntax of Class-Path headers.) The Java EE deployment tools must process all
such referenced files and directories when processing a Java EE module. Any
deployment descriptors in referenced .jar files must be ignored when processing
the referencing .jar file. The deployment tool must install the .jar files and
directories in a way that preserves the relative references between the files.
Typically this is done by installing the .jar files into a directory hierarchy
that matches the original application directory hierarchy. All referenced .jar
files or directories must appear in the logical class path of the referencing
JAR files at runtime.
Only JAR format files or directories containing class files or resources to be
loaded directly by a standard class loader should be the target of a Class-Path
reference; such files are always named with a .jar extension. Top level JAR
files that are processed by a deployment tool should not contain Class-Path
entries; such entries would, by definition, reference other files external to
the deployment unit. A deployment tool is not required to process such external

marina vatkina added a comment - 22/Oct/10 10:46 AM

There will be more things to sort out with a jar wrapping an Java EE module via
Class-Path ref: the module name of an EJB module (with the lack of deployment
descriptors processing in the referenced jars) becomes that of the wrapping jar.