[GLASSFISH-12633] EJBContainerProviderImpl ignores classpath entries when they are EJB modules but not specified using EJBContainer.MODULES Created: 13/Jul/10  Updated: 05/Oct/10

Status: Open
Project: glassfish
Component/s: ejb_container
Affects Version/s: 3.1
Fix Version/s: future release

Type: Improvement Priority: Major
Reporter: szczyp Assignee: marina vatkina
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 12,633

 Description   

I am using GF 3.1 build 9.
The faulty code is (EJBContainerProviderImpl.getRequestedEJBModuleOrLibrary,
lines 281 - 285):

DeploymentElement result = null;
...
if (!isEJBModule || moduleNames.isEmpty() || moduleNames.contains(moduleName)) {
result = new DeploymentElement(file, isEJBModule);
}

return result;

The use case: the container is started and the EJB modules are specified:
return EJBContainer.createEJBContainer(parameters);
where parameters contains a mapping EJBContainer.MODULES -> "ejbmodules".

Still, every classpath entry is checked whether it is an EJB module or WAR or
simple lib (EJBContainerProviderImpl.getRequestedEJBModuleOrLibrary method) - I
don't think this should happen, it should first check if the classpath entry is
listed in MODULES. But that's not the real problem.

The problem is that some classpath entries can be discivered as EJB modeles, and
not listed in MODULES, so they should be probably treated as plain library
entries. However, the code quoted above fails to do so - in the described test
case, the 'if' will never return true - isEJBModule is true, so it will go on to
the last condition, which checks whether the name is within the required modules

  • and the DeploymentElement will remain null, effectively making the whole
    classpath entry excluded from deployment.

If I use a library that has an EJB for some reason, the described behaviour will
simply ignore it and the application will blow up in runtime.

I think the check whether an EJB module is listed using MODULES should be done
earlier, as if it is not listed, it doesn't really matter if there are EJBs or
not, it should be a plain library entry. If however, for some reason, the name
check is to stay as it is, the quoted 'if' should be changed, something like:

if (isEJBModule && !moduleNames.contains(moduleName)) {
isEJBModule = false; // treat entry as plain library
}
if (!isEJBModule || moduleNames.isEmpty() || moduleNames.contains(moduleName)) {
result = new DeploymentElement(file, isEJBModule);
}

or

if (!isEJBModule || moduleNames.isEmpty() || moduleNames.contains(moduleName)) {
result = new DeploymentElement(file, isEJBModule);
} else if (isEJBModule && !moduleNames.contains(moduleName)) {
result = new DeploymentElement(file, false); // treat the entry as library
}



 Comments   
Comment by sirajg [ 13/Jul/10 ]

transfer

Comment by marina vatkina [ 15/Jul/10 ]

EJB module can't become a library if EJBContainer.MODULES is not empty. But we
can look at introducing a special setting for that.

Comment by szczyp [ 19/Jul/10 ]

Why can it not? If it is not listed in modules, it is not an EJB module and
should not be treated as such. And on no account must it be ignored as it is now.

Sometimes you will not know that a third party library is an EJB jar, and then
suddenly you will get ClassNotFoundExceptions, and will start scratching your
head, as the classes are there on the classpath.

What is wrong with the code sample I included? It seemed to work for me, and you
probably have unit tests to check if this is valid?

Comment by marina vatkina [ 19/Jul/10 ]

Deployment doesn't distinguish between a library and a Java EE module. So if it
contains EJB annotation, it's an EJB module. Does it work differently for you
when you package and deploy your aplication to a regular GF instance?

Comment by szczyp [ 20/Jul/10 ]

I tested this and what I see is that if a lib jar is has an EJB that is not
included in MODULES it is not deployed as one (DeploymentResult returns null).
However, it is on the classpath. Does this mean that for an EJB module that is
in listed in MODULES, it is both included in classpath and deployed, effectively
being on the classpath twice?

"Deployment doesn't distinguish between a library and a Java EE module. So if it
contains EJB annotation, it's an EJB module. Does it work differently for you
when you package and deploy your aplication to a regular GF instance?"
But I think this is against the specs, which says that if MODULES is included,
it specifies EJB modules. When MODULES is specified, GF includes the modules,
and also scans the classpath as if MODULES was not specified. Is this correct in
terms of the specs?

Generated at Wed Sep 28 06:21:56 UTC 2016 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.