Java: самый легкий способ упаковать и Java 1.5 и 1,6 кода

Я хочу упаковать часть кода, который абсолютно должен работать на 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),

8
задан SyntaxT3rr0r 15 March 2010 в 16:11
поделиться

3 ответа

Вы не можете скомпилировать это на 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, чтобы избежать этой проблемы. Спасибо за ваши комментарии вам обоим.

3
ответ дан 5 December 2019 в 22:17
поделиться

Скомпилировать для 1.5.

В вашем коде используйте отражение. Вы можете получить объект Method из интерфейса Class; у него есть метод вызова, который принимает ваш экземпляр mbean в качестве параметра. Примерно так:

Class c = mbean.getClass (); // также можно использовать YourClass.class, чтобы получить этот

Метод m = c.getMethod ("findMonitorDeadLockedThreads"); // или любой другой метод (параметры для метода указываются с помощью второго параметра Class ... для getMethod)

m.invoke (mbean) // вызывает метод с вашим экземпляром

Конечно вам не нужно делать это каждый раз; настройте ссылки на методы в конструкторе, а затем просто вызовите нужный по запросу.

2
ответ дан 5 December 2019 в 22:17
поделиться

Maven позволяет довольно легко делать это с помощью профилей. Идея профилей заключается в том, что вы хотите создать две разные версии чего-то на основе некоторых критериев. В этом конкретном примере вы можете определить профиль jdk15 и jdk16 , указать, с какой версией JDK компилировать каждый, и указать ему включить одну копию класса в профиль jdk15. а другой - в jdk16.

Чтобы начать работу, см .:

http://unserializableone.blogspot.com/2008/09/compile-and-test-with-different-jdk.html

Здесь описывается, как использовать различные JDK. версия часть проблемы.

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

Maven - Включить разные файлы во время сборки

1
ответ дан 5 December 2019 в 22:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: