Используйте PicoContainer с двумя подключаемыми модулями IntelliJ - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть два плагина для IntelliJ.PluginTwo зависит от PluginOne, поэтому Two запускается после One.Оба плагина зависят от третьего основного модуля.

Структура:

The Structure

Я хочу получить доступ к Dummy-классу черезКонтекст-класс в PluginTwo.Класс Context является частью Core-Module и использует PicoContainer для предоставления доступа к Dummy-Class.PluginOne создает контекст с PicoContainer при запуске.Теперь я хочу получить доступ к Dummy-классу из PluginTwo через PicoContainer.

Я получил эту ошибку:

    2018-09-28 14:25:19,208 [  12588]  ERROR - roject.impl.ProjectManagerImpl - PluginTwoProjectComponent@94a5de2 
java.lang.LinkageError: loader constraint violation: loader (instance of com/intellij/ide/plugins/cl/PluginClassLoader) previously initiated loading for a different type with name "Context"
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at com.intellij.util.lang.UrlClassLoader._defineClass(UrlClassLoader.java:276)
    at com.intellij.util.lang.UrlClassLoader.defineClass(UrlClassLoader.java:272)
    at com.intellij.util.lang.UrlClassLoader._findClass(UrlClassLoader.java:241)
    at com.intellij.ide.plugins.cl.PluginClassLoader.a(PluginClassLoader.java:142)
    at com.intellij.ide.plugins.cl.PluginClassLoader.a(PluginClassLoader.java:74)
    at com.intellij.ide.plugins.cl.PluginClassLoader.loadClass(PluginClassLoader.java:61)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at PluginTwoProjectComponent.projectOpened(PluginTwoProjectComponent.java:16)

...

PicoContainer создается вContext-Class:

private static Context instance;

private final MutablePicoContainer picoContainer;

public static synchronized Context getInstance() {
    if (instance == null) {
        instance = new Context();
    }
    return instance;
}

public Context() {
    picoContainer = new DefaultPicoContainer();
    picoContainer.addComponent(DummyClass.class);
}

public <T> T getComponent(Class<T> clazz) {
    return picoContainer.getComponent(clazz);
}

PluginOneProjectComponent получает экземпляр контекста

public class PluginOneProjectComponent implements ProjectComponent {

    private static Context context;

    private Project project;

    public PluginOneProjectComponent(Project project) {
        this.project = project;
    }

    @Override
    public void projectOpened() {
        System.out.println("PluginOneProjectComponent started with project " + project.getName());
        context = Context.getInstance();

        DummyClass dummy = context.getComponent(DummyClass.class);
        System.out.println("DummyText from PluginOne " + dummy.getText());
        System.out.println("DummyNumber from PluginOne " + dummy.getNumber());
    }

    public static Context getContext() {
        return context;
    }
}

Из PluginTwo я хочу использовать контекст из PluginOne для доступа к DummyClass.Но это не работает.

public class PluginTwoProjectComponent implements ProjectComponent {

    Project project;

    public PluginTwoProjectComponent(Project project) {
        this.project = project;
    }

    @Override
    public void projectOpened() {
        System.out.println("PluginTwoProjectComponent started with project " + project.getName());
        Context context = PluginOneProjectComponent.getContext();
        DummyClass dummy = context.getComponent(DummyClass.class);
        System.out.println("DummyText from Plugin Two" + dummy.getText());
        System.out.println("DummyNumber from Plugin Two" + dummy.getNumber());
    }
}

Так что вывод только.

PluginOneProjectComponent started with project HelloWorld
DummyText from PluginOne Some Text
DummyNumber from PluginOne 42
PluginTwoProjectComponent started with project HelloWorld

Когда я вызываю getComponent (DummyClass.class) для контекста в отладчике, я получаю только нольв результате.

Может кто-нибудь мне помочь?Есть ли лучший способ получить доступ к моему Context-Class из PluginOne?

Я воспроизвел ошибку в этом небольшом проекте, чтобы поделиться ею с вами.Мне нужен только PicoContainer от PluginOne, чтобы использовать его в PluginTwo.Полный источник доступен здесь: https://github.com/jafey/intellij-plugin-picocontainer-poc

1 Ответ

0 голосов
/ 01 октября 2018

Как я понимаю, вы должны полагаться на концепцию Services для связи между плагинами, поскольку они загружены в отдельные загрузчики классов, тип X в первом плагине на самом деле не совпадает с типом X во втором плагине.

Также концепция пико-контекста подразумевает приватность для плагина

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...