You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by Allan Lykke Christensen <al...@i2m.dk> on 2009/06/18 23:42:28 UTC

Unit testing code containing DirContext resource injection

Hi all,

I've just started using OpenEJB 3.1.1 for unit testing an EJB3 Maven  
project that will be deployed in a GlassFish environment. OpenEJB has  
really simplified unit testing of EJB3s and will be saving me a lot of  
time in the future, however I've run into a problem when testing code  
using LDAP connections.

Problem:  In one of my stateless bean I'm injecting an LDAP connection  
(DirContext) that is registered with a JNDI name in GlassFish:

@Resource(name = "ldap/userDirectory")
private DirContext ldapConn;

Whenever I run a unit test with the above code I get the following  
error:

WARN - Jar not loaded. classpath.ear.  No provider available for  
resource-ref 'null' of type 'javax.naming.directory.DirContext' for  
'UserServiceBean'.
org.apache.openejb.OpenEJBException: No provider available for  
resource-ref 'null' of type 'javax.naming.directory.DirContext' for  
'UserServiceBean'.
         at  
org 
.apache.openejb.config.AutoConfig.autoCreateResource(AutoConfig.java: 
1342)
         at  
org.apache.openejb.config.AutoConfig.getResourceId(AutoConfig.java:1335)
         at  
org.apache.openejb.config.AutoConfig.getResourceId(AutoConfig.java:1286)
         at  
org 
.apache.openejb.config.AutoConfig.processResourceRef(AutoConfig.java: 
799)
         at  
org.apache.openejb.config.AutoConfig.deploy(AutoConfig.java:724)
         at  
org.apache.openejb.config.AutoConfig.deploy(AutoConfig.java:133)
         at org.apache.openejb.config.ConfigurationFactory 
$Chain.deploy(ConfigurationFactory.java:247)
         at  
org 
.apache 
.openejb 
.config 
.ConfigurationFactory.configureApplication(ConfigurationFactory.java: 
601)
         at  
org 
.apache 
.openejb 
.config 
.ConfigurationFactory.configureApplication(ConfigurationFactory.java: 
551)
         at  
org 
.apache 
.openejb 
.config 
.ConfigurationFactory 
.getOpenEjbConfiguration(ConfigurationFactory.java:380)
         at  
org 
.apache 
.openejb 
.assembler.classic.Assembler.getOpenEjbConfiguration(Assembler.java:292)
         at  
org.apache.openejb.assembler.classic.Assembler.build(Assembler.java:271)
         at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:137)
         at org.apache.openejb.OpenEJB.init(OpenEJB.java:286)
         at org.apache.openejb.OpenEJB.init(OpenEJB.java:265)

I tried looking into ways of injecting the DirContext, but with no luck.

Anybody know how to go about this? Any help is much appreciated.

Thanks,
  Allan


Re: Unit testing code containing DirContext resource injection

Posted by David Blevins <da...@visi.com>.
On Aug 5, 2009, at 2:52 PM, Camilo Rivera wrote:

>
>
>
> David Blevins wrote:
>>
>>
>> On Jul 14, 2009, at 1:16 PM, Allan Lykke Christensen wrote:
>>
>>> Thanks for your response.  I realised that I was trying to over-
>>> engineer my code by having dynamic binding and look-up of objects
>>> using JNDI. It was not needed for the purpose of my application.
>>> Instead I've gone back to using a Resource Adapter for connecting to
>>> a Java Content Repository (JCR). Specifically, I'm using the
>>> Jackrabbit Content Repository. A JCA component was already provided
>>> (although a pain to install on Mac because of filename case issues)
>>> and I've managed to install it on GlassFish. This got me back to my
>>> original test case. Using the Resource Adapter (JCA 1.0), requires
>>> me to set-up a a Connector connection pool and resource which I
>>> bound to a JNDI name. The repository would then be available using
>>> the following DI:
>>>
>>> @Resource(mappedName="jcr/repository",
>>> type=javax.jcr.Repository.class) private Repository rep;
>>>
>>> But how do I tell OpenEJB about the resource so that I can add my
>>> own dummy repository before running my tests? Is it possible?
>>
>> Sure, you can plug in any J2EE compliant Resource Adapter.  The
>> process for doing that in a Maven test environment is as a described
>> an email or two back.
>>
>> As described in that other email, Maven will not add rar files
>> (Resource Adapter aRchives) to the classpath for some very stubborn
>> reason, so you have to sort of unwrap it by creating a module with  
>> the
>> same dependencies as the rar file and with the ra.xml file from the
>> rar extracted to src/resources/META-INF/ra.xml.  Fortunately
>> Jackrabbit uses maven and everything is up in maven repositories, so
>> the setup is much easier.  This worked for me:
>>
>>   jackrabbit-rar
>>   jackrabbit-rar/pom.xml
>>   jackrabbit-rar/src
>>   jackrabbit-rar/src/main
>>   jackrabbit-rar/src/main/resources
>>   jackrabbit-rar/src/main/resources/META-INF
>>   jackrabbit-rar/src/main/resources/META-INF/ra.xml
>>
>>   --pom.xml-------------
>>   <?xml version="1.0" encoding="UTF-8"?>
>>   <project xmlns="http://maven.apache.org/POM/4.0.0"
>>     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
>>     http://maven.apache.org/maven-v4_0_0.xsd">
>>
>>     <groupId>your.package</groupId>
>>     <artifactId>jackrabbit-rar</artifactId>
>>     <version>1.0-SNAPSHOT</version>
>>     <modelVersion>4.0.0</modelVersion>
>>     <packaging>jar</packaging>
>>     <name>Jackrabbit Resource Adapter</name>
>>
>>     <dependencies>
>>       <dependency>
>>         <groupId>org.apache.jackrabbit</groupId>
>>         <artifactId>jackrabbit-jca</artifactId>
>>         <version>1.5.6</version>
>>       </dependency>
>>       <dependency>
>>         <groupId>javax.jcr</groupId>
>>         <artifactId>jcr</artifactId>
>>         <version>1.0</version>
>>       </dependency>
>>     </dependencies>
>>   </project>
>>   ----------------------
>>
>> Adjust the <groupId> from "your.package" to whatever groupId you use
>> for your own modules.  Change the jackrabbit version to whatever you
>> are using.  Also remember the ra.xml file needs to be extracted from
>> the jackrabbit-jca.rar file.
>>
>> Then you should add the "<module>jackrabbit-rar</module>" to your
>> parent pom.  Anywhere that needs to use the Jackrabbit Resource
>> Adapter just needs to declare a maven dependency on it like so:
>>
>>     <dependency>
>>       <groupId>your.package</groupId>
>>       <artifactId>jackrabbit-rar</artifactId>
>>       <version>1.0-SNAPSHOT</version>
>>       <scope>provided</provided>
>>     </dependency>
>>
>> Once that is declared in your modules that use the Jackrabbit  
>> Resource
>> Adapter, all the injection points should work.  You should see some
>> log lines like the following that indicate the Resource Adapter (aka
>> Connector) is being found and deployed:
>>
>>   INFO - Found ConnectorModule in classpath: /Users/dblevins/work/
>> openejb3/examples/ear-testing/jackrabbit-rar/target/jackrabbit- 
>> rar-1.0-
>> SNAPSHOT.jar
>>   ...
>>   INFO - Beginning load: /Users/dblevins/work/openejb3/examples/ear-
>> testing/jackrabbit-rar/target/jackrabbit-rar-1.0-SNAPSHOT.jar
>>   ...
>>   INFO - Configuring Service(id=jackrabbit-rar-1.0-SNAPSHOT.jarRA,
>> type=Resource, provider-id=jackrabbit-rar-1.0-SNAPSHOT.jarRA)
>>   INFO - Configuring Service(id=jackrabbit-rar-1.0-SNAPSHOT.jar,
>> type=Resource, provider-id=jackrabbit-rar-1.0-SNAPSHOT.jar)
>>   ...
>>   INFO - Enterprise application "classpath.ear" loaded.
>>
>> I gave the above setup a try and it did deploy for me.  I don't know
>> what it takes to configure and use Jackrabbit itself, but this will
>> get you past the Maven limitation and allow OpenEJB to see and deploy
>> the rar like it would any compliant Resource Adapter.
>>
>> Hope this helps!
>>
>> -David
>>
>>
>>
>
>
> Hello David,
>
> I have followed your instructions and it worked great.  
> Unfortunately, I
> haven't been able to find a way to expose jackrabbit as a JNDI  
> resource.
> This was possible in JBoss by defining a *-ds file like the following:
>
> <connection-factories>
> 	<tx-connection-factory>
> 		<jndi-name>jcr/local</jndi-name>
> 		<xa-transaction/>
> 		<rar-name>etask-jackrabbit-jca.rar</rar-name>
> 		<connection-definition>javax.jcr.Repository</connection-definition>
> 		<config-property name="homeDir"
> type="java.lang.String">C:/path/to/repository</config-property>
> 		<config-property name="configFile"
> type="java.lang.String">classpath:repository.xml</config-property>
> 		<config-property name="bindSessionToTransaction"
> type="java.lang.Boolean">true</config-property>
> 	</tx-connection-factory>
> </connection-factories>
>
> I didn't find any documentation as to the way to deploy such a  
> resource (the
> repository). Do you know of any site where I can find this?

Once the Resource Adapter is deployed you should be able to use any of  
these techniques to get a reference to any object that the Resource  
Adapter can create.

   http://openejb.apache.org/3.0/resource-ref-for-datasource.html

This doc shows DataSource, but the @Resource annotation can be used to  
get references of Resource Adapter created objects put into JNDI for  
lookup and optionally for injection.

Hope that was the answer you were looking for.  Let me know if that  
doesn't do the trick.

-David


Re: Unit testing code containing DirContext resource injection

Posted by Camilo Rivera <ka...@hotmail.com>.


David Blevins wrote:
> 
> 
> On Jul 14, 2009, at 1:16 PM, Allan Lykke Christensen wrote:
> 
>> Thanks for your response.  I realised that I was trying to over- 
>> engineer my code by having dynamic binding and look-up of objects  
>> using JNDI. It was not needed for the purpose of my application.  
>> Instead I've gone back to using a Resource Adapter for connecting to  
>> a Java Content Repository (JCR). Specifically, I'm using the  
>> Jackrabbit Content Repository. A JCA component was already provided  
>> (although a pain to install on Mac because of filename case issues)  
>> and I've managed to install it on GlassFish. This got me back to my  
>> original test case. Using the Resource Adapter (JCA 1.0), requires  
>> me to set-up a a Connector connection pool and resource which I  
>> bound to a JNDI name. The repository would then be available using  
>> the following DI:
>>
>> @Resource(mappedName="jcr/repository",  
>> type=javax.jcr.Repository.class) private Repository rep;
>>
>> But how do I tell OpenEJB about the resource so that I can add my  
>> own dummy repository before running my tests? Is it possible?
> 
> Sure, you can plug in any J2EE compliant Resource Adapter.  The  
> process for doing that in a Maven test environment is as a described  
> an email or two back.
> 
> As described in that other email, Maven will not add rar files  
> (Resource Adapter aRchives) to the classpath for some very stubborn  
> reason, so you have to sort of unwrap it by creating a module with the  
> same dependencies as the rar file and with the ra.xml file from the  
> rar extracted to src/resources/META-INF/ra.xml.  Fortunately  
> Jackrabbit uses maven and everything is up in maven repositories, so  
> the setup is much easier.  This worked for me:
> 
>    jackrabbit-rar
>    jackrabbit-rar/pom.xml
>    jackrabbit-rar/src
>    jackrabbit-rar/src/main
>    jackrabbit-rar/src/main/resources
>    jackrabbit-rar/src/main/resources/META-INF
>    jackrabbit-rar/src/main/resources/META-INF/ra.xml
> 
>    --pom.xml-------------
>    <?xml version="1.0" encoding="UTF-8"?>
>    <project xmlns="http://maven.apache.org/POM/4.0.0"
>      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
>      http://maven.apache.org/maven-v4_0_0.xsd">
> 
>      <groupId>your.package</groupId>
>      <artifactId>jackrabbit-rar</artifactId>
>      <version>1.0-SNAPSHOT</version>
>      <modelVersion>4.0.0</modelVersion>
>      <packaging>jar</packaging>
>      <name>Jackrabbit Resource Adapter</name>
> 
>      <dependencies>
>        <dependency>
>          <groupId>org.apache.jackrabbit</groupId>
>          <artifactId>jackrabbit-jca</artifactId>
>          <version>1.5.6</version>
>        </dependency>
>        <dependency>
>          <groupId>javax.jcr</groupId>
>          <artifactId>jcr</artifactId>
>          <version>1.0</version>
>        </dependency>
>      </dependencies>
>    </project>
>    ----------------------
> 
> Adjust the <groupId> from "your.package" to whatever groupId you use  
> for your own modules.  Change the jackrabbit version to whatever you  
> are using.  Also remember the ra.xml file needs to be extracted from  
> the jackrabbit-jca.rar file.
> 
> Then you should add the "<module>jackrabbit-rar</module>" to your  
> parent pom.  Anywhere that needs to use the Jackrabbit Resource  
> Adapter just needs to declare a maven dependency on it like so:
> 
>      <dependency>
>        <groupId>your.package</groupId>
>        <artifactId>jackrabbit-rar</artifactId>
>        <version>1.0-SNAPSHOT</version>
>        <scope>provided</provided>
>      </dependency>
> 
> Once that is declared in your modules that use the Jackrabbit Resource  
> Adapter, all the injection points should work.  You should see some  
> log lines like the following that indicate the Resource Adapter (aka  
> Connector) is being found and deployed:
> 
>    INFO - Found ConnectorModule in classpath: /Users/dblevins/work/ 
> openejb3/examples/ear-testing/jackrabbit-rar/target/jackrabbit-rar-1.0- 
> SNAPSHOT.jar
>    ...
>    INFO - Beginning load: /Users/dblevins/work/openejb3/examples/ear- 
> testing/jackrabbit-rar/target/jackrabbit-rar-1.0-SNAPSHOT.jar
>    ...
>    INFO - Configuring Service(id=jackrabbit-rar-1.0-SNAPSHOT.jarRA,  
> type=Resource, provider-id=jackrabbit-rar-1.0-SNAPSHOT.jarRA)
>    INFO - Configuring Service(id=jackrabbit-rar-1.0-SNAPSHOT.jar,  
> type=Resource, provider-id=jackrabbit-rar-1.0-SNAPSHOT.jar)
>    ...
>    INFO - Enterprise application "classpath.ear" loaded.
> 
> I gave the above setup a try and it did deploy for me.  I don't know  
> what it takes to configure and use Jackrabbit itself, but this will  
> get you past the Maven limitation and allow OpenEJB to see and deploy  
> the rar like it would any compliant Resource Adapter.
> 
> Hope this helps!
> 
> -David
> 
> 
> 


Hello David,

I have followed your instructions and it worked great. Unfortunately, I
haven't been able to find a way to expose jackrabbit as a JNDI resource.
This was possible in JBoss by defining a *-ds file like the following:

<connection-factories> 
	<tx-connection-factory>
		<jndi-name>jcr/local</jndi-name> 
		<xa-transaction/>
		<rar-name>etask-jackrabbit-jca.rar</rar-name>
		<connection-definition>javax.jcr.Repository</connection-definition>
		<config-property name="homeDir"
type="java.lang.String">C:/path/to/repository</config-property>
		<config-property name="configFile"
type="java.lang.String">classpath:repository.xml</config-property>
		<config-property name="bindSessionToTransaction"
type="java.lang.Boolean">true</config-property>
	</tx-connection-factory>
</connection-factories>

I didn't find any documentation as to the way to deploy such a resource (the
repository). Do you know of any site where I can find this?

Regards,

Camilo.
-- 
View this message in context: http://www.nabble.com/Unit-testing-code-containing-DirContext-resource-injection-tp24101774p24836874.html
Sent from the OpenEJB User mailing list archive at Nabble.com.


Re: Unit testing code containing DirContext resource injection

Posted by David Blevins <da...@visi.com>.
On Jul 14, 2009, at 1:16 PM, Allan Lykke Christensen wrote:

> Thanks for your response.  I realised that I was trying to over- 
> engineer my code by having dynamic binding and look-up of objects  
> using JNDI. It was not needed for the purpose of my application.  
> Instead I've gone back to using a Resource Adapter for connecting to  
> a Java Content Repository (JCR). Specifically, I'm using the  
> Jackrabbit Content Repository. A JCA component was already provided  
> (although a pain to install on Mac because of filename case issues)  
> and I've managed to install it on GlassFish. This got me back to my  
> original test case. Using the Resource Adapter (JCA 1.0), requires  
> me to set-up a a Connector connection pool and resource which I  
> bound to a JNDI name. The repository would then be available using  
> the following DI:
>
> @Resource(mappedName="jcr/repository",  
> type=javax.jcr.Repository.class) private Repository rep;
>
> But how do I tell OpenEJB about the resource so that I can add my  
> own dummy repository before running my tests? Is it possible?

Sure, you can plug in any J2EE compliant Resource Adapter.  The  
process for doing that in a Maven test environment is as a described  
an email or two back.

As described in that other email, Maven will not add rar files  
(Resource Adapter aRchives) to the classpath for some very stubborn  
reason, so you have to sort of unwrap it by creating a module with the  
same dependencies as the rar file and with the ra.xml file from the  
rar extracted to src/resources/META-INF/ra.xml.  Fortunately  
Jackrabbit uses maven and everything is up in maven repositories, so  
the setup is much easier.  This worked for me:

   jackrabbit-rar
   jackrabbit-rar/pom.xml
   jackrabbit-rar/src
   jackrabbit-rar/src/main
   jackrabbit-rar/src/main/resources
   jackrabbit-rar/src/main/resources/META-INF
   jackrabbit-rar/src/main/resources/META-INF/ra.xml

   --pom.xml-------------
   <?xml version="1.0" encoding="UTF-8"?>
   <project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
     http://maven.apache.org/maven-v4_0_0.xsd">

     <groupId>your.package</groupId>
     <artifactId>jackrabbit-rar</artifactId>
     <version>1.0-SNAPSHOT</version>
     <modelVersion>4.0.0</modelVersion>
     <packaging>jar</packaging>
     <name>Jackrabbit Resource Adapter</name>

     <dependencies>
       <dependency>
         <groupId>org.apache.jackrabbit</groupId>
         <artifactId>jackrabbit-jca</artifactId>
         <version>1.5.6</version>
       </dependency>
       <dependency>
         <groupId>javax.jcr</groupId>
         <artifactId>jcr</artifactId>
         <version>1.0</version>
       </dependency>
     </dependencies>
   </project>
   ----------------------

Adjust the <groupId> from "your.package" to whatever groupId you use  
for your own modules.  Change the jackrabbit version to whatever you  
are using.  Also remember the ra.xml file needs to be extracted from  
the jackrabbit-jca.rar file.

Then you should add the "<module>jackrabbit-rar</module>" to your  
parent pom.  Anywhere that needs to use the Jackrabbit Resource  
Adapter just needs to declare a maven dependency on it like so:

     <dependency>
       <groupId>your.package</groupId>
       <artifactId>jackrabbit-rar</artifactId>
       <version>1.0-SNAPSHOT</version>
       <scope>provided</provided>
     </dependency>

Once that is declared in your modules that use the Jackrabbit Resource  
Adapter, all the injection points should work.  You should see some  
log lines like the following that indicate the Resource Adapter (aka  
Connector) is being found and deployed:

   INFO - Found ConnectorModule in classpath: /Users/dblevins/work/ 
openejb3/examples/ear-testing/jackrabbit-rar/target/jackrabbit-rar-1.0- 
SNAPSHOT.jar
   ...
   INFO - Beginning load: /Users/dblevins/work/openejb3/examples/ear- 
testing/jackrabbit-rar/target/jackrabbit-rar-1.0-SNAPSHOT.jar
   ...
   INFO - Configuring Service(id=jackrabbit-rar-1.0-SNAPSHOT.jarRA,  
type=Resource, provider-id=jackrabbit-rar-1.0-SNAPSHOT.jarRA)
   INFO - Configuring Service(id=jackrabbit-rar-1.0-SNAPSHOT.jar,  
type=Resource, provider-id=jackrabbit-rar-1.0-SNAPSHOT.jar)
   ...
   INFO - Enterprise application "classpath.ear" loaded.

I gave the above setup a try and it did deploy for me.  I don't know  
what it takes to configure and use Jackrabbit itself, but this will  
get you past the Maven limitation and allow OpenEJB to see and deploy  
the rar like it would any compliant Resource Adapter.

Hope this helps!

-David


Re: Unit testing code containing DirContext resource injection

Posted by Allan Lykke Christensen <al...@i2m.dk>.
Hi David,

Thanks for your response.  I realised that I was trying to over- 
engineer my code by having dynamic binding and look-up of objects  
using JNDI. It was not needed for the purpose of my application.  
Instead I've gone back to using a Resource Adapter for connecting to a  
Java Content Repository (JCR). Specifically, I'm using the Jackrabbit  
Content Repository. A JCA component was already provided (although a  
pain to install on Mac because of filename case issues) and I've  
managed to install it on GlassFish. This got me back to my original  
test case. Using the Resource Adapter (JCA 1.0), requires me to set-up  
a a Connector connection pool and resource which I bound to a JNDI  
name. The repository would then be available using the following DI:

@Resource(mappedName="jcr/repository",  
type=javax.jcr.Repository.class) private Repository rep;

But how do I tell OpenEJB about the resource so that I can add my own  
dummy repository before running my tests? Is it possible?

Thanks,
  Allan

On 14/07/2009, at 01.15, David Blevins wrote:

>
> On Jul 9, 2009, at 12:41 AM, Allan Lykke Christensen wrote:
>
>> public ContentService getRepository(String jndiName) throws  
>> NamingException {
>>       Context ctx = new InitialContext();
>>       ContentService cs = (ContentService) ctx.lookup(jndiName);
>>       return cs;
>> }
>>
>>
>> In my unit test I  bind some "ContentService" objects to the  
>> InitialContext
>>
>> @Test
>> public void testGetRepository() {
>>   Properties p = new Properties();
>>   p.setProperty(Context.INITIAL_CONTEXT_FACTORY,  
>> "org.apache.openejb.client.LocalInitialContextFactory");
>>   InitialContext initialContext = new InitialContext(p);
>>   initialContext.bind("cs/MyObject", new ContentService("Something  
>> something"));
>>
>>   ContentFacadeLocal bean = (ContentFacadeLocal)  
>> getInitialContext().lookup(BEAN_INTERFACE);
>>   try {
>>       ContentService cs = bean.getRepository("cs/MyObject");
>>       assertNotNull(cs);
>>   } catch (NamingException ex) {
>>       fail(ex.getMessage());
>>   }
>> }
>>
>> When I run the test a NamingException is thrown with the message  
>> "javax.naming.NoInitialContextException: Need to specify class name  
>> in environment or system property, or as an applet parameter, or in  
>> an application resource file:  java.naming.factory.initial"
>
> Hi Allen,
>
> Hmm.. I'm not sure I know how to advise.  Binding things into JNDI  
> and looking them up inside beans is definitely non-compliant and not  
> portable.  It can be done in OpenEJB with certain limitations, but I  
> wouldn't go there as my first choice.  How exactly do you setup and  
> use this ContentService in your application when run outside  
> OpenEJB?  Who normally creates these ContentService objects?
>
> In terms of simplicity, not having things injected and instead  
> looking them up doesn't really change anything from a setup  
> perspective.  Injection is really just syntactic sugar over JNDI, a  
> JNDI lookup is still done under the covers in exactly the same way  
> as if you were to look it up in the bean.
>
> Looking forward to your feedback.
>
> -David
>


Re: Unit testing code containing DirContext resource injection

Posted by David Blevins <da...@visi.com>.
On Jul 9, 2009, at 12:41 AM, Allan Lykke Christensen wrote:

> public ContentService getRepository(String jndiName) throws  
> NamingException {
>        Context ctx = new InitialContext();
>        ContentService cs = (ContentService) ctx.lookup(jndiName);
>        return cs;
> }
>
>
> In my unit test I  bind some "ContentService" objects to the  
> InitialContext
>
> @Test
> public void testGetRepository() {
>    Properties p = new Properties();
>    p.setProperty(Context.INITIAL_CONTEXT_FACTORY,  
> "org.apache.openejb.client.LocalInitialContextFactory");
>    InitialContext initialContext = new InitialContext(p);
>    initialContext.bind("cs/MyObject", new ContentService("Something  
> something"));
>
>    ContentFacadeLocal bean = (ContentFacadeLocal)  
> getInitialContext().lookup(BEAN_INTERFACE);
>    try {
>        ContentService cs = bean.getRepository("cs/MyObject");
>        assertNotNull(cs);
>    } catch (NamingException ex) {
>        fail(ex.getMessage());
>    }
> }
>
> When I run the test a NamingException is thrown with the message  
> "javax.naming.NoInitialContextException: Need to specify class name  
> in environment or system property, or as an applet parameter, or in  
> an application resource file:  java.naming.factory.initial"

Hi Allen,

Hmm.. I'm not sure I know how to advise.  Binding things into JNDI and  
looking them up inside beans is definitely non-compliant and not  
portable.  It can be done in OpenEJB with certain limitations, but I  
wouldn't go there as my first choice.  How exactly do you setup and  
use this ContentService in your application when run outside OpenEJB?   
Who normally creates these ContentService objects?

In terms of simplicity, not having things injected and instead looking  
them up doesn't really change anything from a setup perspective.   
Injection is really just syntactic sugar over JNDI, a JNDI lookup is  
still done under the covers in exactly the same way as if you were to  
look it up in the bean.

Looking forward to your feedback.

-David


Re: Unit testing code containing DirContext resource injection

Posted by Allan Lykke Christensen <al...@i2m.dk>.
Thanks for the tips David. It has taken me ages getting back to the  
code where I was using OpenEJB for testing, hence the late response.

In terms of LDAP, I figured that there was no need to inject it via  
JNDI. DirContext is already connection pooled by default and adding it  
to the JNDI registry wouldn't really serve any purpose.

However, the RAR technique will come in handy as I'm trying to use the  
JackRabbit Content Repository Service. I've never had to work with RAR  
before, so I'll have to get my head around how it works before  
bothering you more.

I still got an issue relating to what I was doing initially with  
LDAP.   I've got some objects that are added to the JNDI registry at  
run-time. Hence,  I don't know their JNDI names at compile-time. I've  
got the following code in one of my EJBs to look up the objects:


public ContentService getRepository(String jndiName) throws  
NamingException {
         Context ctx = new InitialContext();
         ContentService cs = (ContentService) ctx.lookup(jndiName);
         return cs;
}


In my unit test I  bind some "ContentService" objects to the  
InitialContext

@Test
public void testGetRepository() {
     Properties p = new Properties();
     p.setProperty(Context.INITIAL_CONTEXT_FACTORY,  
"org.apache.openejb.client.LocalInitialContextFactory");
     InitialContext initialContext = new InitialContext(p);
     initialContext.bind("cs/MyObject", new ContentService("Something  
something"));

     ContentFacadeLocal bean = (ContentFacadeLocal)  
getInitialContext().lookup(BEAN_INTERFACE);
     try {
         ContentService cs = bean.getRepository("cs/MyObject");
         assertNotNull(cs);
     } catch (NamingException ex) {
         fail(ex.getMessage());
     }
}

When I run the test a NamingException is thrown with the message  
"javax.naming.NoInitialContextException: Need to specify class name in  
environment or system property, or as an applet parameter, or in an  
application resource file:  java.naming.factory.initial"

While debugging the test I realised that the InitialContext created in  
the bean didn't have the Context.INITIAL_CONTEXT_FACTORY injected.  
Isn't this suppose to happen transparently?

Thanks again for your help! Woking on a series of blog entries focused  
on unit testing where OpenEJB is the cornerstone.

All the best,
  Allan

On 19/06/2009, at 22.58, David Blevins wrote:

>
> On Jun 19, 2009, at 1:53 AM, Allan Lykke Christensen wrote:
>
>> Thanks for your response.
>>
>> I'm starting to think that my LDAP integration is non-standard and  
>> should be done in another way. What you are suggesting is that  
>> there might be a JCA connector for LDAP?  In any case, there is  
>> nothing vendor-specific about my current integration. I'm using a  
>> vendor-neutral LdapConnectionFactory for obtaining a connection  
>> from a connection pool.  Perhaps I should bring the connection code  
>> into my application instead and forget about registering the JNDI  
>> name in GlassFish. Having a bit of difficulty finding the best  
>> practice for my use case as you can probably sense.
>
> If the LDAP support is coming from a JCA connector (which it sounds  
> like it is), then you have a picture perfect setup and I wouldn't  
> change a thing.
>
> To get this to work in OpenEJB/Maven land we just need to deploy  
> your .rar file that is providing the LDAP support.
>
> This is a bit of work to setup as we have to work around Maven --  
> Maven does not like rars.  We essentially need to "unwrap" that rar  
> as Maven is hardwired to ignore rar files and will not included them  
> in the classpath as it doesn't know how to include the jars *inside*  
> the rar in the classpath.
>
> So one basic technique I've used is to sort of convert the rar to a  
> maven module by making a new module named after the rar in some way  
> (any name is fine), copying the ra.xml file to src/main/resources/ 
> META-INF/ra.xml, and declaring maven dependencies on all the jars  
> the rar needs (i.e. the ones you normally find inside the rar file).
>
> The trick is that usually the jars inside the rar are not available  
> in any maven repos so you'll have to install them all into your  
> local repo.  If you're lazy like me, you can just make up groupId  
> and artifactIds for these jars and add them to the pom.xml as if  
> they were already in the repo, then just run a 'mvn clean install'  
> and maven will be kind enough to spit out all the 'install:install- 
> file' commands with the parameters already filled in.
>
> Once you have that "rar replacement module" you can simply depend on  
> it from your ejb module and OpenEJB will find and deploy the rar and  
> all the injection should work fine.
>
> An example exists, but unfortunately we can't include it in our  
> examples zip as it has LGPL'ed code in it which is not allowed for  
> us.  But here's the related email and JIRA issue:
>
> http://www.nabble.com/need-help-getting-quartz-ra.rar-file-to-deploy-tp18531000p18783086.html
> (http//issues.apache.org/jira/secure/attachment/12387373/quartz- 
> app.zip)
>
> Anyway, hope that helps.
>
>> You are welcome regarding the tweet. I'm planning to write a blog  
>> entry about mixing OpenEJB, DBUnit, and Apache Derby for unit  
>> testing in the near future as well.
>
> That's great.  When you do, make sure and ping us and we'll post  
> about your entry in our blog.  You could likely do two posts if you  
> wanted, the one you mention and one about creating a rar module for  
> your LDAP connector.
>
> Let us know if you encounter any trouble.
>
> -David
>
>>
>> On 19/06/2009, at 08.01, David Blevins wrote:
>>> Hi Allen,
>>>
>>> DirContext isn't one of the required java ee types such as  
>>> DataSource or UserTransaction, so I'm guessing that there must be  
>>> some sort of LDAP J2EE Connector for it.  If that's the case it  
>>> should be easy to hook up in OpenEJB as well.  If not then it's a  
>>> vendor specific feature, which we'd be more than happy to support  
>>> as well provided we can get enough information on how it should  
>>> work so we can code it up.
>>>
>>> Let us know.
>>>
>>> -David
>>>
>>> PS Thanks for the tweet!
>>
>>
>


Re: Unit testing code containing DirContext resource injection

Posted by David Blevins <da...@visi.com>.
On Jun 19, 2009, at 1:53 AM, Allan Lykke Christensen wrote:

> Thanks for your response.
>
> I'm starting to think that my LDAP integration is non-standard and  
> should be done in another way. What you are suggesting is that there  
> might be a JCA connector for LDAP?  In any case, there is nothing  
> vendor-specific about my current integration. I'm using a vendor- 
> neutral LdapConnectionFactory for obtaining a connection from a  
> connection pool.  Perhaps I should bring the connection code into my  
> application instead and forget about registering the JNDI name in  
> GlassFish. Having a bit of difficulty finding the best practice for  
> my use case as you can probably sense.

If the LDAP support is coming from a JCA connector (which it sounds  
like it is), then you have a picture perfect setup and I wouldn't  
change a thing.

To get this to work in OpenEJB/Maven land we just need to deploy  
your .rar file that is providing the LDAP support.

This is a bit of work to setup as we have to work around Maven --  
Maven does not like rars.  We essentially need to "unwrap" that rar as  
Maven is hardwired to ignore rar files and will not included them in  
the classpath as it doesn't know how to include the jars *inside* the  
rar in the classpath.

So one basic technique I've used is to sort of convert the rar to a  
maven module by making a new module named after the rar in some way  
(any name is fine), copying the ra.xml file to src/main/resources/META- 
INF/ra.xml, and declaring maven dependencies on all the jars the rar  
needs (i.e. the ones you normally find inside the rar file).

The trick is that usually the jars inside the rar are not available in  
any maven repos so you'll have to install them all into your local  
repo.  If you're lazy like me, you can just make up groupId and  
artifactIds for these jars and add them to the pom.xml as if they were  
already in the repo, then just run a 'mvn clean install' and maven  
will be kind enough to spit out all the 'install:install-file'  
commands with the parameters already filled in.

Once you have that "rar replacement module" you can simply depend on  
it from your ejb module and OpenEJB will find and deploy the rar and  
all the injection should work fine.

An example exists, but unfortunately we can't include it in our  
examples zip as it has LGPL'ed code in it which is not allowed for  
us.  But here's the related email and JIRA issue:

  http://www.nabble.com/need-help-getting-quartz-ra.rar-file-to-deploy-tp18531000p18783086.html
  (http//issues.apache.org/jira/secure/attachment/12387373/quartz- 
app.zip)

Anyway, hope that helps.

> You are welcome regarding the tweet. I'm planning to write a blog  
> entry about mixing OpenEJB, DBUnit, and Apache Derby for unit  
> testing in the near future as well.

That's great.  When you do, make sure and ping us and we'll post about  
your entry in our blog.  You could likely do two posts if you wanted,  
the one you mention and one about creating a rar module for your LDAP  
connector.

Let us know if you encounter any trouble.

-David

>
> On 19/06/2009, at 08.01, David Blevins wrote:
>> Hi Allen,
>>
>> DirContext isn't one of the required java ee types such as  
>> DataSource or UserTransaction, so I'm guessing that there must be  
>> some sort of LDAP J2EE Connector for it.  If that's the case it  
>> should be easy to hook up in OpenEJB as well.  If not then it's a  
>> vendor specific feature, which we'd be more than happy to support  
>> as well provided we can get enough information on how it should  
>> work so we can code it up.
>>
>> Let us know.
>>
>> -David
>>
>> PS Thanks for the tweet!
>
>


Re: Unit testing code containing DirContext resource injection

Posted by Allan Lykke Christensen <al...@i2m.dk>.
Thanks for your response.

I'm starting to think that my LDAP integration is non-standard and  
should be done in another way. What you are suggesting is that there  
might be a JCA connector for LDAP?  In any case, there is nothing  
vendor-specific about my current integration. I'm using a vendor- 
neutral LdapConnectionFactory for obtaining a connection from a  
connection pool.  Perhaps I should bring the connection code into my  
application instead and forget about registering the JNDI name in  
GlassFish. Having a bit of difficulty finding the best practice for my  
use case as you can probably sense.

You are welcome regarding the tweet. I'm planning to write a blog  
entry about mixing OpenEJB, DBUnit, and Apache Derby for unit testing  
in the near future as well.

Nice weekend,
Allan

On 19/06/2009, at 08.01, David Blevins wrote:
> Hi Allen,
>
> DirContext isn't one of the required java ee types such as  
> DataSource or UserTransaction, so I'm guessing that there must be  
> some sort of LDAP J2EE Connector for it.  If that's the case it  
> should be easy to hook up in OpenEJB as well.  If not then it's a  
> vendor specific feature, which we'd be more than happy to support as  
> well provided we can get enough information on how it should work so  
> we can code it up.
>
> Let us know.
>
> -David
>
> PS Thanks for the tweet!


Re: Unit testing code containing DirContext resource injection

Posted by David Blevins <da...@visi.com>.
On Jun 18, 2009, at 2:42 PM, Allan Lykke Christensen wrote:

> Hi all,
>
> I've just started using OpenEJB 3.1.1 for unit testing an EJB3 Maven  
> project that will be deployed in a GlassFish environment. OpenEJB  
> has really simplified unit testing of EJB3s and will be saving me a  
> lot of time in the future, however I've run into a problem when  
> testing code using LDAP connections.
>
> Problem:  In one of my stateless bean I'm injecting an LDAP  
> connection (DirContext) that is registered with a JNDI name in  
> GlassFish:
>
> @Resource(name = "ldap/userDirectory")
> private DirContext ldapConn;
>
> Whenever I run a unit test with the above code I get the following  
> error:
>
> WARN - Jar not loaded. classpath.ear.  No provider available for  
> resource-ref 'null' of type 'javax.naming.directory.DirContext' for  
> 'UserServiceBean'.
> org.apache.openejb.OpenEJBException: No provider available for  
> resource-ref 'null' of type 'javax.naming.directory.DirContext' for  
> 'UserServiceBean'.
>        at  
> org 
> .apache.openejb.config.AutoConfig.autoCreateResource(AutoConfig.java: 
> 1342)
>        at  
> org.apache.openejb.config.AutoConfig.getResourceId(AutoConfig.java: 
> 1335)
>        at  
> org.apache.openejb.config.AutoConfig.getResourceId(AutoConfig.java: 
> 1286)
>        at  
> org 
> .apache.openejb.config.AutoConfig.processResourceRef(AutoConfig.java: 
> 799)
>        at  
> org.apache.openejb.config.AutoConfig.deploy(AutoConfig.java:724)
>        at  
> org.apache.openejb.config.AutoConfig.deploy(AutoConfig.java:133)
>        at org.apache.openejb.config.ConfigurationFactory 
> $Chain.deploy(ConfigurationFactory.java:247)
>        at  
> org 
> .apache 
> .openejb 
> .config 
> .ConfigurationFactory.configureApplication(ConfigurationFactory.java: 
> 601)
>        at  
> org 
> .apache 
> .openejb 
> .config 
> .ConfigurationFactory.configureApplication(ConfigurationFactory.java: 
> 551)
>        at  
> org 
> .apache 
> .openejb 
> .config 
> .ConfigurationFactory 
> .getOpenEjbConfiguration(ConfigurationFactory.java:380)
>        at  
> org 
> .apache 
> .openejb 
> .assembler.classic.Assembler.getOpenEjbConfiguration(Assembler.java: 
> 292)
>        at  
> org.apache.openejb.assembler.classic.Assembler.build(Assembler.java: 
> 271)
>        at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:137)
>        at org.apache.openejb.OpenEJB.init(OpenEJB.java:286)
>        at org.apache.openejb.OpenEJB.init(OpenEJB.java:265)
>
> I tried looking into ways of injecting the DirContext, but with no  
> luck.
>
> Anybody know how to go about this? Any help is much appreciated.

Hi Allen,

DirContext isn't one of the required java ee types such as DataSource  
or UserTransaction, so I'm guessing that there must be some sort of  
LDAP J2EE Connector for it.  If that's the case it should be easy to  
hook up in OpenEJB as well.  If not then it's a vendor specific  
feature, which we'd be more than happy to support as well provided we  
can get enough information on how it should work so we can code it up.

Let us know.

-David

PS Thanks for the tweet!