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, [EMAIL PROTECTED] wrote:


Forget what I said. Obviously this cannot work. I have to look in my tests

It seems to work.

Loader 1 javax.jdo.spi.StateManager is
[EMAIL PROTECTED]
Loader 2 javax.jdo.spi.StateManager is [EMAIL PROTECTED]
javax.jdo.spi.StateManager in use is [EMAIL PROTECTED]

Loader 1 javax.jdo.spi.StateManager is
[EMAIL PROTECTED]
Loader 2 javax.jdo.spi.StateManager is [EMAIL PROTECTED]
javax.jdo.spi.StateManager in use is [EMAIL PROTECTED]


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 <[EMAIL PROTECTED]>:

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, [EMAIL PROTECTED] 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 <[EMAIL PROTECTED]>:

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, [EMAIL PROTECTED] 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
P.S. A good JDO? O, Gasp!






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










Craig Russell

Architect, Sun Java Enterprise System http://java.sun.com/products/jdo

408 276-5638 mailto:[EMAIL PROTECTED]

P.S. A good JDO? O, Gasp!


Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to