У меня есть два java-приложения, которые мне нужно, чтобы разговаривать друг с другом - если второй установлен. Оба приложения/фреймворки обширны, а основной код не под моим контролем, но я могу расширить части, которые мне нужно использовать, я просто не могу переписать то, что уже есть.
Мое первое приложение - это набор плагинов, основанных на Eclipse. Именно отсюда мне нужно подключиться ко второму приложению, чтобы извлечь данные из него.
Мое второе приложение - это приложение на основе клиент-сервер, и мне нужно иметь возможность создавать безгласное соединение с сервером (вместо клиента), если клиентское приложение установлено на том же компьютере. Для этого подходят Java API, которые у меня есть в среде Dev, но они могут быть развернуты или не развернуты на пользовательской машине.
Я не могу объединить JAR из второго приложения и доставить их первым, так как это будет абсолютно нарушением авторских прав и т.д. Поэтому мне нужно разрешить пользователю первого приложения указать каталог установки для второго (если они установлены).
То, что я надеюсь сделать, это заставить пользователя первого приложения указать каталог установки второго приложения и загрузить любые классы, которые мне нужны из этого места, без необходимости делать много микроконфигурации.
EDIT: То, что я сделал до сих пор, создано 2 плагинами OSGI. Первый позволяет пользователю первого приложения указать рабочий каталог второго приложения. Если этот путь установлен, я пытаюсь использовать отражение для загрузки второго плагина, который имеет ссылки на классы, необходимые для второго приложения. НО при попытке отразить этот класс - я не могу найти его в classpath и т.д. То, что я пробовал,
Class<?> c = Class.forName("com.package.impl.Activator");
а также
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
Class<?> c = classloader.loadClass("com.package.impl.Activator")
Я также попробовал посмотреть другие классы в Classpath, чтобы попробовать и помочь, используя
ImmutableSet<ClassPath.ClassInfo> paths = ClassPath.from(Thread.currentThread().getContextClassLoader()).getAllClasses();
но это не возвращало ни одного из ожидаемых классов плагинов и содержало только каркасные классы, такие как
com.sun.crypto.provider.AESCipher
com.sun.crypto.provider.TlsRsaPremasterSecretGenerator
com.sun.crypto.provider.ai
com.sun.java.accessibility.AccessBridge
com.sun.java.accessibility._AccessibleState
com.sun.java.accessibility.util.AWTEventMonitor
com.sun.java.accessibility.util.java.awt.ButtonTranslator
com.sun.java.accessibility.util.java.awt.TextComponentTranslator
etc...
Я не уверен, что мне не хватает в настройке classpath, чтобы найти мой класс плагина, используя отражение. Есть идеи?
PS Оба приложения запускаются на рабочем столе Windows.
Я бы сказал, что динамическая загрузка классов так, как вы пытаетесь, является тупиком. Я вижу два варианта:
Если клиентские API-интерфейсы поставляются в банке с пакетом (это означает, что он может быть загружен как пакет в вашу инфраструктуру OSGi), решение будет заключаться в загрузке пакета API-клиента из вашего первого плагина с использованием стандартных API OSGi BundleContext
и Bundle
(BundleContext.installBundle
и Bundle.start
). Это должно быть возможно, так как вы знаете местоположение банки клиента API после ввода пользователем места установки. После этого вы можете сделать то же самое для своего второго пакета, который зависит от этих клиентских API. Это должно вызвать все программное обеспечение для выполнения функций.
Если клиентские API поставляются в обычном банке, и вы не можете убедить поставщика создать банку для вас, ситуация немного сложнее. Предпочтительным решением было бы динамическое обертывание контейнера API-клиента в банку с пакетом. Существует уже программное обеспечение, которое выполняет это действие (bnd, pax, eclipse, различные фреймворки). После обертывания вы вернетесь к первому решению. Но вопрос в том, будет ли это разрешено с учетом условий лицензирования.
Если все вышеперечисленное не удается, я думаю, что нет другого решения, которое затем создавало бы программное обеспечение вне вашей среды плагина, которое устраняет пробел через какое-то RPC-решение: вам нужно написать некоторый код без плагина, который использует клиентскую банку. Эта часть работает в собственной JVM и взаимодействует с плагином в вашей OSGi-среде посредством удаленных вызовов методов.
Надеюсь, что это поможет или что этот ответ вызовет некоторые последующие действия с лучшим решением.