tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <david.blev...@visi.com>
Subject Re: Help with OpenEJB3 and Spring IoC
Date Fri, 06 Jun 2008 20:58:51 GMT
Hmm.  This one is a bit tricky...  The big question on both our minds  
is likely, what *is* in the classpath?

With maven it's easy to see via adding "-X" as an argument, which will  
set the log level to debug and cause all sorts of information to be  
printed, including the test classpath.  It's a lot of output, so  
you'll have to scan for a while to find it.

Alternatively... we can be a little naughty :)  Here's a chunk of code  
which will pull the classpath out of the classloader and print it.  It  
works on a URLClassLoader which is a superclass of nearly every  
classloader out there.

import java.net.URLClassLoader;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.Field;

public class PrintClasspath {

     public static void printClasspath(URLClassLoader loader) throws  
Exception {
         String name = loader.getClass().getSimpleName() + "@" +  
loader.hashCode();

         for (URL url : getURLs(loader)) {
             System.out.println(name + " = " + url.toExternalForm());
         }
     }

     private static URL[] getURLs(URLClassLoader loader) throws  
Exception {
         return ((sun.misc.URLClassPath)  
getUcpField().get(loader)).getURLs();
     }

     private static Field getUcpField() throws Exception {
         return (Field) AccessController.doPrivileged(new  
PrivilegedAction() {
             public Object run() {
                 try {
                     Field ucp =  
URLClassLoader.class.getDeclaredField("ucp");
                     ucp.setAccessible(true);
                     return ucp;
                 } catch (Exception e) {
                     throw new RuntimeException(e);
                 }
             }
         });
     }
}

Use this in your TestCase to get a clean and short printout of the  
test classpath and again inside the bean factory.

The second thing I notice is that your TestCase is inheriting from  
org.springframework.test.jpa.AbstractJpaTests, which makes me realize  
your spring factory bean is likely to get executed before your test's  
setUp() method.  We should probably revise things so OpenEJB  
initializes via your spring xml file as well.

The revised factories might look like this:

     public class OpenEjbFactoryBean implements  
org.springframework.beans.factory.FactoryBean {

         private Properties properties = new Properties();

         public OpenEjbFactoryBean() {
             properties.put(Context.INITIAL_CONTEXT_FACTORY,  
"org.apache.openejb.client.LocalInitialContextFactory");
         }

         public Properties getJndiEnvironment() {
             return properties;
         }

         public void setJndiEnvironment(Properties properties) {
             this.properties.putAll(properties);
         }

         public Object getObject() {
             try {
                 return new InitialContext(properties);
             } catch (NamingException e) {
                 throw new RuntimeException(e);
             }
         }

         public Class getObjectType(){
             return Context.class;
         }

         boolean isSingleton() {
             return true;
         }
     }


     public class EntityManagerFactoryBean implements  
org.springframework.beans.factory.FactoryBean {
         private Context context;

         public Context getContext() {
             return context;
         }

         public void setContext(Context context) {
             this.context = context;
         }

         public Object getObject() {
             try {
                 ResourceLocal bean = (ResourceLocal)  
context.lookup("ResourceBeanLocal");
                 return bean.getEntityManager();
             } catch (NamingException e) {
                 throw new RuntimeException(e);
             }
         }

         public Class getObjectType(){
             return EntityManager.class;
         }

         boolean isSingleton() {
             return true;
         }
     }

   <bean id="OpenEjbContext" class="org.acme.OpenEjbFactoryBean">
     <property name="jndiEnvironment">
       <props>
         <prop key="myDs">new://Resource?type=DataSource</prop>
         <prop key="myDs.JdbcDriver">com.mysql.jdbc.Driver</prop>
         <prop key="myDs.JdbcUrl">jdbc:mysql://localhost/midastest? 
createDatabaseIfNotExist 
=true&amp;useUnicode=true&amp;characterEncoding=utf-8</prop>
         <prop key="myDs.UserName">root</prop>
         <prop key="myDs.Password"></prop>
       </props>
     </property>
   </bean>

   <bean id="ApplicationEntityManager"  
class="org.acme.EntityManagerFactoryBean">
     <property name="context" ref="OpenEjbContext">
   </bean>


Hope this helps, and thanks for posting.  This will make a great doc  
when we are done!

-David




Mime
View raw message