Получение экземпляра, когда конструктор # newInstance выбрасывает? - PullRequest
0 голосов
/ 20 февраля 2011

Я работаю над простой системой плагинов, где сторонние плагины реализуют интерфейс Plugin.Каталог JAR сканируется, и реализующие классы создаются с Constructor#newInstance.

Дело в том, что эти плагины обращаются к register* методам хоста плагина.Эти регистрации используют экземпляр Plugin в качестве дескриптора.Моя проблема заключается в том, как очистить эти регистрации, если конструктор решит потерпеть неудачу и выбросить на полпути.

InvocationTargetException, похоже, не имеет ничего для получения экземпляра. Есть ли способ получить экземпляр конструктора, генерирующего исключение?

PS: пользователям обычно настоятельно рекомендуется, чтобы конструктор ничего не делал, но на практике люди делают это любымпути.

Ответы [ 2 ]

1 голос
/ 20 февраля 2011

В действительности вы спрашиваете, есть ли способ получить (частичный) экземпляр, когда конструктор выдает исключение.

Ответ - нет. Но это не потому, что экземпляр "мертв". Фактически, ссылка на экземпляр все еще может быть доступна и использоваться другими частями приложения ... если она была "опубликована" до завершения конструктора.

Настоящая причина в том, что ни при создании, ни при создании исключения не записывается экземпляр, связанный с методом или конструктором, выполняющим создание / создание.


Вам нужно будет решить это другим способом. Мое предложение заключается в том, чтобы вы установили правило, согласно которому эти классы плагинов должны регистрировать только экземпляр как последний оператор конструктора; то есть, когда больше не могут быть сгенерированы исключения, связанные с инициализацией.

1 голос
/ 20 февраля 2011

Можно ли выполнить регистрацию через объект-держатель, который затем используется для фактической регистрации плагина после успешного создания класса плагина? Я думаю о чем-то вроде этого:

public class MyPlugin extends BasePlugin {
    public MyPlugin(PluginRegistry registry) {
        super(registry);
        // here be things which may cause an exception
        // to be thrown, among other things
    }
}

public interface PluginRegistry {
    // method(s) for registration
}
public class PluginRegistryHolder implements PluginRegistry {
    // implementations of the required method(s) for registration
    // also a method for getting temporary registration data from within the class
}

// Actual usage in your code
public void registerPlugin(final String className) {
    PluginRegistryHolder h = new PluginRegistryHolder();
    Constructor c = /* acquire correct constructor, omitted for clarity */
    try {
        Object o = c.newInstance(new Object[] {h});
        this.actualRegistry.register(o, h.getRegistrationData());
    } catch (Throwable t) { /* die */
    }
}

Так что, в основном, обрабатывайте регистрацию изящно и никогда не позволяйте классу плагина регистрироваться напрямую, а через управляемый прокси.

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