views:

277

answers:

1

I compile my programm against javaee-api. But for Junit testing I must use a specific implementation like glassfish's javaee.jar to avoid errors like java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/persistence/Persistence (see also 1).

So avoid using methods, that are only available in glassfish implementation, I want to compile my artifact with the general api, but run junit with the implementation jar. But both provide equal named classes and inferfaces, so the class loader gets in trouble.

What is the best way to solve this problem? Can I solve this problem with maven?

Thanks a lot

+5  A: 

I think that this is possible. Actually, starting with version 2.0.9, Maven uses the POM order to build the classpath, so you can manipulate it now. And if you combine this with Dependency Scope, it should be possible to achieve what you want. In practical terms, if you place GlassFish's javaee dependency (with a test scope) before the javaee-api dependency, the former should be placed before the later in the test classpath and thus used by unit tests while the later will be used during compile. In theory, this should work but it is kinda fragile so it needs to be carefully documented.

Something like that (with a fictional GFv3 jar):

<dependencies>
  <dependency><!-- this one will be first on the test classpath -->
    <groupId>org.glassfish</groupId>
    <artifactId>javaee</artifactId>
    <version>6.0</version>
    <scope>test</scope>
  <dependency>
  <dependency><!-- this one will be used during compile -->
    <groupId>javax.javaee-api</groupId>
    <artifactId>javaee-api</artifactId>
    <version>6.0</version>
    <scope>provided</scope>
  <dependency>
  ...
</dependencies>
Pascal Thivent
see also http://stackoverflow.com/questions/793054/maven-classpath-order-issues
marabol
I'm using mvn 2.2.1, but your suggestion does not work. I've tried <dependency> <groupId>javaee</groupId> <artifactId>javaee-api</artifactId> <version>5-glassfish-v2.1-b60e</version> <scope>test</scope></dependency><dependency> <groupId>javaee</groupId> <artifactId>javaee-api</artifactId> <version>5</version> <scope>provided</scope></dependency>5-glassfish-v2.1-b60e is my local version provided by glassfish 2.1 b60e
marabol
@marabol What does not work exactly?
Pascal Thivent
It was my fault... The groupid and/or artifactId must differ!
marabol
Maven seams to use the last configuration for groupId:artifactId configured within one poim.xml. So if you configure at first scope "provided" with version "5" and then with same groupId:artifactId scrope "test" with version "5-my-glassfish", maven create an effective pom with only the second one.
marabol
@marabol Thanks for the feedback. This is a very "special" use case but this sounds like a Maven bug.
Pascal Thivent