You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@geronimo.apache.org by pgrey <pg...@iss.net> on 2007/03/02 23:47:46 UTC
Re: ejb circular references
Hi, thanks again for your help, just wanted to follow up.
We pursued the local EJB strategy for a while, but could never quite get it
to work ("same classloader" issues). So we made the EJBs remote, and appA
and appB are both quite happy now.
"David Jencks" <da...@yahoo.com> wrote
in message news:CABF1DAF-C7C4-40BD-B82F-F3719C39B492@yahoo.com...
>
> On Feb 26, 2007, at 7:23 AM, pgrey wrote:
>
>> I'm looking around for an example of a "dependencies only" plan. Do you
>> happen to know of an example?
>
> In the geronimo 2.0 build the configs/jee-specs subproject is a
> dependencies only plan. Here's a shortened version of the output plan
> (mostly generated by the car-maven-plugin):
>
>
> <?xml version="1.0" encoding="UTF-8"?>
> <module xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2">
> <environment>
> <moduleId>
> <groupId>org.apache.geronimo.configs</groupId>
> <artifactId>jee-specs</artifactId>
> <version>2.0-SNAPSHOT</version>
> <type>car</type>
> </moduleId>
> <dependencies>
> <dependency>
> <groupId>org.apache.geronimo.specs</groupId>
> <artifactId>geronimo-annotation_1.0_spec</artifactId>
> <version>1.0</version>
> <type>jar</type>
> <import>classes</import>
> </dependency>
> <dependency>
> <groupId>org.apache.geronimo.specs</groupId>
> <artifactId>geronimo-j2ee-connector_1.5_spec</artifactId>
> <version>1.1</version>
> <type>jar</type>
> <import>classes</import>
> </dependency>
> </dependencies>
> <hidden-classes/>
> <non-overridable-classes/>
> </environment>
> </module>
>
>
> thanks
> david jencks
>
>
>>
>>> parent classloader for both apps. I'd recommend putting the
>>> necessarly
>>> interface jars into the geronimo repository at appropriate locations
>>> and
>>> deploying a "dependencies only" plan to create a classloader including
>>> these jars: then you can have a dependency on this module in each of
>>> your
>>> ears.
>>
>>
>>
>> "David Jencks" <da...@yahoo.com>
>> wrote
>> in message
>> news:CAEDC85C-CB2F-45BE-BF37-2E11ABE0C900@yahoo.com...
>>>
>>> On Feb 23, 2007, at 1:10 PM, pgrey wrote:
>>>
>>>> Hello again.
>>>>
>>>> I've incorporated your code as best I could into myappA. I am able
>>>> to
>>>> get
>>>> and cast a reference to MySecurityServicesLocalHome. However, a call
>>>> on
>>>> this to ".create()" throws a ClassCastException.
>>>>
>>>> [java] Caused by: java.lang.ClassCastException:
>>>> org.openejb.proxy.SessionEJBLocalObject$$EnhancerByCGLIB$$18880c84
>>>> cannot be
>>>> cast to co.my.MySecurityServicesLocal
>>>> [java] at
>>>> org.openejb.proxy.EntityEJBLocalHome$$EnhancerByCGLIB$
>>>> $8786f6ac.create(<generated>)
>>>
>>> OK, I forgot about this part.... but I think someone mentioned you
>>> wanted
>>> to use ejb local references. That means the interface classes have to
>>> be
>>> in the same classloader in both apps. Since you want to be able to
>>> deploy them independently, you have to get them into a parent
>>> classloader for both apps. I'd recommend putting the necessarly
>>> interface jars into the geronimo repository at appropriate locations
>>> and
>>> deploying a "dependencies only" plan to create a classloader including
>>> these jars: then you can have a dependency on this module in each of
>>> your
>>> ears.
>>>
>>> You can also use the sharedlib module, although I don't think that
>>> gives
>>> a suitably explicity level of control over your classloaders.
>>>
>>> If you don't want to have a shared parent classloader you have to use
>>> a
>>> remote rather than local reference. I think there's code that
>>> serializes/deserializes as necessary without actually going over tcp/
>>> ip
>>> but I haven't looked there in quite a while and might be wrong.
>>>
>>> I figure that if you got this far you found the EjbReference class :-)
>>>
>>> Hope this helps
>>> david jencks
>>>
>>>>
>>>>
>>>>
>>>>
>>>> "David Jencks" <da...@yahoo.com>
>>>> wrote
>>>> in message
>>>> news:D5401B05-A79F-4A1D-9E18-511229CCBF37@yahoo.com...
>>>>>
>>>>> On Feb 23, 2007, at 7:31 AM, pgrey wrote:
>>>>>
>>>>>> Thank you for your response.
>>>>>>
>>>>>> Let's try to solve a specific part of this problem.
>>>>>>
>>>>>> In "geronimo-application.xml" of "myappA.ear", there is the
>>>>>> following
>>>>>> declaration.
>>>>>>
>>>>>> <gbean name="my-realm"
>>>>>> class="org.apache.geronimo.security.realm.GenericSecurityRealm"
>>>>>> xmlns="http://geronimo.apache.org/xml/ns/deployment-1.1">
>>>>>> <attribute name="realmName">my-realm</attribute>
>>>>>> <reference name="ServerInfo">
>>>>>> <name>ServerInfo</name>
>>>>>> </reference>
>>>>>> <reference name="LoginService">
>>>>>> <name>JaasLoginService</name>
>>>>>> </reference>
>>>>>> <xml-reference name="LoginModuleConfiguration">
>>>>>> <login-config xmlns="http://geronimo.apache.org/xml/ns/
>>>>>> loginconfig-1.1">
>>>>>> <login-module control-flag="REQUIRED" server-side="true"
>>>>>> wrap-principals="true">
>>>>>> <login-domain-name>my-realm</login-domain-name>
>>>>>> <login-module-class>com.my.subject.MyLoginModule</login- module-
>>>>>> class>
>>>>>> </login-module>
>>>>>> </login-config>
>>>>>> </xml-reference>
>>>>>> </gbean>
>>>>>>
>>>>>> This declares a security realm usable by all of the WARs in
>>>>>> myappA.ear.
>>>>>>
>>>>>> There are two implementations of the backend security information
>>>>>> store.
>>>>>>
>>>>>> SecurityInformationStoreA is a file, similar to the geronimo sample
>>>>>> users.properties and roles.properties.
>>>>>> SecurityInformationStoreB is the security model of "myappB.ear",
>>>>>> accessed
>>>>>> through an local (to geronimo instance) EJB, called
>>>>>> MySecurityServicesB.
>>>>>>
>>>>>> The security information store used is controlled at run time
>>>>>> though
>>>>>> an
>>>>>> external configuration file.
>>>>>>
>>>>>> When myappA is deployed with myappB, myappA should use
>>>>>> SecurityInformationStoreB. When myappA is deployed alone, it
>>>>>> should
>>>>>> use
>>>>>> SecurityInformationStoreA.
>>>>>>
>>>>>> From your response, I gather that the XML above needs to include a
>>>>>> reference
>>>>>> to the SecurityInformationStoreB EJB. Using a reference rather
>>>>>> than a
>>>>>> dependency will allow myappA to deploy, even if myappB is not
>>>>>> present.
>>>>>>
>>>>>> The suggestion below is an "ejb-ref" element. It is possible that
>>>>>> one
>>>>>> of
>>>>>> these needs to go somewhere else in geronimo-application.xml.
>>>>>>
>>>>>> To tie this back in to the original post, myappB makes use of
>>>>>> myappA
>>>>>> EJBs.
>>>>>> myappB gracefully handles the absence of myappA by returning
>>>>>> "nothing".
>>>>>> myappA handles the absence of myappB by using the alternative
>>>>>> security
>>>>>> information store.
>>>>>>
>>>>>> Thank you for any insight you might have into possible solutions
>>>>>> using
>>>>>> Geronimo 1.1.1.
>>>>>>
>>>>>
>>>>> you need to be able to run either app with or without the other app
>>>>> present, right?
>>>>>
>>>>> IIUC there are 2 different situations here.
>>>>> --myappB has j2ee components (ejbs) accessing ejbs in myappA. You
>>>>> should
>>>>> be able to make this work with the ejb-ref xml I showed before in
>>>>> myappB's geronimo plan.
>>>>> --a login module deployed with myappA needs to be able to access
>>>>> ejbs
>>>>> in
>>>>> myappB. This is harder. A login module is not a j2ee component,
>>>>> so
>>>>> it
>>>>> doesn't have the java:comp/env jndi environment available to it, and
>>>>> there is no spec compliant standard way to access a local ejb from a
>>>>> non-j2ee-component, so you will need some geronimo specific code.
>>>>> The
>>>>> easiest way is to use the ejb Reference object we use in jndi,
>>>>> yourself.
>>>>>
>>>>>
>>>>> Your login module will need to use the geronimo Kernel. It can
>>>>> obtain
>>>>> this from the options by looking up the key
>>>>> "org.apache.geronimo.security.realm.GenericSecurityRealm.KERNEL". I
>>>>> 'd
>>>>> suggest passing in the name of the ejb it's trying to use as another
>>>>> option. This would be the geronimo AbstractName of the ejb
>>>>> container
>>>>> gbean. It also needs the moduleId of the app it's in.
>>>>>
>>>>> public void initialize(Subject subject, CallbackHandler
>>>>> callbackHandler, Map sharedState, Map options) {
>>>>> Kernel kernel = (Kernel) options.get
>>>>> ("org.apache.geronimo.security.realm.GenericSecurityRealm.KERNEL");
>>>>> String ejbNameString = (String) options.get
>>>>> ("com.myco.SecurityEjbAbstractName");
>>>>> AbstractNameQuery ejbNameQuery = new AbstractNameQuery
>>>>> (URI.create(ejbNameString));
>>>>> String moduleIdString = (String) options.get
>>>>> ("com.myco.security.ModuleId");
>>>>> Artifact moduleId = Artifact.create(moduleIdString);
>>>>>
>>>>> EjbReference ref = new EjbReference(moduleId, ejbNameQuery,
>>>>> false);
>>>>> ref.setKernel(kernel);
>>>>> EjbBLocalHome home = (EjbBLocalHome) ref.getContent();
>>>>> ...
>>>>>
>>>>> }
>>>>>
>>>>> So this uses options
>>>>> org.apache.geronimo.security.realm.GenericSecurityRealm.KERNEL which
>>>>> you
>>>>> don't have to set (geronimo sets it by itself),
>>>>> com.myco.SecurityEjbAbstractName (something that uniquely identifies
>>>>> the
>>>>> ejb target. If nothing in your app has a similar name, "?
>>>>> name=EjbB#"
>>>>> should work)
>>>>> com.myco.security.ModuleId (the moduleId specified in the geronimo
>>>>> plan
>>>>> for moduleA, as a string like groupId/artifactId/version/type)
>>>>>
>>>>> The last 2 need to be set in the xml login configuration.
>>>>>
>>>>> if you unwind the code the EjbReference uses you can eliminate the
>>>>> moduleId. To compile this you'll need at least the geronimo- kernel,
>>>>> geronimo-naming, and openejb-core jars in your classpath. If you
>>>>> copy
>>>>> appropriate bits of the code you can eliminate geronmo-naming.
>>>>>
>>>>> hope this helps
>>>>> david jencks
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>> "David Jencks" <da...@yahoo.com>
>>>>>> wrote
>>>>>> in message
>>>>>> news:58AB7426-2670-4DF0-9A96-7EF0B299E65D@yahoo.com...
>>>>>>>
>>>>>>> On Feb 22, 2007, at 3:06 PM, pgrey wrote:
>>>>>>>
>>>>>>>> Yes, we have run into a problem.
>>>>>>>>
>>>>>>>> The EJBs are in different EARs.
>>>>>>>>
>>>>>>>>> If you ejbs are in different ears, things get a bit trickier.
>>>>>>>>> IIRC
>>>>>>>>> you
>>>>>>>>> have to supply the entire abstract name of the ejb container
>>>>>>>>> gbean
>>>>>>>>> for
>>>>>>>>> at least one side of the relationship.
>>>>>>>>
>>>>>>>> Can you give an example of "supply the entire abstract name of
>>>>>>>> the
>>>>>>>> ejb
>>>>>>>> container gbean"?
>>>>>>>
>>>>>>> This would go in your geronimo plan, I think its the correct
>>>>>>> syntax
>>>>>>> for
>>>>>>> g. 1.1 and 1.2.
>>>>>>>
>>>>>>> Lets say your looking for the bar ejb in (geronimo) module
>>>>>>> com.myco/
>>>>>>> app1/1.0/car in the ejb1.jar (j2ee) module
>>>>>>>
>>>>>>> <ejb-ref>
>>>>>>> <ref-name>foo</ref-name>
>>>>>>> <pattern>
>>>>>>> <groupId>com.myco</groupId>
>>>>>>> <artifactId>app1</artifactId>
>>>>>>> <version>1.0</version>
>>>>>>> <type>car</type>
>>>>>>> <module>ejb1.jar</module>
>>>>>>> <name>bar</name>
>>>>>>> </pattern>
>>>>>>> </ejb-ref>
>>>>>>>
>>>>>>> You can probably leave out the version, and possibly the type and
>>>>>>> module.
>>>>>>>
>>>>>>> thanks
>>>>>>> david jencks
>>>>>>>
>>>>>>>>
>>>>>>>> Thank you kindly.
>>>>>>>>
>>>>>>>>
>>>>>>>> "David Jencks"
>>>>>>>> <da...@yahoo.com>
>>>>>>>> wrote
>>>>>>>> in message
>>>>>>>> news:235FAA12-810B-4CAF-975A-8A66357100A1@yahoo.com...
>>>>>>>>>
>>>>>>>>> On Feb 22, 2007, at 12:24 PM, Spotts, Joel ((ISS Atlanta)) wrote:
>>>>>>>>>
>>>>>>>>>> I have a bit of a predicament with circular refrences in EJBs.
>>>>>>>>>> Due
>>>>>>>>>> to
>>>>>>>>>> legacy reasons, I have two EJBs - each which references the
>>>>>>>>>> other
>>>>>>>>>> (and
>>>>>>>>>> refactoring would be non-trivial). I would prefer to keep them
>>>>>>>>>> local
>>>>>>>>>> (as
>>>>>>>>>> opposed to remote) for security reasons. Trouble is, I don't
>>>>>>>>>> know
>>>>>>>>>> how
>>>>>>>>>> to
>>>>>>>>>> deploy such an arrangement in geronimo. Each EJB will need to
>>>>>>>>>> reference
>>>>>>>>>> the other in openejb- jar.xml with an <ejb-ref> stanza. But
>>>>>>>>>> since
>>>>>>>>>> each
>>>>>>>>>> one is dependent on the other, each one cannot be deployed
>>>>>>>>>> before
>>>>>>>>>> the
>>>>>>>>>> other (as geronimo checks for the ejb reference at deploy
>>>>>>>>>> time).
>>>>>>>>>> Without
>>>>>>>>>> violated some accepted principals of physics, that leads to an
>>>>>>>>>> impossible situation. How could I go about solving this issue?
>>>>>>>>>
>>>>>>>>> This is supposed to work easily, at least if the ejbs are in the
>>>>>>>>> same
>>>>>>>>> ear. Deployment goes in phases: in "initContext" we try to
>>>>>>>>> find
>>>>>>>>> out
>>>>>>>>> and
>>>>>>>>> "publish" all the things you could possibly reference, such as
>>>>>>>>> ejbs
>>>>>>>>> and
>>>>>>>>> datasources. Then in "addGBeans" we process the jndir ref info
>>>>>>>>> and
>>>>>>>>> construct the jndi References to the appropriate stuff. For
>>>>>>>>> ejbs
>>>>>>>>> in
>>>>>>>>> the
>>>>>>>>> same ear, all necessary info should have been "published" and
>>>>>>>>> thus
>>>>>>>>> available.
>>>>>>>>>
>>>>>>>>> If you ejbs are in different ears, things get a bit trickier.
>>>>>>>>> IIRC
>>>>>>>>> you
>>>>>>>>> have to supply the entire abstract name of the ejb container
>>>>>>>>> gbean
>>>>>>>>> for
>>>>>>>>> at least one side of the relationship.
>>>>>>>>>
>>>>>>>>> Are you speculating or have you actually run into a problem :-)?
>>>>>>>>>
>>>>>>>>> thanks
>>>>>>>>> david jencks
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>>
>>>>>>>>>> Yoel Spotts
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>
>