Skip to content

Commit 600388b

Browse files
authored
Prepare forbiddenapis 3.0: Update to Java 7 minimum version (#160)
Prepare forbiddenapis 3.0: Update to Java 7 minimum version
1 parent 46237fe commit 600388b

37 files changed

+193
-699
lines changed

build.xml

+15-27
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
</condition>
2727
</fail>
2828

29-
<fail message="Minimum supported Java version is 1.6.">
29+
<fail message="Minimum supported Java version is 1.7.">
3030
<condition>
31-
<not><hasmethod classname="java.lang.String" method="isEmpty"/></not>
31+
<not><available classname="java.lang.invoke.MethodHandle"/></not>
3232
</condition>
3333
</fail>
3434

@@ -54,7 +54,6 @@
5454
-->
5555
<condition property="build.java.runtime" value="${-cleaned.specification.version}" else="unknown">
5656
<or>
57-
<equals arg1="${-cleaned.specification.version}" arg2="1.6"/>
5857
<equals arg1="${-cleaned.specification.version}" arg2="1.7"/>
5958
<equals arg1="${-cleaned.specification.version}" arg2="1.8"/>
6059
<equals arg1="${-cleaned.specification.version}" arg2="9"/>
@@ -68,9 +67,8 @@
6867

6968
<property name="build.java.info" value="${java.version} / JVM: ${java.vm.name} / Vendor: ${java.vendor} / OS: ${os.name} (${os.version})"/>
7069

71-
<condition property="is.java-6-7">
70+
<condition property="is.java7">
7271
<or>
73-
<equals arg1="${build.java.runtime}" arg2="1.6"/>
7472
<equals arg1="${build.java.runtime}" arg2="1.7"/>
7573
</or>
7674
</condition>
@@ -79,7 +77,7 @@
7977
<condition property="build.compiler" value="javac1.7">
8078
<and>
8179
<not>
82-
<isset property="is.java-6-7"/>
80+
<isset property="is.java7"/>
8381
</not>
8482
<or>
8583
<antversion exactly="1.8.3" />
@@ -88,19 +86,19 @@
8886
</and>
8987
</condition>
9088

91-
<!-- With Java 6 and Java 7, the HTTPS access to Maven central is broken, workaround (no TLS 1.2 support): -->
89+
<!-- With Java 7, the HTTPS access to Maven central is broken, workaround (no TLS 1.2 support): -->
9290
<condition property="ivy.maven-central.backup" value="http://insecure.repo1.maven.org/maven2" else="https://repo1.maven.org/maven2">
93-
<isset property="is.java-6-7"/>
91+
<isset property="is.java7"/>
9492
</condition>
9593

9694
<condition property="javadoc.doclint.args" value="" else="-Xdoclint:none">
97-
<isset property="is.java-6-7"/>
95+
<isset property="is.java7"/>
9896
</condition>
9997

10098
<property file="${user.home}/build.properties" />
10199
<property file="build.properties" />
102100

103-
<property name="jdk.version" value="1.6"/>
101+
<property name="jdk.version" value="1.7"/>
104102
<property name="maven.version" value="2.2.1"/>
105103
<property name="maven-plugin-plugin.version" value="3.4"/>
106104

@@ -126,7 +124,7 @@
126124
<!-- define Maven coordinates -->
127125
<property name="groupId" value="de.thetaphi" />
128126
<property name="artifactId" value="forbiddenapis" />
129-
<property name="version" value="2.8-SNAPSHOT"/>
127+
<property name="version" value="3.0-SNAPSHOT"/>
130128

131129
<property name="description" value="Allows to parse Java byte code to find invocations of method/class/field signatures and fail build (Apache Ant, Apache Maven, Gradle, or CLI)"/>
132130

@@ -148,14 +146,14 @@
148146

149147
<condition property="tests.supported">
150148
<or>
151-
<equals arg1="${build.java.runtime}" arg2="1.6"/>
152149
<equals arg1="${build.java.runtime}" arg2="1.7"/>
153150
<equals arg1="${build.java.runtime}" arg2="1.8"/>
154151
<equals arg1="${build.java.runtime}" arg2="9"/>
155152
<equals arg1="${build.java.runtime}" arg2="10"/>
156153
<equals arg1="${build.java.runtime}" arg2="11"/>
157154
<equals arg1="${build.java.runtime}" arg2="12"/>
158155
<equals arg1="${build.java.runtime}" arg2="13"/>
156+
<equals arg1="${build.java.runtime}" arg2="14"/>
159157
</or>
160158
</condition>
161159

@@ -195,10 +193,10 @@
195193
<echo level="info" taskname="check-java" message="Java runtime: ${build.java.info}"/>
196194
<local name="java.version-message"/>
197195
<condition property="java.version-message"
198-
value="Java 6 and Java 7 do not support TLS 1.2, so we have to use the insecure Maven Central mirror. If you are building a release, please run the build at least once with Java 8+ to download all Artifacts using HTTPS. If you don't yet have the Gradle Artifacts downloaded, you have to do this anyways."
196+
value="Java 7 does not support TLS 1.2, so we have to use the insecure Maven Central mirror. If you are building a release, please run the build at least once with Java 8+ to download all Artifacts using HTTPS. If you don't yet have the Gradle Artifacts downloaded, you have to do this anyways."
199197
else="You are using Java 8+, so wecan use the HTTPS Maven Repository for downloading artifacts."
200198
>
201-
<isset property="is.java-6-7"/>
199+
<isset property="is.java7"/>
202200
</condition>
203201
<echo level="warn" taskname="check-java" message="${java.version-message}"/>
204202
<ivy:configure file="ivy-settings.xml"/>
@@ -687,9 +685,6 @@
687685
<condition property="-gen.sunmisc">
688686
<available classname="sun.misc.BASE64Encoder"/>
689687
</condition>
690-
<condition property="-gen.jdk7">
691-
<available classname="java.lang.invoke.MethodHandle"/>
692-
</condition>
693688
<condition property="-gen.jdk8">
694689
<hasmethod classname="java.util.Collections" method="emptySortedSet"/>
695690
</condition>
@@ -699,20 +694,13 @@
699694
<echo level="info" message="Generating test classes using sun.misc internal APIs (needs Oracle Java):"/>
700695
<delete dir="src/test/antunit" includes="Oracle*.class"/>
701696
<javac includeantruntime="false" srcdir="src/test/antunit" destdir="src/test/antunit" includes="Oracle*.java"
702-
nowarn="true" source="1.6" target="1.6" debug="true" deprecation="false" encoding="${build.encoding}">
697+
nowarn="true" source="1.7" target="1.7" debug="true" deprecation="false" encoding="${build.encoding}">
703698
<!-- This disables the symbol file used to detect internal APIs while compiling: -->
704699
<compilerarg value="-XDignore.symbol.file=true"/>
705700
</javac>
706701
</target>
707702

708-
<target name="-generate-test-classes-jdk6">
709-
<echo level="info" message="Generating test classes for Java 6:"/>
710-
<delete dir="src/test/antunit" includes="Java6*.class"/>
711-
<javac includeantruntime="false" srcdir="src/test/antunit" destdir="src/test/antunit" includes="Java6*.java"
712-
nowarn="true" source="1.6" target="1.6" debug="true" deprecation="false" encoding="${build.encoding}"/>
713-
</target>
714-
715-
<target name="-generate-test-classes-jdk7" if="-gen.jdk7">
703+
<target name="-generate-test-classes-jdk7">
716704
<echo level="info" message="Generating test classes for Java 7:"/>
717705
<delete dir="src/test/antunit" includes="Java7*.class"/>
718706
<javac includeantruntime="false" srcdir="src/test/antunit" destdir="src/test/antunit" includes="Java7*.java"
@@ -726,7 +714,7 @@
726714
nowarn="true" source="1.8" target="1.8" debug="true" deprecation="false" encoding="${build.encoding}"/>
727715
</target>
728716

729-
<target name="generate-test-classes" depends="-generate-test-classes-init,-generate-test-classes-sunmisc,-generate-test-classes-jdk6,-generate-test-classes-jdk7,-generate-test-classes-jdk8"
717+
<target name="generate-test-classes" depends="-generate-test-classes-init,-generate-test-classes-sunmisc,-generate-test-classes-jdk7,-generate-test-classes-jdk8"
730718
description="Regenerates .class files used by tests if the current JDK version supports it"/>
731719

732720
<target name="show-help-mojo" depends="install-maven-artifacts" description="Shows help about mojo usage">

ivy-settings.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<ibiblio name="gradle" root="https://repo.gradle.org/gradle/libs-releases-local" m2compatible="true" />
2727
<ibiblio name="maven-http-backup" root="${ivy.maven-central.backup}" m2compatible="true" />
2828
<chain name="default" returnFirst="true" checkmodified="true" changingPattern=".*SNAPSHOT">
29-
<resolver ref="maven-http-backup" /><!-- use HTTP with Java 6/7 -->
29+
<resolver ref="maven-http-backup" /><!-- use HTTP with Java 7 -->
3030
<resolver ref="gradle" />
3131
</chain>
3232
</resolvers>

src/main/docs/bundled-signatures.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ <h1>Bundled Signatures Documentation</h1>
2929
<li><strong><tt>jdk-unsafe-*</tt>:</strong> Signatures
3030
of &quot;unsafe&quot; methods that use default charset, default locale, or default timezone. For server applications it is very
3131
stupid to call those methods, as the results will definitely not what the user wants
32-
(for Java <tt>*</tt> = 1.6, 1.7, 1.8, 9, 10, 11, 12, 13, 14; Ant / Maven / Gradle automatically add the compile Java version).</li>
32+
(for Java <tt>*</tt> = 1.7, 1.8, 9, 10, 11, 12, 13, 14; Ant / Maven / Gradle automatically add the compile Java version).</li>
3333

3434
<li><strong><tt>jdk-deprecated-*</tt>:</strong> This disallows all deprecated
35-
methods from the JDK (for Java <tt>*</tt> = 1.6, 1.7, 1.8, 9, 10, 11, 12, 13, 14; Ant / Maven / Gradle automatically add the compile Java version).</li>
35+
methods from the JDK (for Java <tt>*</tt> = 1.7, 1.8, 9, 10, 11, 12, 13, 14; Ant / Maven / Gradle automatically add the compile Java version).</li>
3636

3737
<li><strong><tt>jdk-internal-*</tt>:</strong> Lists all internal packages of the JDK as of <code>Security.getProperty(&quot;package.access&quot;)</code>.
3838
Calling those methods will always trigger security manager and is completely forbidden from Java 9 on
39-
(for Java <tt>*</tt> = 1.6, 1.7, 1.8, 9, 10, 11, 12, 13, 14; Ant / Maven / Gradle automatically add the compile Java version, <em>since forbiddenapis v2.1</em>).</li>
39+
(for Java <tt>*</tt> = 1.7, 1.8, 9, 10, 11, 12, 13, 14; Ant / Maven / Gradle automatically add the compile Java version, <em>since forbiddenapis v2.1</em>).</li>
4040

4141
<li><strong><tt>jdk-non-portable</tt>:</strong> Signatures of all non-portable (like <code>com.sun.management.HotSpotDiagnosticMXBean</code>)
4242
or internal runtime APIs (like <code>sun.misc.Unsafe</code>). This is a superset of <tt>jdk-internal</tt>.<br>

src/main/java/de/thetaphi/forbiddenapis/AsmUtils.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ private static void patchClassMajorVersion(byte[] bytecode, int versionFrom, int
162162
}
163163
}
164164

165-
/** This method is used to read the whole stream into byte array. This allows patching.
166-
* It also works around a bug in ASM 6.1 (https://gitlab.ow2.org/asm/asm/issues/317816). */
165+
/** This method is used to read the whole stream into byte array. This allows patching. */
167166
private static byte[] readStream(final InputStream in) throws IOException {
168167
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
169168
final byte[] data = new byte[4096];

src/main/java/de/thetaphi/forbiddenapis/Checker.java

+9-16
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ public static enum Option {
6969
final EnumSet<Option> options;
7070

7171
/** Classes to check: key is the binary name (dotted) */
72-
final Map<String,ClassSignature> classesToCheck = new HashMap<String,ClassSignature>();
72+
final Map<String,ClassSignature> classesToCheck = new HashMap<>();
7373
/** Cache of loaded classes: key is the binary name (dotted) */
74-
final Map<String,ClassSignature> classpathClassCache = new HashMap<String,ClassSignature>();
74+
final Map<String,ClassSignature> classpathClassCache = new HashMap<>();
7575

7676
final Signatures forbiddenSignatures;
7777

7878
/** descriptors (not internal names) of all annotations that suppress */
79-
final Set<String> suppressAnnotations = new LinkedHashSet<String>();
79+
final Set<String> suppressAnnotations = new LinkedHashSet<>();
8080

8181
public Checker(Logger logger, ClassLoader loader, Option... options) {
8282
this(logger, loader, (options.length == 0) ? EnumSet.noneOf(Option.class) : EnumSet.copyOf(Arrays.asList(options)));
@@ -106,7 +106,7 @@ public Checker(Logger logger, ClassLoader loader, EnumSet<Option> options) {
106106
this.method_Class_getModule = method_Class_getModule;
107107
this.method_Module_getName = method_Module_getName;
108108

109-
final NavigableSet<String> runtimePaths = new TreeSet<String>();
109+
final NavigableSet<String> runtimePaths = new TreeSet<>();
110110

111111
// fall back to legacy behavior:
112112
if (!isSupportedJDK) {
@@ -124,8 +124,8 @@ public Checker(Logger logger, ClassLoader loader, EnumSet<Option> options) {
124124
}
125125
runtimePaths.add(javaHome);
126126
}
127-
// Scan the runtime's bootclasspath, too! This is needed because
128-
// Apple's JDK 1.6 has the main rt.jar outside ${java.home}!
127+
// Scan the runtime's bootclasspath, too! This is needed for
128+
// some JDKs that may have the rt.jar outside ${java.home}!
129129
final RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
130130
if (rb.isBootClassPathSupported()) {
131131
final String cp = rb.getBootClassPath();
@@ -247,9 +247,8 @@ public ClassSignature getClassFromClassLoader(final String clazz) throws ClassNo
247247
if (!isRuntimeClass && options.contains(Option.DISABLE_CLASSLOADING_CACHE)) {
248248
conn.setUseCaches(false);
249249
}
250-
final InputStream in = conn.getInputStream();
251250
final ClassReader cr;
252-
try {
251+
try (final InputStream in = conn.getInputStream()) {
253252
cr = AsmUtils.readAndPatchClass(in);
254253
} catch (IllegalArgumentException iae) {
255254
// if class is too new for this JVM, we try to load it as Class<?> via Jigsaw
@@ -261,12 +260,9 @@ public ClassSignature getClassFromClassLoader(final String clazz) throws ClassNo
261260
return c;
262261
}
263262
}
264-
// unfortunately the ASM IAE has no message, so add good info!
265263
throw new IllegalArgumentException(String.format(Locale.ENGLISH,
266264
"The class file format of '%s' (loaded from location '%s') is too recent to be parsed by ASM.",
267265
clazz, url.toExternalForm()));
268-
} finally {
269-
in.close();
270266
}
271267
final ClassSignature c = new ClassSignature(cr, isRuntimeClass, false);
272268
classpathClassCache.put(clazz, c);
@@ -348,14 +344,11 @@ public boolean hasNoSignatures() {
348344
/** Parses and adds a class from the given stream to the list of classes to check. Closes the stream when parsed (on Exception, too)! Does not log anything. */
349345
public void addClassToCheck(final InputStream in, String name) throws IOException {
350346
final ClassReader reader;
351-
try {
352-
reader = AsmUtils.readAndPatchClass(in);
347+
try (final InputStream in_ = in) {
348+
reader = AsmUtils.readAndPatchClass(in_);
353349
} catch (IllegalArgumentException iae) {
354-
// unfortunately the ASM IAE has no message, so add good info!
355350
throw new IllegalArgumentException(String.format(Locale.ENGLISH,
356351
"The class file format of '%s' is too recent to be parsed by ASM.", name));
357-
} finally {
358-
in.close();
359352
}
360353
final String binaryName = Type.getObjectType(reader.getClassName()).getClassName();
361354
classesToCheck.put(binaryName, new ClassSignature(reader, false, true));

src/main/java/de/thetaphi/forbiddenapis/ClassScanner.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
public final class ClassScanner extends ClassVisitor implements Constants {
4444
private final boolean forbidNonPortableRuntime;
4545
final RelatedClassLookup lookup;
46-
final List<ForbiddenViolation> violations = new ArrayList<ForbiddenViolation>();
46+
final List<ForbiddenViolation> violations = new ArrayList<>();
4747

4848
final Signatures forbiddenSignatures;
4949

@@ -57,7 +57,7 @@ public final class ClassScanner extends ClassVisitor implements Constants {
5757
int currentGroupId = 0;
5858

5959
// Mapping from a (possible) lambda Method to groupId of declaring method
60-
final Map<Method,Integer> lambdas = new HashMap<Method,Integer>();
60+
final Map<Method,Integer> lambdas = new HashMap<>();
6161

6262
// all groups that were disabled due to suppressing annotation
6363
final BitSet suppressedGroups = new BitSet();
@@ -156,7 +156,7 @@ String checkType(Type type) {
156156
type = type.getElementType();
157157
break;
158158
case Type.METHOD:
159-
final ArrayList<String> violations = new ArrayList<String>();
159+
final ArrayList<String> violations = new ArrayList<>();
160160
violation = checkType(type.getReturnType());
161161
if (violation != null) {
162162
violations.add(violation);

src/main/java/de/thetaphi/forbiddenapis/ClassSignature.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ public ClassSignature(final ClassReader classReader, boolean isRuntimeClass, boo
4949
this.className = classReader.getClassName();
5050
this.superName = classReader.getSuperName();
5151
this.interfaces = classReader.getInterfaces();
52-
final Set<Method> methods = new HashSet<Method>();
53-
final Set<String> fields = new HashSet<String>();
54-
final Set<String> signaturePolymorphicMethods = new HashSet<String>();
52+
final Set<Method> methods = new HashSet<>();
53+
final Set<String> fields = new HashSet<>();
54+
final Set<String> signaturePolymorphicMethods = new HashSet<>();
5555
classReader.accept(new ClassVisitor(Opcodes.ASM8) {
5656
@Override
5757
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
@@ -90,9 +90,9 @@ public ClassSignature(final Class<?> clazz, boolean isRuntimeClass) {
9090
for (int i = 0; i < interfClasses.length; i++) {
9191
this.interfaces[i] = Type.getType(interfClasses[i]).getInternalName();
9292
}
93-
final Set<Method> methods = new HashSet<Method>();
94-
final Set<String> fields = new HashSet<String>();
95-
final Set<String> signaturePolymorphicMethods = new HashSet<String>();
93+
final Set<Method> methods = new HashSet<>();
94+
final Set<String> fields = new HashSet<>();
95+
final Set<String> signaturePolymorphicMethods = new HashSet<>();
9696
for (final java.lang.reflect.Method m : clazz.getDeclaredMethods()) {
9797
methods.add(Method.getMethod(m));
9898
if (className.startsWith(SIGNATURE_POLYMORPHIC_PKG_INTERNALNAME) &&

src/main/java/de/thetaphi/forbiddenapis/Signatures.java

+6-9
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ private UnresolvableReporting(boolean reportClassNotFound) {
8686
* <li>classes: key is the internal name (slashed)
8787
* </ul>
8888
*/
89-
final Map<String,String> signatures = new HashMap<String,String>();
89+
final Map<String,String> signatures = new HashMap<>();
9090

9191
/** set of patterns of forbidden classes */
92-
final Set<ClassPatternRule> classPatterns = new LinkedHashSet<ClassPatternRule>();
92+
final Set<ClassPatternRule> classPatterns = new LinkedHashSet<>();
9393

9494
/** if enabled, the bundled signature to enable heuristics for detection of non-portable runtime calls is used */
9595
private boolean forbidNonPortableRuntime = false;
@@ -261,8 +261,7 @@ private void parseSignaturesStream(InputStream in, boolean allowBundled, Set<Str
261261
}
262262

263263
private void parseSignaturesFile(Reader reader, boolean isBundled, Set<String> missingClasses) throws IOException,ParseException {
264-
final BufferedReader r = new BufferedReader(reader);
265-
try {
264+
try (final BufferedReader r = new BufferedReader(reader)) {
266265
String line, defaultMessage = null;
267266
UnresolvableReporting reporter = failOnUnresolvableSignatures ? UnresolvableReporting.FAIL : UnresolvableReporting.WARNING;
268267
while ((line = r.readLine()) != null) {
@@ -285,30 +284,28 @@ private void parseSignaturesFile(Reader reader, boolean isBundled, Set<String> m
285284
addSignature(line, defaultMessage, reporter, missingClasses);
286285
}
287286
}
288-
} finally {
289-
r.close();
290287
}
291288
}
292289

293290
/** Reads a list of bundled API signatures from classpath. */
294291
public void addBundledSignatures(String name, String jdkTargetVersion) throws IOException,ParseException {
295-
final Set<String> missingClasses = new TreeSet<String>();
292+
final Set<String> missingClasses = new TreeSet<>();
296293
addBundledSignatures(name, jdkTargetVersion, true, missingClasses);
297294
reportMissingSignatureClasses(missingClasses);
298295
}
299296

300297
/** Reads a list of API signatures. Closes the Reader when done (on Exception, too)! */
301298
public void parseSignaturesStream(InputStream in, String name) throws IOException,ParseException {
302299
logger.info("Reading API signatures: " + name);
303-
final Set<String> missingClasses = new TreeSet<String>();
300+
final Set<String> missingClasses = new TreeSet<>();
304301
parseSignaturesStream(in, false, missingClasses);
305302
reportMissingSignatureClasses(missingClasses);
306303
}
307304

308305
/** Reads a list of API signatures from a String. */
309306
public void parseSignaturesString(String signatures) throws IOException,ParseException {
310307
logger.info("Reading inline API signatures...");
311-
final Set<String> missingClasses = new TreeSet<String>();
308+
final Set<String> missingClasses = new TreeSet<>();
312309
parseSignaturesFile(new StringReader(signatures), false, missingClasses);
313310
reportMissingSignatureClasses(missingClasses);
314311
}

0 commit comments

Comments
 (0)