1

Configuring target in Maven ensures the library code is going to run in a previous compiler version, but it does not prevent from failing when running the library with it if its dependencies are a future version.

For instance, given my JDK is Java8 for compiler, if my code uses Optionals, it is going to pass the target 1.7, but will fail when run as it is a class introduced in 1.8, provided as a java internal dependency.

Is there any mechanism that ensures the whole library is 1.7 compliant and therefore kicks off Optionals when compiling?

sepp2k
  • 363,768
  • 54
  • 674
  • 675
Whimusical
  • 6,401
  • 11
  • 62
  • 105
  • 3
    No there isn't. Because libraries are compiled files. – Jens Jul 11 '16 at 12:12
  • Well, theoretically there should be a possibility in case it is possible to check a bytecode signature or something – Whimusical Jul 11 '16 at 12:13
  • 2
    Though a dependency unfortunately does not have a java-version property, see http://stackoverflow.com/questions/2567024/maven-project-dependecy-against-jdk-version . One could also create a maven plugin that does a class scan (easy). – Joop Eggen Jul 11 '16 at 12:19

1 Answers1

3

First defining target/source does not guarantee that you code will work with an other JVM version than the one you have used to compile with (it is unlikely but it happens). The only solution for this is to use maven toolchains which assumes you have the appropriate JDK installed and compile with the correct JDK.

Furthermore for your problem with your libraries you can use the animal-sniffer-maven-plugin which will also check libraries against an JDK signature file...

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>animal-sniffer-maven-plugin</artifactId>
        <version>1.15</version>
        ...
        <configuration>
          ...
          <signature>
            <groupId>org.codehaus.mojo.signature</groupId>
            <artifactId>java17</artifactId>
            <version>1.0</version>
          </signature>
          ...
        </configuration>
        ...
      </plugin>
      ...
    </plugins>
    ...
  </build>
  ...
</project>

So if you run it with your build all libraries your using will be checked against the JDK signature file.

To check also the byte code you can use the maven-enforcer-plugin in combination with the extra-enforcer-rules like this:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.4.1</version>
        <executions>
          <execution>
            <id>enforce-bytecode-version</id>
            <goals>
              <goal>enforce</goal>
            </goals>
            <configuration>
              <rules>
                <enforceBytecodeVersion>
                  <maxJdkVersion>1.7</maxJdkVersion>
                  <excludes>
                    <exclude>org.mindrot:jbcrypt</exclude>
                  </excludes>
                </enforceBytecodeVersion>
              </rules>
              <fail>true</fail>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>extra-enforcer-rules</artifactId>
            <version>1.0-beta-4</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
  [...]
</project>
khmarbaise
  • 92,914
  • 28
  • 189
  • 235