Background:
We have maven
-based java project, which targets JRE 1.7, but the source code uses lambdas, so we use retrolambda
for transforming Java 8
source code to Java 7
. Also we use StreamSupport backport library when we need streams, function.*, Optional, etc.
Usage of retrolambda
involves configuring the project's both source and target language level to 1.8.
Everything works fine if there are no dependencies on java8 classes or methods (like java.util.stream.*
, java.util.Optional
, or methods introduced in java8
like Collection.forEach
). If there are such usages then build passes, but it fails in runtime, when running under JVM of Java 8.
Question:
My goal is to fail the build in case when such dependencies exist. Is there any way of detecting dependencies on new Java 8
classes/methods in build-time?
I thought about 2 possible options, but I'm not sure whether either of them is doable:
- Some kind of bytecode analyzer for detecting depdencies on predefined classes and methods. Are there such tools/maven plugins?
- Lint (
lint4j
) rules. Not sure whether it's possible to detect dependency on class/method usinglint
rt.jar
of a Java 7 installation. To let the compiler work with lambda expressions, you may have to add a dummy jar to the path, containing aLambdaMetaFactory
class having declarations of its two methods, in case the compiler verifies this. They don’t have to work, you’ll process the compiled code with retrolambda anyway (then, with the actual JRE8). – MerchantableLambdaConversionException
,LambdaMetafactory
andSerializedLambda
inside the JRE7rt.jar
(using an additional dummy jar didn't work in my case. I got "Fatal Error: Unable to find package java.lang in classpath or bootclasspath"). Then point the maven-compiler-plugin to the enhanced rt.jar via its<bootclasspath>
tag. As a test, I compiled the streamsupport sources (sans j8.u.DelegatingSpliterator which uses Java 8 APIs and therefore is not compilable with a Java 7 rt.jar). – Landonlandor