2011-06-22 6 views
7

Recientemente he tenido un problema con glassfish standalone (v3.1) vs glassfish embedded (v3.1) vs java SE y la forma en que se utiliza java.endorsed.dirs. El problema específico que tuve es here, pero no creo que sea la última vez que me encuentre con algo similar.¿Alguna de las mejores prácticas para tratar con Java EE y java.endorsed.dirs?

La información que encontré here y here sugiere agregar glassfish endorsed libs al arranque classpath al compilar. Sin embargo, el informe de error this sugiere que es difícil obtener las libs aprobadas correctamente cuando se utiliza glassfish incrustado.

Por lo tanto, parece que cuando implemente en un contenedor de vidrio independiente mi aplicación se ejecutará contra las librerías endosadas que incluye glassfish, pero cuando usa el contenedor incrustado no lo hará. Encontré mi problema original porque el complemento maven-embedded-glassfish-plugin no inicia glassfish incrustado usando las librerías endosadas como glassfish standalone. Tampoco estoy seguro de si otros contenedores (por ejemplo, jboss) incluyen el mismo conjunto de libs endosados ​​que glassfish.

Entonces, se supone que tengo que luchar (mucho) para asegurarme de que mi aplicación está compilada contra las librerías aprobadas y siempre implementada en un contenedor que se inicializa usando las librerías aprobadas o debería (2) simplemente adherirme a usar lo que se incluye con Java SE 6?

Si elijo (2), ¿tendré que preocuparme por las incompatibilidades al implementar mi aplicación en un contenedor que se inicia con las librerías respaldadas más recientes?

Agradecería cualquier idea que cualquiera pueda ofrecer.

Respuesta

2

Me puede estar faltando algo obvio aquí, pero ... ¿GlassFish Embbeded no se entrega con bibliotecas compatibles con las especificaciones Java EE? ¿Y esas bibliotecas no están cargadas de forma predeterminada? (Si no lo están, complete un error aquí: http://java.net/jira/browse/EMBEDDED_GLASSFISH).

Lo que quiero decir es: Debe compilar contra las API de especificación de Java EE, y simplemente deje que el contenedor use sus propias implementaciones.

Para la primera parte, si usa Maven, me gusta la forma en que Codehaus archetypes establece las librerías endosadas. Es a la vez limpia y Application Server Agnóstico:

<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> 

que es prácticamente todo lo que necesita para compilar sus proyectos contra Java EE 6 API. Cualquier servidor de aplicaciones compatible con Java EE 6 debe proporcionar esos servicios, y no debe preocuparse por cómo lo están poniendo a disposición de su aplicación.

La responsabilidad de la inicialización de los servicios de Java EE debe ser la de su servidor de aplicaciones. Si prueba su propia solución "interna", es probable que JAR Hell se desate.

Saludos,

+0

Lo que has dicho es (IMO) la forma en que _debe_ funcionar, pero las versiones anteriores de libs endosadas en Java SE ganan el escenario de "primer partido" cuando se cargan .. Creo. Quien inicie JVM necesita configurar java.endorsed.dirs, pero es difícil con algunos de los contenedores integrados. Para Glassfish Embedded, todo está en un gran JAR y no creo que las libs endorsed estén garantizadas en un lugar específico. Comencé un [hilo Arquilliano] (http://community.jboss.org/thread/168521?tstart=0) para ver lo que piensan. Agregué un [error de Glassfish] (http://java.net/jira/browse/EMBEDDED_GLASSFISH-131). –

+0

@Ryan J. Acabo de echar un vistazo en el informe de errores, y es efectivamente reproducible. Esto debería ser resuelto por el equipo de GlassFish siguiendo el espíritu de mi publicación anterior, pero hasta que puedan solucionarlo, hay algunas soluciones rápidas: 1. Utilice una clase principal para iniciar el servidor. 2. Cambie a otro contenedor integrado. 3. Establezca las librerías endosadas utilizando MAVEN_OPTS (uggly, pero lo pondré en funcionamiento inmediatamente ...). –

4

EDIT: El enfoque javaee-endorsed-api anterior, probablemente no tendrán ningún problema, pero me da escalofríos. No creo que ya se haya producido o mantenido.Además, el pom.xml que contiene refleja que en algún momento se llamó javaee-compact-api, y puede ver cómo eliminan las clases de implementación de él. Por el contrario, seleccionar cuidadosamente los frascos de API que desea utilizar según lo endosado (como recomiendo a continuación) parece ser más estable y flexible. Finalmente, si aún desea utilizar el enfoque javaee-endorsed-api, puede seguir utilizando el enfoque general que recomiendo y apuntar a javaee-endorsed-api.jar.

Ryan; Acabo de peinar tu largo camino en esto (tocando StackOverflow, los foros de java.net, etc.) en el mismo viaje.

Durante la prueba unitaria o de integración, tendrá que configurar la propiedad del sistema java.endorsed.dirs, como usted sabe.

El truco es que tienes que hacer esto de forma que la JVM que ejecuta las pruebas lo levante. Y eso depende de cómo tengas funcionando Surefire.

Si por alguna razón tiene Surefire configurado en no en fork, probablemente esto sea algo malo, y debería volver a evaluar su configuración aquí.

Si tiene un juego de éxito seguro al tenedor, entonces se podría pensar que podría incluir simplemente java.endorsed.dirs en una estrofa systemPropertyVariables, así:

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

... pero eso sería un error. La razón es que el programa que se está ejecutando es algo llamado ForkedBooter, y el ForkedBooter establece programáticamente las propiedades del sistema para las pruebas de su unidad. Es decir, cuando su estrofa <systemPropertyVariables> es leída por el ForkedBooter ya es demasiado tarde.

Pero puede utilizar <argLine> en la configuración de éxito seguro de la siguiente manera:

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

Ahora la VM que las horquillas de éxito seguro tendrá sus directorios aprobados valor apropiado. Ahora hablemos sobre qué valor ofrecer.

Desea seleccionar las API para sobrescribirlas. En su caso, javax.annotation.* es una elección legítima. Desea suministrar el directorio en su repositorio Maven local que alberga el contenedor relevante.

Aquí es el valor que utilizo:

${settings.localRepository}${file.separator}org${file.separator}glassfish${file.separator}main${file.separator}javaee-api${file-separator}javax.annotation${file.separator}${javaxAnnotationVersion} 
  • Maven garantiza que ${settings.localRepository} se ampliará para el valor de donde vive su repositorio Maven locales.
  • ${file.separator} es una forma de obtener el valor de System.getProperty("file.separator") en un reemplazo de propiedad Maven.
  • En mi caso, ya he declarado <dependency> en the GlassFish artifact that bundles up the javax.annotation package as defined in Java EE 6. Así que aquí he construido un camino hacia el artefacto. También definí una propiedad llamada javaxAnnotationVersion, que, para mí, está configurada en 3.1.2.

Una vez hecho todo esto, entonces cuando las horquillas de éxito seguro de una máquina virtual para ejecutar las pruebas unitarias, los directorios aprobados se establecerá en el directorio de su repositorio local de Maven que contiene el frasco que contiene las javax.annotation clases, y ahora GlassFish incrustado — que se ejecuta en el proceso — utilizará las versiones de Java EE 6 de las clases javax.annotation en lugar de las versiones de Java SE 6. Espero que esto te ayude.

Cuestiones relacionadas