Делегирование пользовательского загрузчика классов в RMI - PullRequest
1 голос
/ 31 октября 2019

Обновление : добавлена ​​дополнительная информация, поскольку обходной путь не работает надежно

У меня есть модуль RMI, который я загружаю с помощью специального загрузчика классов для Spring bean-компонентов. Этот загрузчик классов также используется для загрузки этого модуля.

ClassLoader наследуется от URLClassLoader. Для родительского загрузчика классов этого пользовательского загрузчика классов установлено значение AppClassLoader.

В этом модуле я запускаю реестр RMI с загрузчиком классов conxt в соответствии с этим загрузчиком классов.

Теперь, если я сделаюВызовы RMI, реестр RMI:

  • способен определить классы по пути URL-адресов, которые я предоставляю своему загрузчику классов
  • НЕ способен определить классы в родительском классеloader.

Включив отладку на стороне сервера RMI через

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

, я смог убедиться, что в реестре RMI используется правильный загрузчик классов (также ссылка наparent)

Я попытался добавить URL из AppClassLoader в мой ClassLoader. Во-первых, это, кажется, работает, но он работает случайно.

В настоящее время у меня есть следующий вывод из журнала RMI

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

Загрузчик родительского класса выглядит следующим образом

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'
...

Примечание: Найдены классы из JDK, такие как java.net.URI

В банке содержится класс

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

Я провел несколько модульных тестов, чтобы убедиться, что это работает (безRMI). Он находит классы

  • в той же банке
  • из обсуждаемой банки
  • из других банок, не входящих в CLASSPATH

Здесьмой 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);
        }

    }

Установлен менеджер безопасности

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

и файл политики очень разрешительный

grant {
    permission java.security.AllPermission;
};

Странно то, что он работаетранее без проблем. Изменения, которые я сделал с тех пор

  • Переключиться на Windows 10
  • Тем временем я убедился, что такая же проблема возникает в Linux (Ubuntu)
  • Обновление до Gradle 5.4. 1
...