1

Update: Added some more info as the workaround is not working reliably

I have a RMI module that I load with a custom classloader vie spring beans. This class loader is also used to load that module.

The ClassLoader inherits from URLClassLoader. The parent class loader of that custom classloader is set to the AppClassLoader.

In this module, I start the RMI registry with the conxt classloader accordingly to this class loader.

Now, if I make RMI calls, the RMI registry:

  • is able to spot classes in the path of the URLs that I provide to my class loader
  • is NOT able to spot classes in the parent class loader.

By enabling debugging on RMI server side via

"-Djava.rmi.server.logCalls=true",
"-Dsun.rmi.server.logLevel=VERBOSE",
"-Dsun.rmi.loader.logLevel=VERBOSE",

I was able to verify that the correct class loader is used by the RMI registry (also the reference to the parent)

I tried adding the URLs from the AppClassLoader to my ClassLoader. First, it seemed to work but it onyl works randomly.

Currently I have the following output from the RMI logging

Nov 04, 2019 2:56:33 PM sun.rmi.server.LoaderHandler loadClass
FEINER: RMI TCP Connection(4)-10.45.42.206: (thread context class loader: class org.jvoicexml.config.JVoiceXmlClassLoader[repo=jsapi20,...,file:/C:/Users/dwalka/Documents/git/JVoiceXML/org.jvoicexml/build/libs/org.jvoicexml-0.7.9.jar,...,parent=sun.misc.Launcher$AppClassLoader@3d4eac69])
Nov 04, 2019 2:56:33 PM sun.rmi.server.LoaderHandler loadClass
FEIN: RMI TCP Connection(4)-10.45.42.206: class "org.jvoicexml.UuidSessionIdentifer" not found via codebase
java.lang.ClassNotFoundException: org.jvoicexml.UuidSessionIdentifer

The parent class loader looks as follows

2019-11-04T14:56:08,505 [JVoiceXmlMain       ] INFO   cexml.jndi.classserver.ClassloaderServer (    56) - parent class loader 'sun.misc.Launcher$AppClassLoader@3d4eac69'
...
2019-11-04T14:56:08,506 [JVoiceXmlMain       ] INFO   cexml.jndi.classserver.ClassloaderServer (    64) - parent class loader entry: 'file:/C:/Users/dwalka/Documents/git/JVoiceXML/org.jvoicexml/build/libs/org.jvoicexml-0.7.9.jar'
...

Side note: Classes from the JDK like java.net.URI are found

The jar contains the class

C:\Users\dwalka\Documents\git\JVoiceXML\org.jvoicexml\build\libs>jar -tf org.jvoicexml-0.7.9.jar | findstr "UuidSessionIdentifer"
org/jvoicexml/UuidSessionIdentifer.class

I did some unit tests to ensure that this works (without RMI). It finds classes

  • in the same jar
  • from the jar under discussion
  • from other jars not in the CLASSPATH

Here is my ClassLoader

    public final class JVoiceXmlClassLoader extends URLClassLoader {
        /** The repository that this class loader is responsible for. */
        private final String repository;

        /**
         * Constructs a new object.
         * @param parent the parent class loader.
         */
        public JVoiceXmlClassLoader(final ClassLoader parent) {
            this(parent, null);
        }

        /**
         * Constructs a new object.
         * @param parent the parent class loader.
         * @param repo the repository that this class loader is responsible for
         */
        public JVoiceXmlClassLoader(final ClassLoader parent, final String repo) {
            super(new URL[0], parent);
            repository = repo;
        }

        /**
         * Retrieves the used repository
         * @return the repository.
         * @since 0.7.9
         */
        public String getRepository() {
            return repository;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void addURL(final URL url) {
            super.addURL(url);
        }

    }

A security manager is set

"-Djava.security.manager",
"-Djava.security.policy=${project(':org.jvoicexml').buildDir}/config/jvoicexml.policy",

and the policy file is very permissive

grant {
    permission java.security.AllPermission;
};

The weird thing is that it was working previously without problems. Changes that I made since then

  • Switch to Windows 10
  • In the meantime I verified the same issue happens under Linux (Ubuntu)
  • Update to Gradle 5.4.1

1 Answers1

0

The root cause of the problem was neither the classloader nor RMI. It seems it was a CLASSPATH issue when mengling around with eclipse and gradle.

  • Seems like the person who posted the question & answered the question are same? same profile picture. Good luck. – Nayana_Das Jun 26 '20 at 11:57