Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way for a class within a war to access the META-INF from it's ear?

This need may sound a little convoluted, and if so, then I am open to suggestions as to best practices for implementation. My problem is the following. I have a WAR webapp, which is contained within an EAR. Everything is mavenized. From within my webapp, I am trying to show the artifact ids and version numbers of the ear and the war.

The war is a fairly easy case to handle. I can use simple maven filtering to inject the necessary artifactId/versionId into the war as it is being built. The ear, however is more complicated.

I know there is a META-INF/maven///pom.properties that I can look at in the ear which contains that information, but I cannot see to access it.

I've tried (from within a jsp page) the following without success (all with and without leading /); all calls return null:

getClass().getClassLoader().getResource( "/META-INF/maven/<group>/<artifact>/pom.properties");
getClass().getClassLoader().getResourceAsStream( "/META-INF/maven/<group>/<artifact>/pom.properties");

Is this even feasible using the classloader? Or is it classloader configuration dependent? Is there a better approach to get this information?

I'm currently running tests on JBoss, but the final deployment will be on WebSphere. However, ideally I would like a solution that is not server dependent.

Thanks!

Eric

like image 544
Eric B. Avatar asked Mar 27 '12 20:03

Eric B.


2 Answers

I don't believe it's possible because of the fact that EARs, EJBs and WARs have different classloaders, which are not necessary linked to each other according to an universal, predictable and Java EE-wide scheme.

Recently I came across the similar problem, and the only acceptable solution I found, was specifying env-entry in application.xml and reading it by @Resource injection:

<application xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd"
             version="6">

  <!-- usual stuff goes here -->
  <env-entry>
    <description>application-wide property</description>
    <env-entry-name>java:app/env/AppWideProperty</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>stackoverflow.com</env-entry-value>
  </env-entry>


</application>

and later on in any class:

public class CalcResultCachePool {
  @Resource(lookup="java:app/env/AppWideProperty")
  String appWideProperty;

  //
  //
}
like image 64
andbi Avatar answered Nov 02 '22 04:11

andbi


Have you tried to use the ContextClassLoader of the relevant artifacts? In web applications, the ContextClassLoader is the preferred way of retrieving files from the deployed application's classpath.

Thread.currentThread().getContextClassLoader().getResourceAsStream("/META-INF/maven/<group>/<artifact>/pom.properties");

If you package this code in both the WAR file and in a JAR file in your EAR, this might return you the correct information depending on the classloader.

Disclaimer: This might not work in all application servers the same, since some app servers use a unified classloader for web applications.

like image 38
nwinkler Avatar answered Nov 02 '22 04:11

nwinkler