1

I needed to change my project to Java 1.7. This causes an error that lots of folks are seeing:

org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException; nested exception is java.lang.reflect.InvocationTargetException: null
...
Caused by: java.lang.UnsupportedClassVersionError: com/.../AppTest : Unsupported major.minor version 51.0

I've seen the many pages saying to configure the maven-surefire-plugin jvm, but this isn't working for me.

Also, my default java IS 1.7, so I don't understand why this should be needed anyway.

$ java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

$ javac -version
javac 1.7.0_45

Also on OS X I thought we're not supposed to be using variables and symlinks, the javahome subsystem is supposed to keep this all sorted out.

$ javahome
/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home

Attempts and errors:

Attempted Fix 1:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <jvm>${env.JAVA_HOME_7}/bin/java</jvm>
    </configuration>
</plugin>

Error 1:

/bin/sh: ${env.JAVA_HOME_7}/bin/java: bad substitution

Attempted Fix 2:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.9</version>
    <configuration>
        <jvm>${jdk.home}/bin/java</jvm>
    </configuration>
</plugin>

Error 2:

/bin/sh: ${jdk.home}/bin/java: bad substitution

Questions:

  • Java 7 is the default, so why should I need to do anything?
  • On OSX, what is the "best practice" for maven?
  • The second failure seems really odd, shouldn't ${jdk.home} be almost "hardwired" in maven?
  • How did Maven get so broken? It puts surefire in the mix, I didn't. And they have directives for setting Java 1.7. So how could this even happen? Is it being worked on?

I eventually did find a workaround:

# I'd rather not put this in my .profile
export JAVA_HOME=`javahome`

# Then in pom.xml I put:
<jvm>${env.JAVA_HOME}/bin/java</jvm>
Mark Bennett
  • 1,446
  • 2
  • 19
  • 37
  • 1
    How about trying with a newer version of surefire plugin - the latest is `2.17` as of date. – Raghuram Apr 30 '14 at 06:18
  • @Raghuram thanks for the suggestion, and I was wondering that too. But I do't specifically call out for surefire in the first place, it's not listed in the dependencies for example. I started the project with just "mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart ...", so I never set a version. – Mark Bennett Apr 30 '14 at 15:55
  • BTW there's a problem with my workaround of "export JAVA_HOME=`javahome`", this doesn't work when I open a new tab in Terminal, I get the error "-bash: javahome: command not found" when the tab is first opened. If I type javahome a second later, in that tab, it works. So presumably the path isn't set. So I'd need to re-order my .profile or put an absolute path to the command. – Mark Bennett Apr 30 '14 at 16:36

2 Answers2

0

Couple of clarifying questions: what are JAVA_HOME_7 and jdk.home? You do not mention what values you have those set to. On my OS X system, I run Maven under Java 7 with JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home/ and I also set my /usr/bin/java to point to that directory, for the sake of compatibility with any utilities that assume a path there. I don't know what constitutes "best practice" (as far as OS configurations, I consider best practice to be a configuration that works and is easily replicated across systems, which my setup is), but you can follow the instructions in this answer to configure JAVA_HOME for Maven and not your entire system- which would save you the edit to your .profile in favor of a Maven specific configuration.

Community
  • 1
  • 1
Rob
  • 100
  • 1
  • 3
  • I don't explicitly set JAVA_HOME_7 nor jdk.home, those were values suggested in posts I found online. I liked the idea of ~/.mavenrc that you linked to, maybe I can do the javahome trick there. – Mark Bennett Apr 30 '14 at 16:38
  • I am not are of JAVA_HOME_7 or jdk.home being set by default in Maven- perhaps the other posts you saw did not mention explicitly those posters set those variables. I am fairly certain JAVA_HOME is going to be what you need, so please do try the .mavenrc method if that is to your liking. – Rob Apr 30 '14 at 16:50
  • Final fix: In ~/.mavenrc I have export JAVA_HOME=`javahome`, and then in pom.xml I have maven-surefire-plugin ${env.JAVA_HOME}/bin/java – Mark Bennett May 01 '14 at 20:02
0

I'm posting a full answer to my own question here because the fix I posted in the comments Rob's answer is incomplete; it creates a new problems when you then work with a Java 6 project. I have a better answer now, and it's easier to read in a full answer.

First of all, if you were to generically define JAVA_HOME in your .mavenrc you're likely to get the following nasty error the next time you work on a Java 1.6 project:

Unresolveable build extension:
Could not find artifact com.sun:tools:jar:1.6 at specified path
    /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/jre/../Classes/classes.jar

To fix both Java 6 and Java 7 projects on the Mac / OSX I believe the best answer is to define different variables for Java 6 and 7 in your ~/.mavenrc file using the OS X javahome command. Then in Java 7 projects call out specifically for the Java 7 variable JAVA_HOME_7. I'm assuming this will extend to Java 8 though I haven't tried it.

In Java 6 projects I don't need any special settings, but JAVA_HOME_6 would be available if I did.

~/.mavenrc

export JAVA_HOME_6=`javahome -v 1.6`
export JAVA_HOME_7=`javahome -v 1.7`

pom.xml of Java 1.7 project

<project ...>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <!-- Set in ~/.mavenrc -->
            <!-- export JAVA_HOME_7=`javahome -v 1.7` -->
            <jvm>${env.JAVA_HOME_7}/bin/java</jvm>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
Mark Bennett
  • 1,446
  • 2
  • 19
  • 37