Я хочу упаковать часть кода, который абсолютно должен работать на Java 1.5. Существует одна часть кода, где программа может быть "улучшена", если VM является 1.6 VM.
В основном это - этот метод:
private long[] findDeadlockedThreads() {
// JDK 1.5 only supports the findMonitorDeadlockedThreads()
// method, so you need to comment out the following three lines
if (mbean.isSynchronizerUsageSupported())
return mbean.findDeadlockedThreads();
else
return mbean.findMonitorDeadlockedThreads();
}
Каков был бы самый легкий способ иметь эту компиляцию на 1,5 и все же сделать 1,6 вызова метода когда на 1,6?
В прошлом я сделал что-то подобное путем компиляции уникальных 1,6 классов, которые я упаковал бы со своим приложением и инстанцировал бы использования ClassLoder, когда на 1,6 (потому что 1,6 JVM прекрасно подходят, смешиваясь 0x32 и 0x31 классы), но я думаю, что это - немного излишества (и немного болезненный, потому что во время процесса сборки необходимо создать и 0x31 и файлы 0x32 .class).
Как я должен пойти, если бы я хотел скомпилировать вышеупомянутый метод на 1,5? Возможно, с помощью отражения, но затем как (я не знаком вообще с отражением),
Примечание: если Вам любопытно, вышеупомянутый метод прибывает из этой статьи: http://www.javaspecialists.eu/archive/Issue130.html
(но я не хочу "комментировать эти три строки" как в статье, я хочу, чтобы это скомпилировало и работало и 1.5 и 1.6),
Вы не можете скомпилировать это на 1.5, но вы можете скомпилировать на 1.6 с параметром target, установленным на 1.5 (который будет генерировать байт-код для 1.5) и в коде, используя отражение, чтобы узнать, доступен ли метод.
Этот код будет искать метод: mbean.getClass (). GetMethod ("findDeadlockedThreads", новый класс [0]); Проблема в том, что он генерирует исключение NoSuchMethodException, если метод не 'не присутствует вместо простого возврата null или чего-то подобного. Это означает, что вам нужен такой код:
try
{
mbean.getClass().getMethod("findDeadlockedThreads", new Class<?>[0]);
return mbean.findDeadlockedThreads();
}
catch(NoSuchMethodException ex)
{
return mbean.findMonitorDeadlockedThreads();
}
Это не очень хорошо, потому что он использует Exception для принятия решения. Это, наверное, не очень быстро. Альтернативой является использование getMethods и перебор возвращенного списка, если ваш метод доступен. Это тоже не очень быстро.
РЕДАКТИРОВАТЬ: Кристофер Озбек предлагает в комментариях выполнить проверку существования метода только один раз и сохранить результат, чтобы избежать накладных расходов на блок Try-catch. Правильное и хорошее решение. matt b предупреждает, что target-option Java-Compiler не проверяет, доступны ли используемые классы и методы в Java 1.5. Это верно (иначе это не сработает, потому что вы хотите скомпилировать метод 1.6), а это означает, что программа должна быть тщательно протестирована под 1.5-VM, чтобы избежать этой проблемы. Спасибо за ваши комментарии вам обоим.
Скомпилировать для 1.5.
В вашем коде используйте отражение. Вы можете получить объект Method из интерфейса Class; у него есть метод вызова, который принимает ваш экземпляр mbean в качестве параметра. Примерно так:
Class c = mbean.getClass (); // также можно использовать YourClass.class, чтобы получить этот
Метод m = c.getMethod ("findMonitorDeadLockedThreads"); // или любой другой метод (параметры для метода указываются с помощью второго параметра Class ... для getMethod)
m.invoke (mbean) // вызывает метод с вашим экземпляром
Конечно вам не нужно делать это каждый раз; настройте ссылки на методы в конструкторе, а затем просто вызовите нужный по запросу.
Maven позволяет довольно легко делать это с помощью профилей. Идея профилей заключается в том, что вы хотите создать две разные версии чего-то на основе некоторых критериев. В этом конкретном примере вы можете определить профиль jdk15
и jdk16
, указать, с какой версией JDK компилировать каждый, и указать ему включить одну копию класса в профиль jdk15. а другой - в jdk16.
Чтобы начать работу, см .:
http://unserializableone.blogspot.com/2008/09/compile-and-test-with-different-jdk.html
Здесь описывается, как использовать различные JDK. версия часть проблемы.
Чтобы решить вторую часть проблемы, используя другое определение класса в зависимости от версии JDK, см. Это: