2009-08-08 5 views
3

У меня есть агент Java, который использует байт-код. Я использую приставку apis в java 6, чтобы позволить пользователям динамически загружать агент и инструмент и код деинструмента с помощью моего java-агента. Я использую атрибут атрибута Boot-Class-Path, чтобы убедиться, что мои классы javagent находятся в пути класса загрузки, так что мои пользователи могут обрабатывать классы, такие как ArrayList и т. Д.Выгрузка класса Javaagent

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

Мне нужен такой способ, чтобы при моей клиентской версии 2 javaagent версия 1 была выгружена.

Я знаю, что одним из способов было бы написать загрузчик классов для классов javaagent и установить ссылку на загрузчик классов на null. Однако в этом случае я не буду в состоянии классов инструментов в пути к загрузке, так как мой загрузчик классов будет ниже в иерархии от загрузчика загрузчика и, таким образом, мои пользовательские классы инструментов, такие как ArrayList, потому что, если я добавлю вызов внутри методов ArrayList к одному из методы моих агентов, загрузчик загрузочного класса не сможет их увидеть.

Итак, есть ли способ решить проблему с загрузкой класса и выгрузить классы предыдущего агента?

+1

Возможно, вы захотите взглянуть на JavaRebel (http://www.zeroturnaround.com/javarebel/), который является коммерческой реализацией того, что вы пытаетесь сделать. Это может дать вам указание на то, что есть и что невозможно. – skaffman

ответ

1

Я не эксперт по этой теме, но похоже, что этот вид выгрузки на замену напрямую не поддерживается.

Но вам нужно выгрузить-заменить класс?

Не могли бы вы создать неизменяемый класс, о котором говорит внешний мир, в котором вы внутренне внедряете систему управления версиями?

Например, вы создаете класс MyToolAgent, который имеет, скажем, статическую строку с именем класса используемой ToolAgentImplementation. При первом выпуске он настроен на использование ToolAgentImplementation1_0. При обновлении до версии 2.0 вы развертываете дополнительный класс под названием ToolAgentImplmenetation2_0 и обновляете класс MyToolAgent для его загрузки и использования. Вы никогда не выгружаете версию 1.0, но перестаете ее использовать. Здесь вы теряете память, но вы добиваетесь обновления версии.

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

0

Я не уверен, что это будет работать, но он может дать вам некоторые варианты ...

Вместо того, чтобы пытаться перезагрузить текущий агент (назовем это агент инструмент), добавить новый агент (агент установки). Агент-установщик будет иметь ровно 1 функцию: используйте RedefineClasses(), чтобы заменить исходные классы агента инструмента.

Если вы укажете агент-установщик с номером версии как часть имени класса (MyToolInstallerV1), вы можете продолжить загрузку новых установщиков, которые обновляют инструмент инструмента. Если размер становится проблемой, возможно, агент-установщик может искать предыдущих установщиков и заменять их классы небольшим заглушкой no-op.

0

Я пока ничего не сделал, но я просто играл с java.util.ServiceLoader и реализовал какую-то архитектуру плагина с динамической загрузкой JAR с помощью подхода URLClassLoader.

Я не знаю, что «измерительная аппаратура» может быть изменена таким образом, но проблемы с управлением версиями и динамическими нагрузками могут быть отслежены, и это очень быстро проверить, потому что жесткий материал выполняется ServiceLoader (просто следуйте спецификации крошечных/META-INF/services/XXX), и вы готовы :)

С уважением.

0

Идеальный вариант использования для OSGI. Не уверен, что вы могли бы подключить ваш агент как пакет.