db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig L Russell <Craig.Russ...@Sun.COM>
Subject Re: classloader for JDO classes
Date Wed, 11 Jan 2006 19:34:48 GMT
I think that what might be happening is that the jdo.jar is defined  
in your classpath or is available by delegation by your special class  
loader. The standard Java class loaders first delegate to the parent  
class loader and if jdo.jar is available to the parent then you will  
get the same StateManager class from both class loaders. Which is  
what you want.

The bottom line is that in environments with multiple class loaders,  
the jdo.jar needs to be loaded by a common parent class loader of  
both the application and the implementation.

Craig

On Jan 11, 2006, at 11:06 AM, erik@jpox.org wrote:

>
> Forget what I said. Obviously this cannot work. I have to look in  
> my tests
> Quoting erik@jpox.org:
>
>> It seems to work.
>>
>> Loader 1 javax.jdo.spi.StateManager is
>> sun.misc.Launcher$AppClassLoader@53ba3d
>> Loader 2 javax.jdo.spi.StateManager is java.net.URLClassLoader@19d6af
>> javax.jdo.spi.StateManager in use is sun.misc.Launcher 
>> $AppClassLoader@53ba3d
>>
>> Loader 1 javax.jdo.spi.StateManager is
>> sun.misc.Launcher$AppClassLoader@53ba3d
>> Loader 2 javax.jdo.spi.StateManager is java.net.URLClassLoader@19d6af
>> javax.jdo.spi.StateManager in use is sun.misc.Launcher 
>> $AppClassLoader@53ba3d
>>
>>
>> Here is the unit test I'm running
>>
>>         File root = new
>>
> File(ClassLoaderTest.class.getResource("/org/jpox/persistence/ 
> ClassLoaderTest.class").getPath()).getParentFile().getParentFile 
> ().getParentFile().getParentFile();
>>         URL path1 = new URL(root.toURL().toString()+"/");
>>         URL path2 = new URL(path1.toString()+"/test/");
>>         URL path3 = new URL(path1.toString()+"/test-classes/");
>>         String jar =
>> JDOHelper.class.getResource("/javax/jdo/JDOHelper.class").getPath();
>>         if( jar.indexOf('!')>0 ) // jar
>>         {
>>             jar = jar.substring(0,jar.indexOf('!'));
>>         }
>>         else
>>         {
>>             jar = new
>> File(jar).getParentFile().getParentFile().getParentFile().toURL 
>> ().toString();
>>         }
>>         URL path4 = new URL(jar);
>>         URLClassLoader loader = new URLClassLoader(new URL[]  
>> {path1, path2,
>> path3, path4},null);
>>         ClassLoader l = Thread.currentThread 
>> ().getContextClassLoader();
>>
>>         Thread.currentThread().setContextClassLoader(loader);
>>         PersistenceManager pm = pmf.getPersistenceManager();
>>         Transaction tx = pm.currentTransaction();
>>
>>         Object id = null;
>>         try
>>         {
>>
>>
> l.loadClass("javax.jdo.spi.StateManager").forName 
> ("javax.jdo.spi.StateManager",true,l);
>>
>>
> loader.loadClass("javax.jdo.spi.StateManager").forName 
> ("javax.jdo.spi.StateManager",true,loader);
>>             System.out.println("Loader 1  
>> javax.jdo.spi.StateManager is
>> "+l.loadClass("javax.jdo.spi.StateManager").getClassLoader());
>>             System.out.println("Loader 2  
>> javax.jdo.spi.StateManager is
>> "+loader.loadClass("javax.jdo.spi.StateManager").getClassLoader());
>>             Person p = new Person(987322,"cl","last","mail");
>>             tx.begin();
>>             pm.makePersistent(p);
>>             id = pm.getObjectId(p);
>>             System.out.println("javax.jdo.spi.StateManager in use is
>>
> "+((org.jpox.PersistenceManagerImpl)pm).getStateManagerById 
> (id).getClass().getClassLoader());
>>
>>             tx.commit();
>>         }
>>         finally
>>         {
>>             if (tx.isActive())
>>             {
>>                 tx.rollback();
>>             }
>>             pm.close();
>>         }
>>
>>         pm = pmf.getPersistenceManager();
>>         Thread.currentThread().setContextClassLoader(l);
>>         tx = pm.currentTransaction();
>>         try
>>         {
>>             tx.begin();
>>             Person p = (Person) pm.getObjectById(id);
>>
>>
> l.loadClass("javax.jdo.spi.StateManager").forName 
> ("javax.jdo.spi.StateManager");
>>
>>
> loader.loadClass("javax.jdo.spi.StateManager").forName 
> ("javax.jdo.spi.StateManager");
>>             System.out.println("Loader 1  
>> javax.jdo.spi.StateManager is
>> "+l.loadClass("javax.jdo.spi.StateManager").getClassLoader());
>>             System.out.println("Loader 2  
>> javax.jdo.spi.StateManager is
>> "+loader.loadClass("javax.jdo.spi.StateManager").getClassLoader());
>>             System.out.println("javax.jdo.spi.StateManager in use is
>>
> "+((org.jpox.PersistenceManagerImpl)pm).getStateManagerById 
> (id).getClass().getClassLoader());
>>             assertEquals("cl",p.getFirstName());
>>             pm.deletePersistent(p);
>>             tx.commit();
>>         }
>>         finally
>>         {
>>             if (tx.isActive())
>>             {
>>                 tx.rollback();
>>             }
>>
>>
>> Quoting Craig L Russell <Craig.Russell@Sun.COM>:
>>
>>> Hi Erik,
>>>
>>> If your Employee is loaded by classloader 1 and your implementation
>>> is loaded by classloader 2 then the implementation won't work using
>>> the standard JDO 2 binary compatible contracts.
>>>
>>> Your implementation implements cl2.StateManager but the Employee
>>> expects cl1.StateManager. I don't see how it can work.
>>>
>>> Craig
>>>
>>> On Jan 11, 2006, at 1:27 AM, erik@jpox.org wrote:
>>>
>>>> Craig,
>>>>
>>>> We can make it work easily. We are able to verify by class name the
>>>> interfaces
>>>> implemented, but I wonder if there is some security restriction on
>>>> that.
>>>>
>>>> Regards,
>>>>
>>>> Erik Bengtson
>>>>
>>>> Quoting Craig L Russell <Craig.Russell@Sun.COM>:
>>>>
>>>>> Hi Erik,
>>>>>
>>>>> No, this is not ok.
>>>>>
>>>>> The problem is for example when the application calls
>>>>> pm.makePersistent(employee). If the jdoimpl does a check (if (! o
>>>>> instanceof PersistenceCapable) throw JDOUserException("Object  
>>>>> was not
>>>>> enhanced");) then the different classes will be an issue. The
>>>>> PersistenceCapable in the 2nd jar is not the same class as in  
>>>>> the 1st
>>>>> jar even though they have the same name.
>>>>>
>>>>> Have you tried it?
>>>>>
>>>>> Craig
>>>>>
>>>>> On Jan 10, 2006, at 4:09 PM, erik@jpox.org wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> An app has two classloaders, the 1st with jdoimpl.jar+jdo2.jar  
>>>>>> and
>>>>>> the 2nd with
>>>>>> persistent classes +jdo2.jar.
>>>>>>
>>>>>> The PCclass links to jdo2.jar(2) and the jdoImpl links to  
>>>>>> jdo2.jar
>>>>>> (1). I guess
>>>>>> that's ok, right? In any case, it may worth mentioning that in  
>>>>>> the
>>>>>> spec.
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> Erik Bengtson
>>>>>
>>>>> Craig Russell
>>>>> Architect, Sun Java Enterprise System http://java.sun.com/ 
>>>>> products/
>>>>> jdo
>>>>> 408 276-5638 mailto:Craig.Russell@sun.com
>>>>> P.S. A good JDO? O, Gasp!
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>> Craig Russell
>>> Architect, Sun Java Enterprise System http://java.sun.com/ 
>>> products/jdo
>>> 408 276-5638 mailto:Craig.Russell@sun.com
>>> P.S. A good JDO? O, Gasp!
>>>
>>>
>>
>>
>>
>>
>
>
>

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Mime
View raw message