Выгрузка классов Javaagent - PullRequest
       11

Выгрузка классов Javaagent

3 голосов
/ 08 августа 2009

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

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

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

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

Так есть ли способ решить проблему пути к загрузочным классам и все же выгрузить классы предыдущего агента?

Ответы [ 4 ]

1 голос
/ 12 августа 2009

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

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

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

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

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

0 голосов
/ 27 января 2011

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

0 голосов
/ 17 августа 2009

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

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

Привет.

0 голосов
/ 14 августа 2009

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

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

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

...