You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@geronimo.apache.org by Andrew Thorburn <nz...@gmail.com> on 2008/05/27 01:59:51 UTC

EAR can't find WEB-INF/classes or WEB-INF/lib

What am I doing wrong? It seems like it should work fine...

I have a fairly basic configuration (I think), which looks kinda like this:

A.ear
|---META-INF
|   |---application.xml
|   |---geronimo-application.xml
|---A.war
|   |---JSPs
|   |---WEB-INF
|   |    |---classes
|   |    |---lib
|   |    |---web.xml
|   |    |--- geroniomo-web.xml
|---jms-resources.xml
|---geronimo-activemq-ra-2.1.1.rar
|---MessageDrivenBean.jar

If necessary I can post the various XML configuration files, though I'd
prefer it if someone could mention what I should have, as I imagine the most
likely cause is that I've missed something.

Both the EAR and the WAR have a manifest.mf file, though it's empty and even
then not much use for pointing to directories.

The bizarre thing is that  I had copied the  libraries to  {EAR_ROOT}/lib,
and it managed to find the JSP files without any problem, and it actually
took a while before I realised it wasn't finding my classes (I was testing
something unrelated). Prior to deploying an EAR file, I was deploying the
WAR file in-place (and exploded, so it wasn't actually a single archive).
That worked fine.

I'd also like to know how to do something similar with the EAR. What's the
directory structure going to need to be? Will it basically be what I've got
now, except extracted and using the --inPlace option with Geronimo?

I'm just really confused, as this is a similar structure to a simple example
I saw, and that had no classpath information. I assume it would have it
worked (not certain about that though, despite it being on the Geronimo
Wiki). That said, it was for 1.1, and I'm running 2.1.1.

All I'm need in need of here is how to get my application to find
WEB-INF/lib and WEB-INF/classes, because right now it doesn't.

Does it matter that I the EAR and WAR have the same name? They're not
actually named A.(ear/war), but as it's for work, I'd like to try and not
divulge too much.

Thanks all,

- Andrew

Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by Andrew Thorburn <nz...@gmail.com>.
Finally found out what I needed to change: I just needed to use
Thread.currentThread().getContextClassLoader()...

I don't know if that's going to be perfect, but it seems to have
solved my problems for now. Bloody Classloading stuff.

Thanks for your help. Now I can have the joy of converting a WAR to an
EAR. Is there any particular reason I can't have an exploded WAR
inside an unexploded EAR file?

Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by Andrew Thorburn <nz...@gmail.com>.
Thanks for your replies. You're right - it's essentially a case of front-end
stuff being mixed in with the back-end stuff. That's not something I did - I
have no idea who decided that would be a good idea, but that's the way it is
right now. There's also a number of other strange design features, but
that's another story entirely.

I can't change dependencies without approval from my boss. I suspect he'll
be ok with it when he finally realises that there's not going to be an
easier way. I'd also worry about it causing flow-on effects to other
projects, and then having to integrate my changes with the main branch...
But that's a problem entirely unrelated to Geronimo, and doesn't need to be
discussed on here.

While I'd appreciate a "Single Class-loader per EAR", I think it would be
better if I could convince my boss to straighten out the dependencies.
Besides, wouldn't that also cause portability problems if people begin
relying on it?

Thanks for your help,

- Andrew

On Wed, May 28, 2008 at 6:46 PM, David Jencks <da...@yahoo.com>
wrote:

>
> On May 27, 2008, at 7:32 PM, Andrew Thorburn wrote:
>
>  Encountered another part of the problem:
>>
>> I can package the frontend stuff (that would normally be found in
>> WAR/WEB-INF/classes into a JAR, put that in EAR/lib, and everything works.
>> However, my boss doesn't like that.
>>
>
> Why not?  that's basically the only arrangement that will work....
>
> It sounds a bit like the dependencies between the jars you are dealing with
> are somewhat mixed up.  In my experience when this kind of problem is
> straightened out everyone finds it much easier to make progress and makes
> fewer mistakes.
>
>>
>>
>> But if I leave the classes in WAR/WEB-INF, then I get a "Class Not Found"
>> exception from one of the libs in EAR/lib, which is trying to load, via
>> reflection, one of the classes in the frontend. I understand why that
>> doesn't work, thanks to your explanation of the classloader.
>>
>> Obviously, if I move the libs from EAR/lib to EAR/WAR/WEB-INF/lib, then
>> all is good. Except that my MDB can't find the libs anymore. Bugger.
>>
>> This problem will occur if I duplicate the libs, yes? I'm reasonably sure
>> it did last time.
>>
>
> I'd expect so.
>
>>
>>
>> Further, if I set "reverse-classloading" to true, then I'm bound to get
>> all sorts of problems, and if my MDB tries to access a static method (say,
>> getInstance() for a class where that pattern is used), it will, essentially,
>> call a *different* method to the one the classes in the WAR would call, yes?
>> And return a different object. Not cool.
>>
>
> I think that would produce more problems that it would solve.
>
>>
>>
>> Can't really go around moving things, as the logging class (that's
>> basically essential) is in the same package as the reflection-using class.
>>
>> Any ideas here apart from "Don't use Reflection", and "Don't call from
>> libs to main"?
>>
>> Now, I think the solution I want is to have the libs able to access the
>> frontend (in WEB-INF), while at the same time being access exactly the same
>> libs from my MDB, and I don't think that's possible in Geronimo?
>>
>
> Not at present.  We could add a "single classloader per ear" flag fairly
> easily but it probably won't get into a release for a month or two.
>
> I'd start by asking why you can't straighten out the dependencies.
>
> thanks
> david jencks
>
>
>

Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by David Jencks <da...@yahoo.com>.
On May 27, 2008, at 7:32 PM, Andrew Thorburn wrote:

> Encountered another part of the problem:
>
> I can package the frontend stuff (that would normally be found in  
> WAR/WEB-INF/classes into a JAR, put that in EAR/lib, and everything  
> works. However, my boss doesn't like that.

Why not?  that's basically the only arrangement that will work....

It sounds a bit like the dependencies between the jars you are dealing  
with are somewhat mixed up.  In my experience when this kind of  
problem is straightened out everyone finds it much easier to make  
progress and makes fewer mistakes.
>
>
> But if I leave the classes in WAR/WEB-INF, then I get a "Class Not  
> Found" exception from one of the libs in EAR/lib, which is trying to  
> load, via reflection, one of the classes in the frontend. I  
> understand why that doesn't work, thanks to your explanation of the  
> classloader.
>
> Obviously, if I move the libs from EAR/lib to EAR/WAR/WEB-INF/lib,  
> then all is good. Except that my MDB can't find the libs anymore.  
> Bugger.
>
> This problem will occur if I duplicate the libs, yes? I'm reasonably  
> sure it did last time.

I'd expect so.
>
>
> Further, if I set "reverse-classloading" to true, then I'm bound to  
> get all sorts of problems, and if my MDB tries to access a static  
> method (say, getInstance() for a class where that pattern is used),  
> it will, essentially, call a *different* method to the one the  
> classes in the WAR would call, yes? And return a different object.  
> Not cool.

I think that would produce more problems that it would solve.
>
>
> Can't really go around moving things, as the logging class (that's  
> basically essential) is in the same package as the reflection-using  
> class.
>
> Any ideas here apart from "Don't use Reflection", and "Don't call  
> from libs to main"?
>
> Now, I think the solution I want is to have the libs able to access  
> the frontend (in WEB-INF), while at the same time being access  
> exactly the same libs from my MDB, and I don't think that's possible  
> in Geronimo?

Not at present.  We could add a "single classloader per ear" flag  
fairly easily but it probably won't get into a release for a month or  
two.

I'd start by asking why you can't straighten out the dependencies.

thanks
david jencks



Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by Andrew Thorburn <nz...@gmail.com>.
Encountered another part of the problem:

I can package the frontend stuff (that would normally be found in
WAR/WEB-INF/classes into a JAR, put that in EAR/lib, and everything works.
However, my boss doesn't like that.

But if I leave the classes in WAR/WEB-INF, then I get a "Class Not Found"
exception from one of the libs in EAR/lib, which is trying to load, via
reflection, one of the classes in the frontend. I understand why that
doesn't work, thanks to your explanation of the classloader.

Obviously, if I move the libs from EAR/lib to EAR/WAR/WEB-INF/lib, then all
is good. Except that my MDB can't find the libs anymore. Bugger.

This problem will occur if I duplicate the libs, yes? I'm reasonably sure it
did last time.

Further, if I set "reverse-classloading" to true, then I'm bound to get all
sorts of problems, and if my MDB tries to access a static method (say,
getInstance() for a class where that pattern is used), it will, essentially,
call a *different* method to the one the classes in the WAR would call, yes?
And return a different object. Not cool.

Can't really go around moving things, as the logging class (that's basically
essential) is in the same package as the reflection-using class.

Any ideas here apart from "Don't use Reflection", and "Don't call from libs
to main"?

Now, I think the solution I want is to have the libs able to access the
frontend (in WEB-INF), while at the same time being access exactly the same
libs from my MDB, and I don't think that's possible in Geronimo?

Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by Andrew Thorburn <nz...@gmail.com>.
Well, I moved it to WAR/WEB-INF/classes (where it used to be), and it works
fine, everything seems to be good.

I understand that it would probably be good to move things to /var/..., but
that would involve making a large number of changes to an application that
I'm really not familiar with, and I'd likely break things. Severely. That
would also result in another configuration file, right? I'm having quite
enough trouble understanding the ones I've got. Don't want another one!

In any event, there's no changes made to these files at run-time, as far as
I'm aware. Anything like that should be stored in the database. And since
it's working, I'm just going to try and avoid changing things.

Also, how would I go about deploying in-place, without having to create an
EAR? Should I just copy everything to where it would be in the EAR but just
not compress it?

On Wed, May 28, 2008 at 11:50 AM, David Jencks <da...@yahoo.com>
wrote:

>
> On May 27, 2008, at 4:40 PM, Andrew Thorburn wrote:
>
> Thanks for the help - I find that I'm struggling to get my head around this
> stuff. It's not exactly touched on at University (and I've only got the
> internet for help).
>
> Anyway, I think it's starting to come together. My current problem is that
> I'm getting a file not found error, of the form:
> /home/andrew/geronimo-jetty6-javaee5-2.1.1/repository/com/proaxiom/maps/
> MAPS/5.9.0/MAPS-5.9.0.ear/lib/maps_www.jar!/quartz-job.xml
>
> Now, the file quartz-job.xml is indeed inside maps_www.jar, and that is,
> indeed, the path to the JAR file. Which is more likely to be the problem:
> Something's not using the correct method to extract files from a JAR, or:
> I've stuck it in the wrong place? If it's the first, there's not much I can
> do about it, as it's the Quartz code, not code I've got access to.
>
> I'll try moving them while I wait for your response, as that seems the
> solution most likely to work.
>
> I don't know much about quartz.  I hope that you can specify the location
> of this configuration file somehow?  I also imagine that this file might be
> something the admin for the program might want to edit?
>
> In geronimo the philosophy is that the stuff in the repo should never be
> modified, and that app specific configuration files should go in the var
> directory.  For instance, the derby db data files are in var/derby.  So, the
> recommended practice would be to put this file in var/proaxiom/config or
> something similar.
>
> If you deploy your app as a geronimo plugin you can arrange that the plugin
> installation will unpack the (original version) of this file into such a
> location automatically.  Otherwise you will have to install it manually.
>  See http://cwiki.apache.org/GMOxDOC21/plugin-infrastructure.html
>
> thanks
> david jencks
>
> Thanks,
>
> - Andrew
>
> On Wed, May 28, 2008 at 11:20 AM, David Jencks <da...@yahoo.com>
> wrote:
>
>>
>> On May 27, 2008, at 3:50 PM, Andrew Thorburn wrote:
>>
>> Yes, that helps a lot. It's not the answer I wanted, but it does answer
>> the question :).
>>
>> I guess that means I'll have to play around and see what can be done.
>>
>> How do separate classloaders work with statics (fields, etc). e.g. If I
>> have a class A with static field B in the WAR, and again in the EJB jar,
>> will I have two instances of that field, such that the WAR has one (because
>> it has it's own separate classloader), and the EJB will have another? If so,
>> then that's a problem.
>>
>>
>> With normal parent-first classloader delegation, only one copy of the
>> class will be loaded, the one in the ejb jar.  If you turn on
>> inverse-classloading in the war, then you will get two copies: one in the
>> ejb jar visible to the ejbs, and one in the war, visible to the web app.
>>  IMO it is almost never appropriate to turn on inverse-classloading.  I
>> didn't discuss this detail in my first reply.
>>
>>
>>
>> I don't know much about Java Beans or Enterprise Java Beans, so this might
>> be a bit silly, but: Can I put the MDB in the WAR? Or does it *have to* have
>> it's own JAR?
>>
>>
>> An mdb has to be in an ejb jar. (or a jar accessible to the ejb apps
>> classloader, such as in a jar in an ear lib directory).  Since the web
>> app/war has a separate classloader that is a child of the ear classloader,
>> there's no way you will be able to get the mdb visible to an ejb app if it
>> is in the war.
>>
>> I guess I should mention that I think openejb standalone has a mode in
>> which you can do something like what you seem to want to do, but it is not
>> standard javaee.  I don't know too much about it.
>>
>> hope this helps
>> david jencks
>>
>>
>>
>> On Tue, May 27, 2008 at 6:03 PM, David Jencks <da...@yahoo.com>
>> wrote:
>>
>>>
>>> On May 26, 2008, at 6:28 PM, Andrew Thorburn wrote:
>>>
>>>  Ok, it now works. Well, kinda.
>>>>
>>>> I think I must have originally also had a lib directory directly inside
>>>> the EAR, as well as in the WAR, which was what was confusing Geronimo.
>>>> Removed that, and my bean didn't start. Removed the (small but important)
>>>> bits of code that relied on that, and everything works. Except it doesn't do
>>>> logging anymore for my MDB. Works fine everywhere else.
>>>>
>>>> Apologies for not having the faintest idea what my problem was, but
>>>> there we go. I now have a new problem, however: How do I reference the stuff
>>>> in the WAR from my MDB JAR? I'm sure I saw information on this somewhere,
>>>> but I closed it because I thought I had a different problem :(. I can't
>>>> duplicate the JARS, as I'm sure that'll cause a vast multitude of problems.
>>>> I really just want to be able to reference them easily, so that I don't have
>>>> to worry about this when coding my application. In fact, it's going to be
>>>> very necessary to communicate between the WAR and the MDB for it to be of
>>>> any use at all (AJAX stuff communicating between browser and database via
>>>> Java app). Basically need the WAR to be processed first, and then have the
>>>> MDB JAR processed, so that I can then reference all the classes in the WAR.
>>>>
>>>> Is this possible? If not, what's the best alternative? Can I chuck my
>>>> MDB into the WAR? I'd be very surprised if I could do that. And I don't know
>>>> if that would solve any of my issues anyway...
>>>>
>>>> The exact location of the classfiles doesn't matter, just so long as it
>>>> all works...
>>>>
>>>> Feh. This is starting to do my head in. Won't be posting again for
>>>> nearly 24 hours (I only work part-time).
>>>>
>>>
>>> I'm not sure I've understood clearly what problem you are having.  Maybe
>>> if I explain the classloader structure your app has and what I think you
>>> need to do it will help.
>>>
>>> For an ear based application with no javaee app clients, there is one
>>> "base" classloader that includes all the ejb jars, all the rars, and all the
>>> jars in the lib directory.
>>>
>>> Then for each war inside the ear, there is a separate classloader that is
>>> a child of the ear classloader that contains the jars in WEB-INF/lib and the
>>> classes in WEB-INF/classes.  Since this is a child of the ear classloader,
>>> all the code in the war can see the classes in the ear (ejb, connector, and
>>> lib).  Also, since these war classloaders  are  children of the ear, nothing
>>> in an ejb, connector or lib jar can see anything in any war classloader.
>>>
>>> I think what you need to do is put any classes that need to be accessible
>>> to both the ejb app (such as your mdb) and the war(s) in either the ejb jar
>>> or in a jar in the ear's lib directory.  Putting any such class anywhere in
>>> any war file will definitely prevent it being accessible from the ejb
>>> application.
>>>
>>> Hope this relates to what you are asking about :-)
>>> david jencks
>>>
>>>>
>>>>
>>>> Anyway, thanks again,
>>>>
>>>> - Andrew
>>>>
>>>
>>>
>>
>>
>
>

Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by David Jencks <da...@yahoo.com>.
On May 27, 2008, at 4:40 PM, Andrew Thorburn wrote:

> Thanks for the help - I find that I'm struggling to get my head  
> around this stuff. It's not exactly touched on at University (and  
> I've only got the internet for help).
>
> Anyway, I think it's starting to come together. My current problem  
> is that I'm getting a file not found error, of the form:
> /home/andrew/geronimo-jetty6-javaee5-2.1.1/repository/com/proaxiom/ 
> maps/
> MAPS/5.9.0/MAPS-5.9.0.ear/lib/maps_www.jar!/quartz-job.xml
>
> Now, the file quartz-job.xml is indeed inside maps_www.jar, and that  
> is, indeed, the path to the JAR file. Which is more likely to be the  
> problem: Something's not using the correct method to extract files  
> from a JAR, or: I've stuck it in the wrong place? If it's the first,  
> there's not much I can do about it, as it's the Quartz code, not  
> code I've got access to.
>
> I'll try moving them while I wait for your response, as that seems  
> the solution most likely to work.
>
I don't know much about quartz.  I hope that you can specify the  
location of this configuration file somehow?  I also imagine that this  
file might be something the admin for the program might want to edit?

In geronimo the philosophy is that the stuff in the repo should never  
be modified, and that app specific configuration files should go in  
the var directory.  For instance, the derby db data files are in var/ 
derby.  So, the recommended practice would be to put this file in var/ 
proaxiom/config or something similar.

If you deploy your app as a geronimo plugin you can arrange that the  
plugin installation will unpack the (original version) of this file  
into such a location automatically.  Otherwise you will have to  
install it manually.  See http://cwiki.apache.org/GMOxDOC21/plugin-infrastructure.html

thanks
david jencks

> Thanks,
>
> - Andrew
>
> On Wed, May 28, 2008 at 11:20 AM, David Jencks  
> <da...@yahoo.com> wrote:
>
> On May 27, 2008, at 3:50 PM, Andrew Thorburn wrote:
>
>> Yes, that helps a lot. It's not the answer I wanted, but it does  
>> answer the question :).
>>
>> I guess that means I'll have to play around and see what can be done.
>>
>> How do separate classloaders work with statics (fields, etc). e.g.  
>> If I have a class A with static field B in the WAR, and again in  
>> the EJB jar, will I have two instances of that field, such that the  
>> WAR has one (because it has it's own separate classloader), and the  
>> EJB will have another? If so, then that's a problem.
>
> With normal parent-first classloader delegation, only one copy of  
> the class will be loaded, the one in the ejb jar.  If you turn on  
> inverse-classloading in the war, then you will get two copies: one  
> in the ejb jar visible to the ejbs, and one in the war, visible to  
> the web app.  IMO it is almost never appropriate to turn on inverse- 
> classloading.  I didn't discuss this detail in my first reply.
>
>>
>>
>> I don't know much about Java Beans or Enterprise Java Beans, so  
>> this might be a bit silly, but: Can I put the MDB in the WAR? Or  
>> does it *have to* have it's own JAR?
>
> An mdb has to be in an ejb jar. (or a jar accessible to the ejb apps  
> classloader, such as in a jar in an ear lib directory).  Since the  
> web app/war has a separate classloader that is a child of the ear  
> classloader, there's no way you will be able to get the mdb visible  
> to an ejb app if it is in the war.
>
> I guess I should mention that I think openejb standalone has a mode  
> in which you can do something like what you seem to want to do, but  
> it is not standard javaee.  I don't know too much about it.
>
> hope this helps
> david jencks
>
>>
>>
>> On Tue, May 27, 2008 at 6:03 PM, David Jencks  
>> <da...@yahoo.com> wrote:
>>
>> On May 26, 2008, at 6:28 PM, Andrew Thorburn wrote:
>>
>> Ok, it now works. Well, kinda.
>>
>> I think I must have originally also had a lib directory directly  
>> inside the EAR, as well as in the WAR, which was what was confusing  
>> Geronimo. Removed that, and my bean didn't start. Removed the  
>> (small but important) bits of code that relied on that, and  
>> everything works. Except it doesn't do logging anymore for my MDB.  
>> Works fine everywhere else.
>>
>> Apologies for not having the faintest idea what my problem was, but  
>> there we go. I now have a new problem, however: How do I reference  
>> the stuff in the WAR from my MDB JAR? I'm sure I saw information on  
>> this somewhere, but I closed it because I thought I had a different  
>> problem :(. I can't duplicate the JARS, as I'm sure that'll cause a  
>> vast multitude of problems. I really just want to be able to  
>> reference them easily, so that I don't have to worry about this  
>> when coding my application. In fact, it's going to be very  
>> necessary to communicate between the WAR and the MDB for it to be  
>> of any use at all (AJAX stuff communicating between browser and  
>> database via Java app). Basically need the WAR to be processed  
>> first, and then have the MDB JAR processed, so that I can then  
>> reference all the classes in the WAR.
>>
>> Is this possible? If not, what's the best alternative? Can I chuck  
>> my MDB into the WAR? I'd be very surprised if I could do that. And  
>> I don't know if that would solve any of my issues anyway...
>>
>> The exact location of the classfiles doesn't matter, just so long  
>> as it all works...
>>
>> Feh. This is starting to do my head in. Won't be posting again for  
>> nearly 24 hours (I only work part-time).
>>
>> I'm not sure I've understood clearly what problem you are having.   
>> Maybe if I explain the classloader structure your app has and what  
>> I think you need to do it will help.
>>
>> For an ear based application with no javaee app clients, there is  
>> one "base" classloader that includes all the ejb jars, all the  
>> rars, and all the jars in the lib directory.
>>
>> Then for each war inside the ear, there is a separate classloader  
>> that is a child of the ear classloader that contains the jars in  
>> WEB-INF/lib and the classes in WEB-INF/classes.  Since this is a  
>> child of the ear classloader, all the code in the war can see the  
>> classes in the ear (ejb, connector, and lib).  Also, since these  
>> war classloaders  are  children of the ear, nothing in an ejb,  
>> connector or lib jar can see anything in any war classloader.
>>
>> I think what you need to do is put any classes that need to be  
>> accessible to both the ejb app (such as your mdb) and the war(s) in  
>> either the ejb jar or in a jar in the ear's lib directory.  Putting  
>> any such class anywhere in any war file will definitely prevent it  
>> being accessible from the ejb application.
>>
>> Hope this relates to what you are asking about :-)
>> david jencks
>>
>>
>> Anyway, thanks again,
>>
>> - Andrew
>>
>>
>
>


Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by Andrew Thorburn <nz...@gmail.com>.
Thanks for the help - I find that I'm struggling to get my head around this
stuff. It's not exactly touched on at University (and I've only got the
internet for help).

Anyway, I think it's starting to come together. My current problem is that
I'm getting a file not found error, of the form:
/home/andrew/geronimo-jetty6-javaee5-2.1.1/repository/com/proaxiom/maps/
MAPS/5.9.0/MAPS-5.9.0.ear/lib/maps_www.jar!/quartz-job.xml

Now, the file quartz-job.xml is indeed inside maps_www.jar, and that is,
indeed, the path to the JAR file. Which is more likely to be the problem:
Something's not using the correct method to extract files from a JAR, or:
I've stuck it in the wrong place? If it's the first, there's not much I can
do about it, as it's the Quartz code, not code I've got access to.

I'll try moving them while I wait for your response, as that seems the
solution most likely to work.

Thanks,

- Andrew

On Wed, May 28, 2008 at 11:20 AM, David Jencks <da...@yahoo.com>
wrote:

>
> On May 27, 2008, at 3:50 PM, Andrew Thorburn wrote:
>
> Yes, that helps a lot. It's not the answer I wanted, but it does answer the
> question :).
>
> I guess that means I'll have to play around and see what can be done.
>
> How do separate classloaders work with statics (fields, etc). e.g. If I
> have a class A with static field B in the WAR, and again in the EJB jar,
> will I have two instances of that field, such that the WAR has one (because
> it has it's own separate classloader), and the EJB will have another? If so,
> then that's a problem.
>
>
> With normal parent-first classloader delegation, only one copy of the class
> will be loaded, the one in the ejb jar.  If you turn on inverse-classloading
> in the war, then you will get two copies: one in the ejb jar visible to the
> ejbs, and one in the war, visible to the web app.  IMO it is almost never
> appropriate to turn on inverse-classloading.  I didn't discuss this detail
> in my first reply.
>
>
>
> I don't know much about Java Beans or Enterprise Java Beans, so this might
> be a bit silly, but: Can I put the MDB in the WAR? Or does it *have to* have
> it's own JAR?
>
>
> An mdb has to be in an ejb jar. (or a jar accessible to the ejb apps
> classloader, such as in a jar in an ear lib directory).  Since the web
> app/war has a separate classloader that is a child of the ear classloader,
> there's no way you will be able to get the mdb visible to an ejb app if it
> is in the war.
>
> I guess I should mention that I think openejb standalone has a mode in
> which you can do something like what you seem to want to do, but it is not
> standard javaee.  I don't know too much about it.
>
> hope this helps
> david jencks
>
>
>
> On Tue, May 27, 2008 at 6:03 PM, David Jencks <da...@yahoo.com>
> wrote:
>
>>
>> On May 26, 2008, at 6:28 PM, Andrew Thorburn wrote:
>>
>>  Ok, it now works. Well, kinda.
>>>
>>> I think I must have originally also had a lib directory directly inside
>>> the EAR, as well as in the WAR, which was what was confusing Geronimo.
>>> Removed that, and my bean didn't start. Removed the (small but important)
>>> bits of code that relied on that, and everything works. Except it doesn't do
>>> logging anymore for my MDB. Works fine everywhere else.
>>>
>>> Apologies for not having the faintest idea what my problem was, but there
>>> we go. I now have a new problem, however: How do I reference the stuff in
>>> the WAR from my MDB JAR? I'm sure I saw information on this somewhere, but I
>>> closed it because I thought I had a different problem :(. I can't duplicate
>>> the JARS, as I'm sure that'll cause a vast multitude of problems. I really
>>> just want to be able to reference them easily, so that I don't have to worry
>>> about this when coding my application. In fact, it's going to be very
>>> necessary to communicate between the WAR and the MDB for it to be of any use
>>> at all (AJAX stuff communicating between browser and database via Java app).
>>> Basically need the WAR to be processed first, and then have the MDB JAR
>>> processed, so that I can then reference all the classes in the WAR.
>>>
>>> Is this possible? If not, what's the best alternative? Can I chuck my MDB
>>> into the WAR? I'd be very surprised if I could do that. And I don't know if
>>> that would solve any of my issues anyway...
>>>
>>> The exact location of the classfiles doesn't matter, just so long as it
>>> all works...
>>>
>>> Feh. This is starting to do my head in. Won't be posting again for nearly
>>> 24 hours (I only work part-time).
>>>
>>
>> I'm not sure I've understood clearly what problem you are having.  Maybe
>> if I explain the classloader structure your app has and what I think you
>> need to do it will help.
>>
>> For an ear based application with no javaee app clients, there is one
>> "base" classloader that includes all the ejb jars, all the rars, and all the
>> jars in the lib directory.
>>
>> Then for each war inside the ear, there is a separate classloader that is
>> a child of the ear classloader that contains the jars in WEB-INF/lib and the
>> classes in WEB-INF/classes.  Since this is a child of the ear classloader,
>> all the code in the war can see the classes in the ear (ejb, connector, and
>> lib).  Also, since these war classloaders  are  children of the ear, nothing
>> in an ejb, connector or lib jar can see anything in any war classloader.
>>
>> I think what you need to do is put any classes that need to be accessible
>> to both the ejb app (such as your mdb) and the war(s) in either the ejb jar
>> or in a jar in the ear's lib directory.  Putting any such class anywhere in
>> any war file will definitely prevent it being accessible from the ejb
>> application.
>>
>> Hope this relates to what you are asking about :-)
>> david jencks
>>
>>>
>>>
>>> Anyway, thanks again,
>>>
>>> - Andrew
>>>
>>
>>
>
>

Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by David Jencks <da...@yahoo.com>.
On May 27, 2008, at 3:50 PM, Andrew Thorburn wrote:

> Yes, that helps a lot. It's not the answer I wanted, but it does  
> answer the question :).
>
> I guess that means I'll have to play around and see what can be done.
>
> How do separate classloaders work with statics (fields, etc). e.g.  
> If I have a class A with static field B in the WAR, and again in the  
> EJB jar, will I have two instances of that field, such that the WAR  
> has one (because it has it's own separate classloader), and the EJB  
> will have another? If so, then that's a problem.

With normal parent-first classloader delegation, only one copy of the  
class will be loaded, the one in the ejb jar.  If you turn on inverse- 
classloading in the war, then you will get two copies: one in the ejb  
jar visible to the ejbs, and one in the war, visible to the web app.   
IMO it is almost never appropriate to turn on inverse-classloading.  I  
didn't discuss this detail in my first reply.
>
>
> I don't know much about Java Beans or Enterprise Java Beans, so this  
> might be a bit silly, but: Can I put the MDB in the WAR? Or does it  
> *have to* have it's own JAR?

An mdb has to be in an ejb jar. (or a jar accessible to the ejb apps  
classloader, such as in a jar in an ear lib directory).  Since the web  
app/war has a separate classloader that is a child of the ear  
classloader, there's no way you will be able to get the mdb visible to  
an ejb app if it is in the war.

I guess I should mention that I think openejb standalone has a mode in  
which you can do something like what you seem to want to do, but it is  
not standard javaee.  I don't know too much about it.

hope this helps
david jencks

>
>
> On Tue, May 27, 2008 at 6:03 PM, David Jencks  
> <da...@yahoo.com> wrote:
>
> On May 26, 2008, at 6:28 PM, Andrew Thorburn wrote:
>
> Ok, it now works. Well, kinda.
>
> I think I must have originally also had a lib directory directly  
> inside the EAR, as well as in the WAR, which was what was confusing  
> Geronimo. Removed that, and my bean didn't start. Removed the (small  
> but important) bits of code that relied on that, and everything  
> works. Except it doesn't do logging anymore for my MDB. Works fine  
> everywhere else.
>
> Apologies for not having the faintest idea what my problem was, but  
> there we go. I now have a new problem, however: How do I reference  
> the stuff in the WAR from my MDB JAR? I'm sure I saw information on  
> this somewhere, but I closed it because I thought I had a different  
> problem :(. I can't duplicate the JARS, as I'm sure that'll cause a  
> vast multitude of problems. I really just want to be able to  
> reference them easily, so that I don't have to worry about this when  
> coding my application. In fact, it's going to be very necessary to  
> communicate between the WAR and the MDB for it to be of any use at  
> all (AJAX stuff communicating between browser and database via Java  
> app). Basically need the WAR to be processed first, and then have  
> the MDB JAR processed, so that I can then reference all the classes  
> in the WAR.
>
> Is this possible? If not, what's the best alternative? Can I chuck  
> my MDB into the WAR? I'd be very surprised if I could do that. And I  
> don't know if that would solve any of my issues anyway...
>
> The exact location of the classfiles doesn't matter, just so long as  
> it all works...
>
> Feh. This is starting to do my head in. Won't be posting again for  
> nearly 24 hours (I only work part-time).
>
> I'm not sure I've understood clearly what problem you are having.   
> Maybe if I explain the classloader structure your app has and what I  
> think you need to do it will help.
>
> For an ear based application with no javaee app clients, there is  
> one "base" classloader that includes all the ejb jars, all the rars,  
> and all the jars in the lib directory.
>
> Then for each war inside the ear, there is a separate classloader  
> that is a child of the ear classloader that contains the jars in WEB- 
> INF/lib and the classes in WEB-INF/classes.  Since this is a child  
> of the ear classloader, all the code in the war can see the classes  
> in the ear (ejb, connector, and lib).  Also, since these war  
> classloaders  are  children of the ear, nothing in an ejb, connector  
> or lib jar can see anything in any war classloader.
>
> I think what you need to do is put any classes that need to be  
> accessible to both the ejb app (such as your mdb) and the war(s) in  
> either the ejb jar or in a jar in the ear's lib directory.  Putting  
> any such class anywhere in any war file will definitely prevent it  
> being accessible from the ejb application.
>
> Hope this relates to what you are asking about :-)
> david jencks
>
>
> Anyway, thanks again,
>
> - Andrew
>
>


Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by Andrew Thorburn <nz...@gmail.com>.
Yes, that helps a lot. It's not the answer I wanted, but it does answer the
question :).

I guess that means I'll have to play around and see what can be done.

How do separate classloaders work with statics (fields, etc). e.g. If I have
a class A with static field B in the WAR, and again in the EJB jar, will I
have two instances of that field, such that the WAR has one (because it has
it's own separate classloader), and the EJB will have another? If so, then
that's a problem.

I don't know much about Java Beans or Enterprise Java Beans, so this might
be a bit silly, but: Can I put the MDB in the WAR? Or does it *have to* have
it's own JAR?

On Tue, May 27, 2008 at 6:03 PM, David Jencks <da...@yahoo.com>
wrote:

>
> On May 26, 2008, at 6:28 PM, Andrew Thorburn wrote:
>
>  Ok, it now works. Well, kinda.
>>
>> I think I must have originally also had a lib directory directly inside
>> the EAR, as well as in the WAR, which was what was confusing Geronimo.
>> Removed that, and my bean didn't start. Removed the (small but important)
>> bits of code that relied on that, and everything works. Except it doesn't do
>> logging anymore for my MDB. Works fine everywhere else.
>>
>> Apologies for not having the faintest idea what my problem was, but there
>> we go. I now have a new problem, however: How do I reference the stuff in
>> the WAR from my MDB JAR? I'm sure I saw information on this somewhere, but I
>> closed it because I thought I had a different problem :(. I can't duplicate
>> the JARS, as I'm sure that'll cause a vast multitude of problems. I really
>> just want to be able to reference them easily, so that I don't have to worry
>> about this when coding my application. In fact, it's going to be very
>> necessary to communicate between the WAR and the MDB for it to be of any use
>> at all (AJAX stuff communicating between browser and database via Java app).
>> Basically need the WAR to be processed first, and then have the MDB JAR
>> processed, so that I can then reference all the classes in the WAR.
>>
>> Is this possible? If not, what's the best alternative? Can I chuck my MDB
>> into the WAR? I'd be very surprised if I could do that. And I don't know if
>> that would solve any of my issues anyway...
>>
>> The exact location of the classfiles doesn't matter, just so long as it
>> all works...
>>
>> Feh. This is starting to do my head in. Won't be posting again for nearly
>> 24 hours (I only work part-time).
>>
>
> I'm not sure I've understood clearly what problem you are having.  Maybe if
> I explain the classloader structure your app has and what I think you need
> to do it will help.
>
> For an ear based application with no javaee app clients, there is one
> "base" classloader that includes all the ejb jars, all the rars, and all the
> jars in the lib directory.
>
> Then for each war inside the ear, there is a separate classloader that is a
> child of the ear classloader that contains the jars in WEB-INF/lib and the
> classes in WEB-INF/classes.  Since this is a child of the ear classloader,
> all the code in the war can see the classes in the ear (ejb, connector, and
> lib).  Also, since these war classloaders  are  children of the ear, nothing
> in an ejb, connector or lib jar can see anything in any war classloader.
>
> I think what you need to do is put any classes that need to be accessible
> to both the ejb app (such as your mdb) and the war(s) in either the ejb jar
> or in a jar in the ear's lib directory.  Putting any such class anywhere in
> any war file will definitely prevent it being accessible from the ejb
> application.
>
> Hope this relates to what you are asking about :-)
> david jencks
>
>>
>>
>> Anyway, thanks again,
>>
>> - Andrew
>>
>
>

Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by David Jencks <da...@yahoo.com>.
On May 26, 2008, at 6:28 PM, Andrew Thorburn wrote:

> Ok, it now works. Well, kinda.
>
> I think I must have originally also had a lib directory directly  
> inside the EAR, as well as in the WAR, which was what was confusing  
> Geronimo. Removed that, and my bean didn't start. Removed the (small  
> but important) bits of code that relied on that, and everything  
> works. Except it doesn't do logging anymore for my MDB. Works fine  
> everywhere else.
>
> Apologies for not having the faintest idea what my problem was, but  
> there we go. I now have a new problem, however: How do I reference  
> the stuff in the WAR from my MDB JAR? I'm sure I saw information on  
> this somewhere, but I closed it because I thought I had a different  
> problem :(. I can't duplicate the JARS, as I'm sure that'll cause a  
> vast multitude of problems. I really just want to be able to  
> reference them easily, so that I don't have to worry about this when  
> coding my application. In fact, it's going to be very necessary to  
> communicate between the WAR and the MDB for it to be of any use at  
> all (AJAX stuff communicating between browser and database via Java  
> app). Basically need the WAR to be processed first, and then have  
> the MDB JAR processed, so that I can then reference all the classes  
> in the WAR.
>
> Is this possible? If not, what's the best alternative? Can I chuck  
> my MDB into the WAR? I'd be very surprised if I could do that. And I  
> don't know if that would solve any of my issues anyway...
>
> The exact location of the classfiles doesn't matter, just so long as  
> it all works...
>
> Feh. This is starting to do my head in. Won't be posting again for  
> nearly 24 hours (I only work part-time).

I'm not sure I've understood clearly what problem you are having.   
Maybe if I explain the classloader structure your app has and what I  
think you need to do it will help.

For an ear based application with no javaee app clients, there is one  
"base" classloader that includes all the ejb jars, all the rars, and  
all the jars in the lib directory.

Then for each war inside the ear, there is a separate classloader that  
is a child of the ear classloader that contains the jars in WEB-INF/ 
lib and the classes in WEB-INF/classes.  Since this is a child of the  
ear classloader, all the code in the war can see the classes in the  
ear (ejb, connector, and lib).  Also, since these war classloaders   
are  children of the ear, nothing in an ejb, connector or lib jar can  
see anything in any war classloader.

I think what you need to do is put any classes that need to be  
accessible to both the ejb app (such as your mdb) and the war(s) in  
either the ejb jar or in a jar in the ear's lib directory.  Putting  
any such class anywhere in any war file will definitely prevent it  
being accessible from the ejb application.

Hope this relates to what you are asking about :-)
david jencks
>
>
> Anyway, thanks again,
>
> - Andrew


Re: EAR can't find WEB-INF/classes or WEB-INF/lib

Posted by Andrew Thorburn <nz...@gmail.com>.
Ok, it now works. Well, kinda.

I think I must have originally also had a lib directory directly inside the
EAR, as well as in the WAR, which was what was confusing Geronimo. Removed
that, and my bean didn't start. Removed the (small but important) bits of
code that relied on that, and everything works. Except it doesn't do logging
anymore for my MDB. Works fine everywhere else.

Apologies for not having the faintest idea what my problem was, but there we
go. I now have a new problem, however: How do I reference the stuff in the
WAR from my MDB JAR? I'm sure I saw information on this somewhere, but I
closed it because I thought I had a different problem :(. I can't duplicate
the JARS, as I'm sure that'll cause a vast multitude of problems. I really
just want to be able to reference them easily, so that I don't have to worry
about this when coding my application. In fact, it's going to be very
necessary to communicate between the WAR and the MDB for it to be of any use
at all (AJAX stuff communicating between browser and database via Java app).
Basically need the WAR to be processed first, and then have the MDB JAR
processed, so that I can then reference all the classes in the WAR.

Is this possible? If not, what's the best alternative? Can I chuck my MDB
into the WAR? I'd be very surprised if I could do that. And I don't know if
that would solve any of my issues anyway...

The exact location of the classfiles doesn't matter, just so long as it all
works...

Feh. This is starting to do my head in. Won't be posting again for nearly 24
hours (I only work part-time).

Anyway, thanks again,

- Andrew