This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 173195 - ear files with war and ejb are mispackaged
Summary: ear files with war and ejb are mispackaged
Status: RESOLVED FIXED
Alias: None
Product: javaee
Classification: Unclassified
Component: EAR (show other bugs)
Version: 6.x
Hardware: Macintosh All
: P2 blocker (vote)
Assignee: David Konecny
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-09-28 15:54 UTC by bbissett
Modified: 2009-10-22 23:40 UTC (History)
8 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
the NB project (27.50 KB, application/x-gzip)
2009-09-28 15:55 UTC, bbissett
Details
The built ear file (7.44 KB, application/octet-stream)
2009-09-28 15:56 UTC, bbissett
Details

Note You need to log in before you can comment on or make changes to this bug.
Description bbissett 2009-09-28 15:54:58 UTC
(I will attach the NB project and ear file after submitting.)

When an ear file is packaged containing a war file and ejb module, then entire ejb module is contained in the classpath of the war file. Only the ejb 
interface should be there. This causes an application server to see two impl classes for a bean interface rather than one, and it cannot resolve the bean impl 
class. Ear files packaged this way work with GlassFish v2, but not with GlassFish v3. Deploying the built ear file into GFv3 fails with:

[#|2009-09-28T10:31:24.968-
0400|SEVERE|glassfish|javax.enterprise.system.tools.deployment.org.glassfish.deployment.common|_ThreadID=22;_ThreadName=Thread-3;|Cannot 
resolve reference Local ejb-ref name=com.example.web.HelloServlet/helloBean,Local 3.x interface =com.example.biz.HelloLocal,ejb-
link=null,lookup=null,mappedName=,jndi-name=,refType=Session because there are 2 ejbs  in the application with interface 
com.example.biz.HelloLocal|#]


More information can be found here:
https://glassfish.dev.java.net/issues/show_bug.cgi?id=9765
Comment 1 bbissett 2009-09-28 15:55:39 UTC
Created attachment 88436 [details]
the NB project
Comment 2 bbissett 2009-09-28 15:56:10 UTC
Created attachment 88437 [details]
The built ear file
Comment 3 David Konecny 2009-09-29 00:49:56 UTC
bbissett, this problem should NOT happen if you do Clean and Build on EAR project. Could you confirm that please?

If I do Clean and Build on EAR then WAR file inside EAR file does not contain EJB jar but just ClassPath reference in
its manifest file which is correct. The problem you described happens when you first build just WAR project - that
creates WAR file and includes entire EJB jar in it. And if you later build EAR then already built WAR file is included
as is. That's something what should not happen and what causes "2 EJBs" problem.
Comment 4 hongzhang 2009-09-29 13:57:31 UTC
Referencing through the manifest is essentially the same thing as packaging the ejb jar in the war. The bean class just
should not be visible to the war file. 

The follow comments are from the EJB spec lead Ken Saks:
It was never legal in EE 5 to package a bean class containing a component-defining annotation in the .war (whether
directly or via the manifest approach).  
The easiest repackaging approach is just to replicate the common interfaces and supporting types in the 
.war instead of using the .war manifest classpath. An alternative is to package the common interface 
code in a library .jar and put it in a directory named "lib" at the .ear level.  In that case all code will be 
guaranteed visibility to both ejb-jars and .wars in the .ear.  
Comment 5 Vince Kraemer 2009-09-29 18:29:39 UTC
do we need the manifest entry at all if the war and ejb-jar are in the same ear?
Comment 6 hongzhang 2009-09-29 18:43:22 UTC
No, we don't and it should be removed. But the EJB interfaces that the web component depend on should be visible to the
war (through packaging directly in the war or in the form of a library jar).
Comment 7 _ ludo 2009-09-29 19:19:35 UTC
to Hong: why? all the necessary classes needed by the war in the context of this EAR file are known and in the ejb jar...

Introducing a new lib will complexify the build process, and as well the dir deploy structure, and compile on save (need
to copy in 2 places the interface?)
How does a maven ejb jar/ear project structure? What about EE 6 samples with ANT tasks? Pointers?


The real reason this cp entry was introduced in Nb 5 for EE 5 was not a runtime error but a GF verifier tool error.
Without the cp entry, I think the runtime was ok, so the war file in the context of the EAR file had access to the
classes in the EJB jar packaged in that EAR file...

Comment 8 David Konecny 2009-09-30 01:19:40 UTC
I re-read chapters of specification on EAR packaging twice but either they are too vague or I missed relevant parts
because some details are still unclear to me.

Let's say I have couple of jars/projects:
* entities.jar - Java class library project which packages JPA entity classes
* ejbs.jar - EJB JAR project which is using using entities.jar and which is defining Session bean for entity class
manipulation
* web.jar - JSF Web Application project which is using entities.jar and ejbs.jar to access directly entity classes and
also ejbs and present them in UI
How these modules should be packaged into one EAR application? I found that GF2 and GF3 behave quite differently. I
actually was not able to package EAR app to make it run properly on GF3 - entity classes cannot be resolved in runtime -
regardless if I place entities.jar to EAR's lib folder or not and regardless if I use ClassPath manifest entry or not.

I would appreciate if somebody could shed some light. Thanks.

PS: I agree that generating separate JAR for EJB interfaces seems like overkill when both WAR and EJBJAR are in the same
EAR.
Comment 9 miteshm 2009-09-30 03:07:19 UTC
dkonecny, 

The simplest way to package the application is as follows

app.ear
 web.jar
 ejb.jar
   META-INF/persitence.xml - persistence.xml contains following
                 <jar-file>lib/earEntities.jar</jar-file>
 lib/
   entity.jar (Notice no persistence.xml should be present here. See section 8.2 of JPA 2.0 spec for details)
  
Comment 10 David Konecny 2009-10-01 04:26:58 UTC
mitesh, thanks! <jarfile> made it clear to me. There is issue which I'm about to fix and which requests that all JAR
files which are not J2EE modules are by default placed to EAR's lib folder (issue 163971). That makes these jars
available to all J2EE modules in EAR and these JARs do not have to be listed in ClassPath manifest property.
Comment 11 David Konecny 2009-10-01 04:29:17 UTC
Re. "EJB interfaces that the web component depend on should be visible to the war (through packaging directly in the war
or in the form of a library jar)" - this is still open question.
Comment 12 miteshm 2009-10-08 00:54:50 UTC
dkonecny, 

I think I misread your post from "Wed Sep 30 00:19:40" last time. If you were trying following ear structure, it should
work. 

app.ear
 web.jar
 ejb.jar
 lib/
   entity.jar
        META-INF/persitence.xml

Can you please try it against latest GlassFish nightly. 

Thanks,
Mitesh
Comment 13 hongzhang 2009-10-08 00:59:13 UTC
Probably this part was never clearly stated in JavaEE5 Spec. This is what's in JavaEE6 Spec:

EE.8.3.1Web Container Class Loading Requirements

Components in the web container may have access to the following classes and resources. Portable applications must not
depend on having or not having access to these classes or resources.

•The classes and resources accessible to any other web modules included in the same ear file, as described above.
•The content of any EJB jar files included in the same ear file. 
...
Comment 14 David Konecny 2009-10-08 01:27:49 UTC
Mitesh, my problem was that I was not using <jar-file> tag properly (which somehow worked in GF2). Fixing that according
to your advice made everything pretty straightforward. Regarding persistence.xml placement I followed specification
chapter "8.2.2 Persistence Unit Scope" and that worked as expected so I more or less ignored your comment "entity.jar
(Notice no persistence.xml should be present here. See section 8.2 of JPA 2.0 spec for details)". :-)
Comment 15 David Konecny 2009-10-08 01:54:12 UTC
Re. "EE.8.3.1Web Container Class Loading Requirements" - let me summarize solutions:

At the moment code for EAR with EJB and WAR generated by NetBeans relies on ClassPath manifest attribute (WAR uses
ClassPath manifest attribute to reference EJB). According to hongzhang "Referencing through the manifest is essentially
the same thing as packaging the ejb jar in the war" which I tend to agree with and we should not be doing. Side note is
that latest GF3 does not seem to follow that - it does not complain that "there are 2 ejbs in the application with [the
same] interface" in case of ClassPath manifest attribute; but it does complain when EJB is packaged in WAR. Let's call
this Solution1.

Solution2 is slight modification of existing state: keep everything as is but do not generate ClassPath manifest
attribute. That would mean that generated code would not be *portable* as defined in EE.8.3.1 - generated WAR would 
depend on having access to "The content of any EJB jar files included in the same ear file" which is optional
requirement but which seems to be implemented by GF3 but which may not be implemented by other servers. How bad is it if
NetBeans generate "non-portable" enterprise applications?

Solution3 is "repackaging approach" - just replicate the common interfaces and supporting types in the 
war. An alternative is to package the common interface code in a library .jar and put it in a directory named "lib" at
the .ear level".

Am I clear and do I understand it right? Any other solutions? At this stage of NB68 development I would prefer to go
with Solution1 or Solution2 despite neither of them being "perfect". Solution3 is a whole new feature. Comments/opinions
highly appreciated. Thanks.
Comment 16 hongzhang 2009-10-08 02:02:38 UTC
Yes, I think you understand the situation fairly well and pretty clear about the three solutions :-) 

Correction for solution 1 though: the v3 does treat them the same. It complains about the manifest case also which is
why this bug was filed. :-) 

I think it would be NetBeans (and plug in) teams' call whether to go with 2) or 3). 

Comment 17 David Konecny 2009-10-08 02:29:56 UTC
Re. "the v3 does treat them the same. It complains about the manifest case also which is why this bug was filed" - no it
does not. :-) I just re-tested it on glassfish-v3-b66 and in manifest case (Solution1) application is correctly
deployed. The bug described in this issue is caused by EJB jar being wrongly included in WAR file which happens if you
perform build of EAR project in certain steps - see my first comment in this issue for more details. But manifest case
was never a problem.

Thanks for confirming that my descriptions are clear - I wanted to make sure we are all on the same page.

Re. "I think it would be NetBeans (and plug in) teams' call whether to go with 2) or 3)." - as Solution1 or Solution2
depends on implementation details of GF3 I would go with them only if GF team confirms they are going to support one of
them.
Comment 18 hongzhang 2009-10-08 02:55:23 UTC
Did you try with the ear that was attached (SimpleWebEjb.ear)? Did it give you the failure when you tried to deploy it? 
Inside this ear, there is an ejb jar and war. In the war, there is no ejb jar packaged directly (nothing under
WEB-INF/classes or WEB-INF/lib), but there is a Manifest file with Class-Path pointing to the ejb.jar. Am I missing
something here? 

For solution 2, yes, this will work with glassfish v3. I would still recommend solution 3 as it's a portable approach
but I understand there will be more work involved. 
Comment 19 David Konecny 2009-10-08 04:23:06 UTC
Re. "Did you try with the ear that was attached (SimpleWebEjb.ear)?" - no, I never did. And trying it now I can see that
deploying an EAR application in directory mode works fine but deploying it as EAR fails with "there are 2 ejbs in the
application". Thanks, that drops Solution1.

Re. "For solution 2, yes, this will work with glassfish v3." - great to hear! I will go ahead and make the changes on
NetBeans side.
Comment 20 Vince Kraemer 2009-10-08 04:33:30 UTC
I was looking through this issue, and realized that one update that I had meant to post was not in here....

Since my memory is a bit faded, you may want to take the following statement with a  grain of salt...

I did some experiments to try to reproduce this issue.  I think I hit another way to generate the output that bbissett
alludes to...

Create an EAR project that includes an EJB jar project and a WAR project.
create an ejb and a simple 'echo' business method
create a servlet that calls that uses the ejb to call the echo method.
Build the project from inside NB.
go to the command-line and use asadmin deploy to deploy the EAR.

Sorry to mention this so late in the process.

I think my posting got jinxed by the network issues that netbeans.org had over the weekend of the Friday Oct 2 to Monday
Oct 5...
Comment 21 David Konecny 2009-10-16 00:48:30 UTC
By fixing issue 163971 I resolved packaging problems identified here: no ClassPath manifest attribute is used; J2EE
Modules are packaged in root of EAR and all other JARs are packaged in EAR's lib subfolder. What remains to be resolved
in this issue is problem described in my first comment in this issue which is P3 issue.
Comment 22 hongzhang 2009-10-16 01:58:46 UTC
Can you clarify with some more details? Reading the other issues, I understand we now add a lib directory to the ear
packaging and will not use manifest entry anymore. So for the attached application, what will be the resulting packaging
now? What is inside the lib directory? Will the current packaged ear work with glassfish v3? 

(And what's "my first comment" referred to?)
Comment 23 David Konecny 2009-10-16 02:40:29 UTC
re. "for the attached application, what will be the resulting packaging now" - file layout will be the same - 2 J2EE
Modules in root of EAR. The only difference is that SimpleWebEjb-war.war will not contain in its manifest following
entry "Class-Path: SimpleWebEjb-ejb.jar". EAR's lib directory in this case is empty and therefore will not be created.

An example when EAR's lib folder would be used is for example if your SimpleWebEjb-ejb.jar sample was depending on a
SomeEntities.jar defining JPA entity classes - SomeEntities.jar would be packaged to EAR's lib folder so that both war
and ejb can access these entity classes. war and ejb would not use ClassPath manifest entry to refer to SomeEntities.jar
as everything in lib folder is available to all J2EE Modules.

"my first comment" refers to my comment in this issue labelled "------- Additional comments from dkonecny Mon Sep 28
23:49:56 +0000 2009 -------".
Comment 24 hongzhang 2009-10-16 02:48:57 UTC
Ok, so the current packaged application will deploy on v3 with no problem. That's my main question :-) 

For you first comment, I thought we later found clean or not does not really make a difference? Anyways, that's not my
main concern.
Comment 25 David Konecny 2009-10-16 03:08:26 UTC
hongzhang, yes deployment to GF3 as well as to GF2 works fine now. There is still one more problem in clean target of
Web Project - that problem can result in whole ejb jar being packaged in war file which is then packaged in ear and
which will result in "there are 2 ejbs in the application". But that error is triggered only by particular order of
build steps and that's why I lowered importance of problem to P3. I plan to resolve that one as well.

Now, one more question hongzhang about AppClient project packaging. If EJB and WAR and APPCLIENT are all packaged in EAR
and APPCLIENT will access enterprise beans from EJB module then what should packaging of APPCLIENT look like.
APPCLIENT.jar should be in EAR's root, right? and contrary to EJB and WAR it should contain ClassPath manifest entry
listing EJB jar, right?? Just when I felt I know all the answers and everything should work fine I realized that
APPCLIENT is most probably broken now (issue 174708).
Comment 26 hongzhang 2009-10-16 03:41:49 UTC
For appclient part, the correct (spec defined portable) packaging is to package the ejb interfaces that the appclient
references inside the appclient jar (or put the interfaces in lib), just like what we should do for the war which
references EJB. 
The reason it worked for war without manifest entry with glassfish is that in glassfish implementation the EJB
classloader is the parent classloader of the Web classloader, so the classes in the war can automatically see all the
EJB classes. But this is not the case with appclient, as the appclient loads in appclient container in client VM (issue
174708).
Using the manifest in the appclient jar to include the ejb jar would work with glassfish for most cases, but it is
really troublesome to do this. To give you an example, one problem that reported: one ejb references some connector
class, when the appclient container loads the appclient in client VM, because the ejb jar was there, that ejb tries to
look for the connector class which does not exist in client VM. 
I think you should probably spend some time to see if we can implement the packaging the proper way before using the
manifest thing as the last resort.
Comment 27 tjquinn 2009-10-16 16:28:46 UTC
Hong's most recent entry is right on-target.  Ideally the app client module will not depend on the EJB module.

Some additional reasons...

Doing so inflates the size of the downloadable bits needed for the app client.  

From the point of view of "clarity of app design" we do not want to encourage or institutionalize through NB exposing
the EJB implementation classes to the client.  The client should depend only on the interfaces and we should not
encourage application structures which expose the EJB implementation classes to the client.

I can see that placing the EJB interface(s) into a library JAR - accessible to all modules in the app including app
clients - involves more engineering work in the tool but it's also the best practice we'd want to encourage.
Comment 28 tjquinn 2009-10-16 16:29:22 UTC
forgot to add myself to the cc list earlier
Comment 29 David Konecny 2009-10-19 04:09:11 UTC
Thanks tjquinn and hongzhang. I understand all the arguments in favour of a JAR file holding EJB interfaces and using
such JAR from WAR/APPCLIENT.

I don't think we can safely automate that process and generate EJB API JAR for user on the background. We could collect
all Remote/Local/No-Interfaces and place them in a JAR but how to handle classes which are required by these API
interfaces? I mean if a stateless session bean references in its Local interface a JPA entity class should we include
that JPA entity class in EJB API JAR as well? or rather not?

The other option is for users to make this separation of API themselves - create dedicated Java Class Project and place
all EJB API there and use it from other J2EE Modules. Users can do it today though there is no extra support or
encouragement to do that from IDE point of view. I understand that it is best practice but I do not like added overhead
for developer so I'm not particularly keen on changing NetBeans EJB project to by default suggest to user to create two
projects and place all EJB API into separate project. That sounds like overkill to me and something user's projects may
have to grown into during the time.

Any ideas how you imagine IDE should deal with this are welcome!
Comment 30 judytang 2009-10-21 16:53:21 UTC
I would like to raise this issue from P3 to P2 so it may be fixed faster, saw two FishCAT emails reporting hitting this
issue, if we can fix this sooner, then it can save every one time.

Thanks,
Judy
Comment 31 Vince Kraemer 2009-10-21 17:49:07 UTC
judytang: please add a pointer to the issue/reports that you think are similar to this issue.
Comment 32 David Konecny 2009-10-22 01:02:16 UTC
If you experience this problem on latest NB build then please file a new issue. I'm fixing the last remaining part of
the problem: 3bc2aa4358cb
Comment 33 Quality Engineering 2009-10-22 23:40:57 UTC
Integrated into 'main-golden', will be available in build *200910221401* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/3bc2aa4358cb
User: David Konecny <dkonecny@netbeans.org>
Log: #173195 - make sure EJB jar is not packaged twice (in WAR and EAR)