Skip to content

Commit

Permalink
Merge pull request #3 from jtulach/CtSym
Browse files Browse the repository at this point in the history
Use ct.sym to isolate sigtest from underlaying JDK
  • Loading branch information
jtulach committed Apr 13, 2021
2 parents 9d77e0e + 26a4152 commit e8e3ef8
Show file tree
Hide file tree
Showing 24 changed files with 718 additions and 39 deletions.
7 changes: 5 additions & 2 deletions README.md
Expand Up @@ -23,7 +23,7 @@ e.g. the signature file. Just add following into your own `pom.xml` file:
<plugin>
<groupId>org.netbeans.tools</groupId>
<artifactId>sigtest-maven-plugin</artifactId>
<version>1.3</version>
<version>1.4</version>
<executions>
<execution>
<goals>
Expand All @@ -32,6 +32,7 @@ e.g. the signature file. Just add following into your own `pom.xml` file:
</execution>
</executions>
<configuration>
<release>8</release> <!-- specify version of JDK API to use 6,7,8,...15 -->
<packages>org.yourcompany.app.api,org.yourcompany.help.api</packages>
</configuration>
</plugin>
Expand All @@ -56,7 +57,7 @@ Try the following:
<plugin>
<groupId>org.netbeans.tools</groupId>
<artifactId>sigtest-maven-plugin</artifactId>
<version>1.3</version>
<version>1.4</version>
<executions>
<execution>
<goals>
Expand All @@ -67,6 +68,7 @@ Try the following:
<configuration>
<packages>org.yourcompany.app.api,org.yourcompany.help.api</packages>
<releaseVersion>1.3</releaseVersion>
<release>8</release> <!-- specify version of JDK API to use 6,7,8,...15 -->
</configuration>
</plugin>
```
Expand Down Expand Up @@ -129,6 +131,7 @@ then try:

<packages>org.yourcompany.app.api,org.yourcompany.help.api</packages>
<releaseVersion>1.3</releaseVersion>
<release>8</release> <!-- specify version of JDK API to use 6,7,8,...15 -->
</configuration>
```

Expand Down
58 changes: 56 additions & 2 deletions pom.xml
Expand Up @@ -20,6 +20,7 @@
</scm>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<ct.sym>${java.home}/lib/ct.sym</ct.sym>
</properties>
<build>
<plugins>
Expand All @@ -43,25 +44,70 @@
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>unpack</id>
<phase>process-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>org.netbeans.tools</includeGroupIds>
<includes>**/*</includes>
<exclude>META-INF/**</exclude>
<outputDirectory>${project.build.directory}/classes/META-INF/sigtest/</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>list-sigtest</id>
<phase>process-classes</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>org.netbeans.apitest.ListCtSym</mainClass>
<arguments>
<argument>${project.build.directory}/classes/META-INF/sigtest.ls</argument>
<argument>${project.build.directory}/classes/META-INF/sigtest/</argument>
<argument>2</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<subpackages>org.netbeans.apitest</subpackages>
</configuration>
<version>2.10.3</version>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.1</version>
<version>3.6.0</version>
<configuration>
<extractors>
<extractor>java-annotations</extractor>
Expand Down Expand Up @@ -159,6 +205,14 @@
<version>15.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.netbeans.tools</groupId>
<artifactId>ct-sym</artifactId>
<version>latest</version>
<scope>system</scope>
<systemPath>${ct.sym}</systemPath>
<type>jar</type>
</dependency>
</dependencies>
<description>
Signature test to compare APIs of two versions of JARs
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/sun/tdk/apicover/Main.java
Expand Up @@ -41,6 +41,7 @@
import com.sun.tdk.signaturetest.util.I18NResourceBundle;
import com.sun.tdk.signaturetest.util.OptionInfo;
import com.sun.tdk.apicover.markup.Adapter;
import com.sun.tdk.signaturetest.classpath.Release;

import com.sun.tdk.signaturetest.core.MemberCollectionBuilder.BuildMode;
import com.sun.tdk.signaturetest.sigfile.FileManager;
Expand Down Expand Up @@ -247,7 +248,7 @@ public void decodeOptions(String optionName, String[] args) throws CommandLinePa
}
else if (optionName.equalsIgnoreCase(TS_OPTION)) {
try {
classpath = new ClasspathImpl(true, args[0]);
classpath = new ClasspathImpl(Release.BOOT_CLASS_PATH, args[0]);
} catch (SecurityException e) {
debug(e);
log.println(i18n.getString("Main.error.sec.newclasses"));
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/sun/tdk/signaturetest/Setup.java
Expand Up @@ -192,7 +192,7 @@ protected boolean parseParameters(String[] args) {

parser.addOption(PACKAGE_OPTION, OptionInfo.optionVariableParams(1, OptionInfo.UNLIMITED), optionsDecoder);
parser.addOption(CLASSPATH_OPTION, OptionInfo.requiredOption(1), optionsDecoder);
parser.addOption(USE_BOOT_CP, OptionInfo.optionalFlag(), optionsDecoder);
parser.addOption(USE_BOOT_CP, OptionInfo.optionVariableParams(0, 1), optionsDecoder);
parser.addOption(FILENAME_OPTION, OptionInfo.requiredOption(1), optionsDecoder);

parser.addOption(TESTURL_OPTION, OptionInfo.option(1), optionsDecoder);
Expand Down Expand Up @@ -373,7 +373,7 @@ private boolean create(URL sigFile) {
getLog().println(i18n.getString("Setup.log.classpath", classpathStr));

try {
classpath = new ClasspathImpl(useBootCp, classpathStr);
classpath = new ClasspathImpl(release, classpathStr);
} catch (SecurityException e) {
if (SigTest.debug)
e.printStackTrace();
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/com/sun/tdk/signaturetest/SigTest.java
Expand Up @@ -29,6 +29,7 @@

import com.sun.tdk.signaturetest.classpath.Classpath;
import com.sun.tdk.signaturetest.classpath.ClasspathImpl;
import com.sun.tdk.signaturetest.classpath.Release;
import com.sun.tdk.signaturetest.core.*;
import com.sun.tdk.signaturetest.errors.ErrorFormatter;
import com.sun.tdk.signaturetest.model.AnnotationItem;
Expand Down Expand Up @@ -142,7 +143,7 @@ public abstract class SigTest extends Result implements PluginAPI, Log {
protected String classpathStr = null;

/** search also boot classpath when a class is not found on classpath? */
protected boolean useBootCp;
protected Release release;

/**
* Collector for error messages, or <code>null</code> if log is not required.
Expand Down Expand Up @@ -284,7 +285,15 @@ protected void decodeCommonOptions(String optionName, String[] args) throws Comm
} else if (optionName.equalsIgnoreCase(CLASSPATH_OPTION)) {
classpathStr = args[0];
} else if (optionName.equalsIgnoreCase(USE_BOOT_CP)) {
useBootCp = true;
if (args.length == 0) {
release = Release.BOOT_CLASS_PATH;
} else {
try {
release = Release.find(Integer.parseInt(args[0]));
} catch (NumberFormatException ex) {
throw new CommandLineParserException(i18n.getString("SigTest.error.arg.invalid2", optionName, args[0]));
}
}
} else if (optionName.equalsIgnoreCase(APIVERSION_OPTION)) {
apiVersion = args[0];
} else if (optionName.equalsIgnoreCase(STATIC_OPTION)) {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/sun/tdk/signaturetest/SignatureTest.java
Expand Up @@ -353,7 +353,7 @@ private boolean parseParameters(String[] args) {

// required only in static mode!
parser.addOption(CLASSPATH_OPTION, OptionInfo.option(1), optionsDecoder);
parser.addOption(USE_BOOT_CP, OptionInfo.optionalFlag(), optionsDecoder);
parser.addOption(USE_BOOT_CP, OptionInfo.optionVariableParams(0, 1), optionsDecoder);

parser.addOption(FILENAME_OPTION, OptionInfo.option(1), optionsDecoder);
parser.addOption(FILES_OPTION, OptionInfo.option(1), optionsDecoder);
Expand Down Expand Up @@ -444,14 +444,14 @@ private boolean parseParameters(String[] args) {

// create ClasspathImpl for founding of the added classes
try {
classpath = new ClasspathImpl(useBootCp, classpathStr);
classpath = new ClasspathImpl(release, classpathStr);
} catch (SecurityException e) {
if (SigTest.debug)
e.printStackTrace();
getLog().println(i18n.getString("SignatureTest.error.sec.newclasses"));
}

if (isStatic && classpath.isEmpty() && !useBootCp)
if (isStatic && classpath.isEmpty() && release == null)
return error(i18n.getString("SignatureTest.error.classpath.unspec"));

return passed();
Expand Down
Expand Up @@ -38,6 +38,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.*;

/**
Expand All @@ -62,7 +63,7 @@
* @see com.sun.tdk.signaturetest.classpath.ClasspathEntry
*/
public class ClasspathImpl implements Classpath {
private final boolean useBootCP;
private final Release release;

/*
public class ClassIterator {
Expand Down Expand Up @@ -169,7 +170,7 @@ public String next() {
* directories and zip files become available through the created
* <b>ClasspathImpl</b> instance.
*
* @param useBootCP search JDK's bootclasspath when class isn't found?
* @param release specify how to search JDK's API when class isn't found on class path
* @param classPath Path string listing directories and/or zip files.
* @throws SecurityException The <code>classPath</code> string has
* invalid format.
Expand All @@ -178,8 +179,8 @@ public String next() {
* @see #setListToBegin()
* @see #createPathEntry(ClasspathEntry, String)
*/
public ClasspathImpl(boolean useBootCP, String classPath) {
this.useBootCP = useBootCP;
public ClasspathImpl(Release release, String classPath) {
this.release = release;
init(classPath);
}

Expand Down Expand Up @@ -336,9 +337,8 @@ public InputStream findClass(String name) throws IOException, ClassNotFoundExcep
// just skip this entry
}
}
if (useBootCP) {
final String resourceName = name.replace('.', '/') + ".class";
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(resourceName);
if (release != null) {
InputStream is = release.findClass(name);
if (is != null) {
return is;
}
Expand Down
94 changes: 94 additions & 0 deletions src/main/java/com/sun/tdk/signaturetest/classpath/Release.java
@@ -0,0 +1,94 @@
package com.sun.tdk.signaturetest.classpath;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public final class Release {
public static final Release BOOT_CLASS_PATH = new Release('0', null);

private final char version;
private final String[] prefixes;

private Release(char version, String... prefixes) {
this.version = version;
this.prefixes = prefixes;
}

/**
* Finds version of the JDK API.
* @param version 6, 7, 8, 9, ..., 11, ... 15
* @return found version or null
*/
public static Release find(int version) {
if (version > 15) {
return null;
}
char ch = (char) (version < 10 ? '0' + version : 'A' + (version - 10));
return RELEASES.get(ch);
}

InputStream findClass(String name) {
if (prefixes == null) {
final String resourceName = name.replace('.', '/') + ".class";
return ClassLoader.getSystemClassLoader().getResourceAsStream(resourceName);
} else {
for (String p : prefixes) {
final String resourceName = "/META-INF/sigtest/" + p + "/" + name.replace('.', '/') + ".sig";
InputStream is = Release.class.getResourceAsStream(resourceName);
if (is != null) {
return is;
}
}
return null;
}

}

private static final Map<Character, Release> RELEASES;
static {
List<String> lines = new ArrayList<>();
try {
try (BufferedReader r = new BufferedReader(new InputStreamReader(Release.class.getResourceAsStream("/META-INF/sigtest.ls")))) {
for (;;) {
String l = r.readLine();
if (l == null) {
break;
}
lines.add(l);
}
}
} catch (IOException ex) {
throw new InternalError(ex);
}

Map<Character,List<String>> prefixes = new HashMap<>();
for (String l : lines) {
String[] versionsDir = l.split("/");
String versions = versionsDir[0];
for (int i = 0; i < versions.length(); i++) {
Character ch = versions.charAt(i);
List<String> arr = prefixes.get(ch);
if (arr == null) {
arr = new ArrayList<>();
prefixes.put(ch, arr);
}
arr.add(l);
}
}

Map<Character,Release> releases = new HashMap<>();
for (Map.Entry<Character, List<String>> entry : prefixes.entrySet()) {
Character key = entry.getKey();
List<String> value = entry.getValue();
releases.put(key, new Release(key, value.toArray(new String[0])));
}

RELEASES = releases;
}
}
12 changes: 10 additions & 2 deletions src/main/java/com/sun/tdk/signaturetest/core/ClassCorrector.java
Expand Up @@ -751,9 +751,17 @@ private void removeInvisibleAnnotations(ClassDescription cl) throws ClassNotFoun
for (int i = 0; i < len; ++i) {
String annoName = annotations[i].getName();

boolean documented = classHierarchy.isDocumentedAnnotation(annoName);
boolean documented;
boolean invisible;
try {
documented = classHierarchy.isDocumentedAnnotation(annoName);
invisible = isInvisibleClass(annoName);
} catch (ClassNotFoundException ex) {
documented = false;
invisible = true;
}

if (isInvisibleClass(annoName)) {
if (invisible) {
if (documented && logger.isLoggable(Level.WARNING))
logger.warning(i18n.getString("ClassCorrector.error.invisible_documented_annotation", annoName));
annotations[i] = null;
Expand Down

0 comments on commit e8e3ef8

Please sign in to comment.