You left out some details such as whether the objects instantiated by
the factory are accessed through an interface available to everyone
or through reflection. I'm also not too clear on whether the wars
are all in one ear or deployed separately.
I suspect we could add a flag that would cause a war to use the ear
classloader rather than having a separate classloader. If everything
is in one ear this might work for you. I don't think we are going to
make it so several separately deployed apps have the same classloader.
In terms of what's in g 1.1.1, there are several things you can try.
I'm going to assume that the factory class and a bunch of interfaces
need to be accessible to every part of your application. Recall that
the g. classloaders form a directed acyclic graph. So, you need to
get the factory + interfaces into an ancestor of all the war
classloaders. You can do this by:
- constructing a geronimo module/configuration with a gbean plan that
lists the jars containing these classes as a dependency (put the jars
in the geronimo repo)
- constructing a j2ee artifact such as a war or ejb jar with no
servlets/ejbs that contians the classes
- if all wars are in an ear, either
-- using a geronimo-application.xml plan to pull the jars (in the
geronimo repo) into the ear classloader
-- having an ejb-jar with no ejbs that either contains the classes or
uses manifest-classpath to include the jars that are inside the ear
- putting the jars in shared/lib and using the sharedlib
configuration as a parent
Now, you need to get the actual classes accessible to the factory.
You can do this be either
- putting all these classes in jars that get into the same
classloader as the factory, using one of the techniques already
described
- registering all the child classloaders with the factory, and it
can try each in turn (or do something like constructing a geronimo
multi-parent classloader that includes all of them as parents and
using it)
The second would let you expand the system at runtime without
redeploying the factory.
hope this helps
david jencks
On Oct 18, 2006, at 7:52 AM, Fran Varin wrote:
Hi,
I work with Mark and maybe I can shed a little more light on the
problem
that he is describing. We have classes that are typically
instantiated from
a factory class. This factory uses reflection to perform the
instantiation.
We register the fully qualified name of the class along with a
String that
is used as a key to cause the later instantiation.
We have been using WebSphere for years and have configured WAS to
be able to
share resources (like classes) across the various Web Applications.
This
allows us to maintain the Factory in one context and be able to see
the
other class at runtime when an application requests an object
instance of a
given class. To the best of my knowledge, the ability for an app.
server to
see across the web appications is not unique to WAS. In fact, it makes
configuring complex Java EE applications much easier.
So, our question really boils down to, how can we achieve a similar
behavior
in Geronimo. We would like to use Geronimo for a production
deployment but,
feel that the behavior above is a huge advantage where configuration,
maintenance, and system resource utilization is concerned. Without the
ability we would be required to introduce unnecessary redundancy
across the
entire application. Keep in mind that the Web applications we are
describing
are an integral part of a larger applications, they are not separate
applications running withing the context of one Java EE EAR. Each
WAR is a
logical division of business function that directly contributes to the
application's functionality. As such, they are not atomic
applications by
any definition. So, this strengthens the case above for using resource
sharing.
Since IBM is very involved with Geronimo (WAS-CE) and is moving to
bring
Geronimo and WAS closer together, it is would make sense that the
functionality of each would be complementary. Even if we use
Geronimo (or
WAS-CE) for testing purposes it is not a desirable situation to be
testing
using two servers that have radically different behavior. So, with
that in
mind, it does not seem to make sense for Geronimo to dis-allow such a
valuable capability.
Fran Varin
Sr. Architect
Amica Insurance
Mark L. wrote:
Thanks for the response. I am not sure i gave enough information the
first time as to what our problem truly is. We are using a
factory to
instanciate a list of classes. This factory lives at the EAR
level; the
list of classes are spread thru-out the multiple web modules.
This means
that the factory needs to instantiate some classes in WebA and some
classes in WebB. It appears the way we have configured out
application,
the factory itself is loaded in WebA's classloader (WebA is the
first to
load). Because of this, when the factory tries to instantiate
classes in
the list that reside in WebB, they are not visible and we get the
classNotFound exception. I think putting the classes into jars
and adding
them as dependencies might be overkill since there is no real
co-dependency upon the classes as i inferred in my original post.
It is
simply to be able to instantiate them.
Or is there a way to load our factory in the EAR at startup, which i
assume would have visibility to all classes in all web modules? This
would allow all classes to be instantiated.
We have another application running on Websphere where we have a
similar
setup. We use the same factory living at the EAR level, with
multiple web
modules. When the first module loads, it loads the factory, which
is then
able to instantiate all classes listed, regardless of the modules
they
reside in.
David Jencks wrote:
On Oct 11, 2006, at 10:18 AM, Mark L. wrote:
Hello,
I am using Geronimo 1.1.1. I have created an EAR,
ApplicationIntgrations,
that contains two web modules, WebA and WebB. Both web modules
require
access to each others classes to be able to run. WebA depends on
classes in
WebB, and vice versa. When i deploy the EAR and start the server,
i get
classNotFound errors. See below. Class 'test' is a class in WebB,
but
WebA's classloader cannot find him.
1:08:49,334 ERROR [[/WebA]] Servlet /WebA threw load() exception
java.lang.ClassNotFoundException: test in classloader
Applications/ApplicationIntegrations_WebA.war/EAR/car
at
org.apache.geronimo.kernel.config.MultiParentClassLoader.loadClass
(MultiParentClassLoader.java:249)
at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
How can i make both web modules' classes visible to each other? I
have
tried using dependencies and imports, but i am new to Gernoimo and
have not
been able to get either to work.
Since all the classes need to be in the same classloader, you won't
be able to use dependencies to make this work, as that would lead to
circular classloader dependencies. You have to get the classes into
the ear's classloader: each web app classloader is a child of the
ear
classloader.
I can think of 3 solutions:
1. Put your classes in jars in appropriate places in the geronimo
repository and add dependencies to them to the geronimo application
plan.
2. Put the jars in the shared/lib directory and add a dependency to
the shared lib configuration either in the geronimo application
plan
or in each web app geronimo plan
3. Include a fake ejb jar (i.e. a jar with an ejb deployment
descriptor but no ejbs declared) that either contains all the
classes
or uses the manifest classpath to include the jars with the classes.
If you only need a one-way dependency then it would be much easier,
you could just have one web app depend on the other.
thanks
david jencks
--
View this message in context: http://www.nabble.com/Multiple-
Applications-within-one-Ear---Co-dependent-classes-
tf2424151.html#a6878030
Sent from the Apache Geronimo - Users mailing list archive at
Nabble.com.