Есть ли лучшие практики для работы с Java EE и java.endorsed.dirs?

Недавно я столкнулся с проблемой, связанной с автономной версией Glassfish (v3.1) и встроенной версией Glassfish (v3.1) против java SE и способом использования java.endorsed.dirs. Конкретная проблема у меня здесь, но я не думаю, что в последний раз я столкнусь с чем-то подобным.

Информация, которую я нашел здесь и здесь, предполагает добавление библиотек, одобренных Glassfish, в путь начальной загрузки при компиляции. Тем не менее, этот отчет об ошибках показывает, что сложно установить правильные библиотеки при использовании встроенного Glassfish.

Таким образом, создается впечатление, что при развертывании в автономном контейнере Glassfish мое приложение будет работать с одобренными библиотеками, содержащимися в Glassfish, но при использовании встроенного контейнера этого не произойдет. Я столкнулся с моей первоначальной проблемой, потому что плагин maven-embedded-glassfish-plugin не запускает Glassfish, внедренный с использованием одобренных библиотек, как это делает автономный Glassfish. Я также не уверен, включают ли другие контейнеры (например, jboss) тот же набор одобренных библиотек, что и Glassfish.

Итак, я (1) должен изо всех сил (чтобы) убедиться, что мое приложение скомпилировано с одобренными библиотеками и всегда развернуто в контейнере, который загружается с использованием одобренных библиотек, или я должен (2) просто придерживаться того, что в комплекте с Java SE 6?

Если я выберу (2), придется ли мне беспокоиться о несовместимости при развертывании моего приложения в контейнере, который загружается с новыми одобренными библиотеками?

Буду признателен за любую информацию, которую может предложить каждый.

2 ответа

Решение

Я могу упустить что-то очевидное здесь, но... Разве GlassFish Embbeded не поставляется с библиотеками, совместимыми со спецификациями Java EE? И разве эти библиотеки не загружены по умолчанию? (Если это не так, пожалуйста, заполните ошибку здесь: http://java.net/jira/browse/EMBEDDED_GLASSFISH).

Я имею в виду следующее: вы должны скомпилировать API-интерфейсы спецификации Java EE и просто позволить контейнеру использовать его собственные реализации.

Для первой части, если вы используете Maven, мне нравится, как архетипы Codehaus устанавливают одобренные библиотеки. Это и чистый и Agnostic сервера приложений:

<properties>
   <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

...

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
        <compilerArguments>
            <endorseddirs>${endorsed.dir}</endorseddirs>
        </compilerArguments>
    </configuration>
 </plugin>

...

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.1</version>
    <executions>
       <execution>
            <phase>validate</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <outputDirectory>${endorsed.dir}</outputDirectory>
                <silent>true</silent>
                <artifactItems>
                    <artifactItem>
                        <groupId>javax</groupId>
                        <artifactId>javaee-endorsed-api</artifactId>
                        <version>6.0</version>
                        <type>jar</type>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

Это практически все, что вам нужно для компиляции ваших проектов с использованием API Java EE 6. Любой сервер приложений, совместимый с Java EE 6, должен предоставлять эти услуги, и вам не следует беспокоиться о том, как они делают его доступным для вашего приложения.

Ответственность за загрузку служб Java EE должна лежать на вашем сервере приложений. Если вы попробуете свое собственное решение "в доме", скорее всего, JAR Hell вырвется на свободу.

Ура,

РЕДАКТИРОВАТЬ: javaee-endorsed-api Подход выше, вероятно, будет хорошо работать, но это дает мне воли. Я не думаю, что это произведено или поддержано больше. Кроме того pom.xml он содержит в себе отражает, что в какой-то момент он был назван javaee-compact-api и вы можете увидеть, как они удаляют из него классы реализации. В отличие от этого, выбор вишен API, который вы хотите использовать в качестве одобренного (как я рекомендую ниже), кажется более стабильным и гибким. Наконец, если вы все еще хотите использовать javaee-endorsed-api подход, вы все еще можете использовать общий подход, который я рекомендую, и указать на javaee-endorsed-api.jar вместо.

Райан; Я только что прочесал ваш длинный след в этом (касаясь Stackru, форумов java.net и т. Д.) В том же путешествии.

Во время модульного или интеграционного тестирования вам необходимо установить java.endorsed.dirs Системное свойство, как вы знаете.

Хитрость в том, что вы должны сделать это таким образом, чтобы JVM, выполняющая тесты, подхватила его. И это зависит от того, как работает Surefire.

Если по какой-то причине у вас есть Surefire, не настроенный на форк, это, вероятно, плохо, и вам следует пересмотреть свою конфигурацию здесь.

Если вы установили Surefire на форк, вы можете подумать, что можете просто включить java.endorsed.dirs в systemPropertyVariables строфа, вот так:

<systemPropertyVariables>
  <java.endorsed.dirs>weWillGetToThisInAMoment</java.endorsed.dirs>
</systemPropertyVariables>

... но это было бы неправильно. Причина в том, что фактически запущенная программа называется ForkedBooter и ForkedBooter программно устанавливает системные свойства для ваших юнит-тестов. То есть к тому времени, когда ваш <systemPropertyVariables> строфа читается ForkedBooter сейчас уже поздно.

Но вы можете использовать <argLine> в вашей конфигурации Surefire, как это:

<configuration>
  <argLine>-Djava.endorsed.dirs=weWillGetToThisInAMoment</argLine>
</configuration>

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

Вы хотите черри выбрать API для переопределения. В твоем случае, javax.annotation.* это законный выбор. Вы хотите предоставить каталог в вашем локальном репозитории Maven, в котором находится соответствующий файл.

Вот значение, которое я использую:

${settings.localRepository}${file.separator}org${file.separator}glassfish${file.separator}main${file.separator}javaee-api${file-separator}javax.annotation${file.separator}${javaxAnnotationVersion}
  • Maven гарантирует, что ${settings.localRepository} будет расширяться до значения, где живет ваш местный репозиторий Maven.
  • ${file.separator} это способ получить значение System.getProperty("file.separator") в замене собственности Maven.
  • В моем случае я уже объявил <dependency> на артефакте GlassFish, который связывает javax.annotation пакет, как определено в Java EE 6. Итак, здесь я построил путь к артефакту. Я также определил свойство с именем javaxAnnotationVersion который для меня установлен на 3.1.2,

После того, как вы сделаете все это, затем, когда Surefire разбудит виртуальную машину для запуска ваших модульных тестов, для утвержденных каталогов будет установлен каталог в вашем локальном репозитории Maven, содержащий jar, в котором находится javax.annotation классы, и теперь встроенный GlassFish, который работает в процессе, будет использовать версии Java EE 6 javax.annotation классы вместо версий Java SE 6. Я надеюсь, что это помогает вам.

Другие вопросы по тегам