--- a/langtools/make/build.properties Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/make/build.properties Thu Aug 28 14:53:49 2014 -0700
@@ -68,7 +68,7 @@
# set the following to -version to verify the versions of javac being used
javac.version.opt =
# in time, there should be no exceptions to -Xlint:all
-javac.lint.opts = -Xlint:all -Werror
+javac.lint.opts = -Xlint:all,-deprecation -Werror
# options for the <javadoc> task for javac
#javadoc.jls3.url=http://java.sun.com/docs/books/jls/
--- a/langtools/make/intellij/langtools.iml Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/make/intellij/langtools.iml Thu Aug 28 14:53:49 2014 -0700
@@ -6,10 +6,14 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/bootstrap/gensrc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/genstubs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/share/classes" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/test" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/java.base" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/java.compiler" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/jdk.compiler" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/jdk.dev" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/jdk.javadoc" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
- <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="inheritedJdk" />
</component>
</module>
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Aug 28 14:53:49 2014 -0700
@@ -2196,16 +2196,6 @@
}
@Override
- public Type visitWildcardType(WildcardType t, Boolean recurse) {
- final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
- Type erased = erasure(wildUpperBound(t), recurse);
- if (!annos.isEmpty()) {
- erased = erased.annotatedType(annos);
- }
- return erased;
- }
-
- @Override
public Type visitClassType(ClassType t, Boolean recurse) {
Type erased = t.tsym.erasure(Types.this);
List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Aug 28 14:53:49 2014 -0700
@@ -919,14 +919,14 @@
// Empty bodies are only allowed for
// abstract, native, or interface methods, or for methods
// in a retrofit signature class.
- if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0 &&
- !relax)
- log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
if (tree.defaultValue != null) {
if ((owner.flags() & ANNOTATION) == 0)
log.error(tree.pos(),
"default.allowed.in.intf.annotation.member");
}
+ if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0 &&
+ !relax)
+ log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
} else if ((tree.sym.flags() & ABSTRACT) != 0 && !isDefaultMethod) {
if ((owner.flags() & INTERFACE) != 0) {
log.error(tree.body.pos(), "intf.meth.cant.have.body");
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/BuildState.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/BuildState.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,15 +31,17 @@
import java.util.Map;
import java.util.Set;
+import com.sun.tools.javac.util.Assert;
+
/**
* The build state class captures the source code and generated artifacts
* from a build. There are usually two build states, the previous one (prev),
* loaded from the javac_state file, and the current one (now).
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class BuildState {
private Map<String,Module> modules = new HashMap<>();
@@ -75,7 +77,7 @@
*/
Module findModuleFromPackageName(String pkg) {
int cp = pkg.indexOf(':');
- assert(cp != -1);
+ Assert.check(cp != -1);
String mod = pkg.substring(0, cp);
return lookupModule(mod);
}
@@ -94,7 +96,7 @@
for (Map.Entry<String,Package> j : i.packages().entrySet()) {
Package p = packages.get(j.getKey());
// Check that no two different packages are stored under same name.
- assert(p == null || p == j.getValue());
+ Assert.check(p == null || p == j.getValue());
if (p == null) {
p = j.getValue();
packages.put(j.getKey(),j.getValue());
@@ -102,7 +104,7 @@
for (Map.Entry<String,Source> k : p.sources().entrySet()) {
Source s = sources.get(k.getKey());
// Check that no two different sources are stored under same name.
- assert(s == null || s == k.getValue());
+ Assert.check(s == null || s == k.getValue());
if (s == null) {
s = k.getValue();
sources.put(k.getKey(), k.getValue());
@@ -111,7 +113,7 @@
for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
File f = artifacts.get(g.getKey());
// Check that no two artifacts are stored under the same file.
- assert(f == null || f == g.getValue());
+ Assert.check(f == null || f == g.getValue());
if (f == null) {
f = g.getValue();
artifacts.put(g.getKey(), g.getValue());
@@ -134,13 +136,13 @@
for (Map.Entry<String,Package> j : i.packages().entrySet()) {
Package p = packages.get(j.getKey());
// Check that no two different packages are stored under same name.
- assert(p == null || p == j.getValue());
+ Assert.check(p == null || p == j.getValue());
p = j.getValue();
packages.put(j.getKey(),j.getValue());
for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
File f = artifacts.get(g.getKey());
// Check that no two artifacts are stored under the same file.
- assert(f == null || f == g.getValue());
+ Assert.check(f == null || f == g.getValue());
artifacts.put(g.getKey(), g.getValue());
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java Thu Aug 28 14:53:49 2014 -0700
@@ -36,19 +36,18 @@
import java.util.Properties;
import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
/**
* The clean properties transform should not be necessary.
* Eventually we will cleanup the property file sources in the OpenJDK instead.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
-public class CleanProperties implements Transformer
-{
+public class CleanProperties implements Transformer {
public void setExtra(String e) {
// Any extra information is ignored for clean properties.
}
@@ -57,7 +56,7 @@
// Any extra information is ignored for clean properties.
}
- public boolean transform(JavacService javacService,
+ public boolean transform(Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses,
@@ -70,8 +69,7 @@
boolean incremental,
int numCores,
PrintStream out,
- PrintStream err)
- {
+ PrintStream err) {
boolean rc = true;
for (String pkgName : pkgSrcs.keySet()) {
String pkgNameF = pkgName.replace('.',File.separatorChar);
@@ -87,9 +85,12 @@
return rc;
}
- boolean clean(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel,
- Map<String,Set<URI>> packageArtifacts)
- {
+ boolean clean(String pkgName,
+ String pkgNameF,
+ File src,
+ File destRoot,
+ int debugLevel,
+ Map<String,Set<URI>> packageArtifacts) {
// Load the properties file.
Properties p = new Properties();
try {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileChunk.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileChunk.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,10 +33,10 @@
* A compile chunk is a list of sources/packages to be compiled. Possibly a subset of
* the total number of sources/packages to be compiled for this sjavac invocation.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class CompileChunk implements Comparable<CompileChunk> {
public int numPackages;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Thu Aug 28 14:53:49 2014 -0700
@@ -30,13 +30,12 @@
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Random;
import java.util.Set;
import java.util.Map;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.server.CompilationResult;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SysInfo;
/**
@@ -67,7 +66,7 @@
args = a;
}
- public boolean transform(final JavacService javacService,
+ public boolean transform(final Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs,
final Set<URI> visibleSources,
final Map<URI,Set<String>> visibleClasses,
@@ -86,18 +85,12 @@
boolean concurrentCompiles = true;
// Fetch the id.
- String idOpt = Util.extractStringOption("id", args.getServerConf());
- if (idOpt == null || idOpt.equals("")) {
- // No explicit id set. Create a random id so that the requests can be
- // grouped properly in the server.
- idOpt = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
- }
- final String id = idOpt;
+ final String id = Util.extractStringOption("id", sjavac.serverSettings());
// Only keep portfile and sjavac settings..
- String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), args.getServerConf());
+ String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), sjavac.serverSettings());
// Get maximum heap size from the server!
- SysInfo sysinfo = javacService.getSysInfo();
+ SysInfo sysinfo = sjavac.getSysInfo();
if (sysinfo.numCores == -1) {
Log.error("Could not query server for sysinfo!");
return false;
@@ -222,7 +215,7 @@
requests[i] = new Thread() {
@Override
public void run() {
- rn[ii] = javacService.compile("n/a",
+ rn[ii] = sjavac.compile("n/a",
id + "-" + ii,
args.prepJavacArgs(),
Collections.<File>emptyList(),
@@ -253,6 +246,8 @@
requests[ii].run();
// If there was an error, then stop early when running single threaded.
if (rn[i].returnCode != 0) {
+ Log.info(rn[i].stdout);
+ Log.error(rn[i].stderr);
return false;
}
}
@@ -269,6 +264,8 @@
for (int i=0; i<numCompiles; ++i) {
if (compileChunks[i].srcs.size() > 0) {
if (rn[i].returnCode != 0) {
+ Log.info(rn[i].stdout);
+ Log.error(rn[i].stderr);
rc = false;
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java Thu Aug 28 14:53:49 2014 -0700
@@ -38,20 +38,19 @@
import java.util.Map;
import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
/**
* Compile properties transform a properties file into a Java source file.
* Java has built in support for reading properties from either a text file
* in the source or a compiled java source file.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
-public class CompileProperties implements Transformer
-{
+public class CompileProperties implements Transformer {
// Any extra information passed from the command line, for example if:
// -tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
// then extra will be "sun.util.resources.LocaleNamesBundle"
@@ -64,7 +63,7 @@
public void setExtra(Options a) {
}
- public boolean transform(JavacService javacService,
+ public boolean transform(Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java Thu Aug 28 14:53:49 2014 -0700
@@ -32,16 +32,16 @@
import java.util.Map;
import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
/**
* The copy file transform simply copies a matching file from -src to -d .
* Such files are typically images, xml documents and other data files.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class CopyFile implements Transformer {
@@ -51,7 +51,7 @@
public void setExtra(Options a) {
}
- public boolean transform(JavacService javacService,
+ public boolean transform(Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java Thu Aug 28 14:53:49 2014 -0700
@@ -26,7 +26,6 @@
package com.sun.tools.sjavac;
import java.io.*;
-import java.nio.file.Path;
import java.util.Collections;
import java.util.Date;
import java.util.Set;
@@ -39,20 +38,18 @@
import java.util.*;
import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.options.SourceLocation;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
/**
* The javac state class maintains the previous (prev) and the current (now)
* build states and everything else that goes into the javac_state file.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
-public class JavacState
-{
+public class JavacState {
// The arguments to the compile. If not identical, then it cannot
// be an incremental build!
String theArgs;
@@ -60,7 +57,6 @@
int numCores;
// The bin_dir/javac_state
- private String javacStateFilename;
private File javacState;
// The previous build state is loaded from javac_state
@@ -99,7 +95,7 @@
private Set<String> recompiledPackages;
// The output directories filled with tasty artifacts.
- private File binDir, gensrcDir, headerDir;
+ private File binDir, gensrcDir, headerDir, stateDir;
// The current status of the file system.
private Set<File> binArtifacts;
@@ -128,7 +124,11 @@
// Where to send stdout and stderr.
private PrintStream out, err;
- JavacState(Options options, boolean removeJavacState, PrintStream o, PrintStream e) {
+ // Command line options.
+ private Options options;
+
+ JavacState(Options op, boolean removeJavacState, PrintStream o, PrintStream e) {
+ options = op;
out = o;
err = e;
numCores = options.getNumCores();
@@ -136,8 +136,8 @@
binDir = Util.pathToFile(options.getDestDir());
gensrcDir = Util.pathToFile(options.getGenSrcDir());
headerDir = Util.pathToFile(options.getHeaderDir());
- javacStateFilename = binDir.getPath()+File.separator+"javac_state";
- javacState = new File(javacStateFilename);
+ stateDir = Util.pathToFile(options.getStateDir());
+ javacState = new File(stateDir, "javac_state");
if (removeJavacState && javacState.exists()) {
javacState.delete();
}
@@ -148,7 +148,7 @@
// We do not want to risk building a broken incremental build.
// BUT since the makefiles still copy things straight into the bin_dir et al,
// we avoid deleting files here, if the option --permit-unidentified-classes was supplied.
- if (!options.isUnidentifiedArtifactPermitted()) {
+ if (!options.areUnidentifiedArtifactsPermitted()) {
deleteContents(binDir);
deleteContents(gensrcDir);
deleteContents(headerDir);
@@ -268,7 +268,7 @@
*/
public void save() throws IOException {
if (!needsSaving) return;
- try (FileWriter out = new FileWriter(javacStateFilename)) {
+ try (FileWriter out = new FileWriter(javacState)) {
StringBuilder b = new StringBuilder();
long millisNow = System.currentTimeMillis();
Date d = new Date(millisNow);
@@ -311,7 +311,7 @@
boolean newCommandLine = false;
boolean syntaxError = false;
- try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) {
+ try (BufferedReader in = new BufferedReader(new FileReader(db.javacState))) {
for (;;) {
String l = in.readLine();
if (l==null) break;
@@ -512,7 +512,8 @@
allKnownArtifacts.add(javacState);
for (File f : binArtifacts) {
- if (!allKnownArtifacts.contains(f)) {
+ if (!allKnownArtifacts.contains(f) &&
+ !options.isUnidentifiedArtifactPermitted(f.getAbsolutePath())) {
Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
f.delete();
}
@@ -605,13 +606,16 @@
/**
* Recursively delete a directory and all its contents.
*/
- private static void deleteContents(File dir) {
+ private void deleteContents(File dir) {
if (dir != null && dir.exists()) {
for (File f : dir.listFiles()) {
if (f.isDirectory()) {
deleteContents(f);
}
- f.delete();
+ if (!options.isUnidentifiedArtifactPermitted(f.getAbsolutePath())) {
+ Log.debug("Removing "+f.getAbsolutePath());
+ f.delete();
+ }
}
}
}
@@ -648,7 +652,7 @@
/**
* Compile all the java sources. Return true, if it needs to be called again!
*/
- public boolean performJavaCompilations(JavacService javacService,
+ public boolean performJavaCompilations(Sjavac sjavac,
Options args,
Set<String> recentlyCompiled,
boolean[] rcValue) {
@@ -656,7 +660,7 @@
suffixRules.put(".java", compileJavaPackages);
compileJavaPackages.setExtra(args);
- rcValue[0] = perform(javacService, binDir, suffixRules);
+ rcValue[0] = perform(sjavac, binDir, suffixRules);
recentlyCompiled.addAll(taintedPackages());
clearTaintedPackages();
boolean again = !packagesWithChangedPublicApis.isEmpty();
@@ -686,10 +690,9 @@
* For all packages, find all sources belonging to the package, group the sources
* based on their transformers and apply the transformers on each source code group.
*/
- private boolean perform(JavacService javacService,
+ private boolean perform(Sjavac sjavac,
File outputDir,
- Map<String,Transformer> suffixRules)
- {
+ Map<String,Transformer> suffixRules) {
boolean rc = true;
// Group sources based on transforms. A source file can only belong to a single transform.
Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<>();
@@ -713,7 +716,7 @@
Map<String,String> packagePublicApis =
Collections.synchronizedMap(new HashMap<String, String>());
- boolean r = t.transform(javacService,
+ boolean r = t.transform(sjavac,
srcs,
visibleSrcs,
visibleClasses,
@@ -791,9 +794,7 @@
* Used to detect bugs where the makefile and sjavac have different opinions on which files
* should be compiled.
*/
- public void compareWithMakefileList(File makefileSourceList)
- throws ProblemException
- {
+ public void compareWithMakefileList(File makefileSourceList) throws ProblemException {
// If we are building on win32 using for example cygwin the paths in the makefile source list
// might be /cygdrive/c/.... which does not match c:\....
// We need to adjust our calculated sources to be identical, if necessary.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Log.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Log.java Thu Aug 28 14:53:49 2014 -0700
@@ -31,10 +31,10 @@
* Utility class only for sjavac logging.
* The log level can be set using for example --log=DEBUG on the sjavac command line.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class Log {
private static PrintStream out, err;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Main.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Main.java Thu Aug 28 14:53:49 2014 -0700
@@ -31,19 +31,21 @@
import java.nio.file.Path;
import java.nio.file.Files;
+import com.sun.tools.sjavac.client.SjavacClient;
+import com.sun.tools.sjavac.comp.SjavacImpl;
+import com.sun.tools.sjavac.comp.PooledSjavac;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.options.SourceLocation;
-import com.sun.tools.sjavac.server.JavacService;
-import com.sun.tools.sjavac.server.JavacServer;
-import com.sun.tools.sjavac.server.JavacServiceClient;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SjavacServer;
/**
* The main class of the smart javac wrapper tool.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class Main {
@@ -163,13 +165,19 @@
return;
}
// Spawn a background server.
- int rc = JavacServer.startServer(args[0], System.err);
- System.exit(rc);
+ try {
+ SjavacServer server = new SjavacServer(args[0], System.err);
+ int rc = server.startServer();
+ System.exit(rc);
+ } catch (IOException ioex) {
+ Log.error("IOException caught: " + ioex);
+ System.exit(-1);
+ }
}
Main main = new Main();
int rc = main.go(args, System.out, System.err);
// Remove the portfile, but only if this background=false was used.
- JavacServer.cleanup(args);
+ SjavacServer.cleanup(args);
System.exit(rc);
}
@@ -205,6 +213,9 @@
if (!createIfMissing(options.getDestDir()))
return -1;
+ if (!createIfMissing(options.getStateDir()))
+ return -1;
+
Path gensrc = options.getGenSrcDir();
if (gensrc != null && !createIfMissing(gensrc))
return -1;
@@ -302,7 +313,7 @@
// For examples, files that have been manually copied into these dirs.
// Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
// in javac_state) have already been removed when the javac_state was loaded.
- if (!options.isUnidentifiedArtifactPermitted()) {
+ if (!options.areUnidentifiedArtifactsPermitted()) {
javac_state.removeUnidentifiedArtifacts();
}
// Go through all sources and taint all packages that miss artifacts.
@@ -338,15 +349,22 @@
// Collect the name of all compiled packages.
Set<String> recently_compiled = new HashSet<>();
boolean[] rc = new boolean[1];
+ Sjavac sjavac;
+ boolean background = Util.extractBooleanOption("background", options.getServerConf(), true);
do {
// Clean out artifacts in tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
- // Create a JavacService to delegate the actual compilation to.
- // Currently sjavac always connects to a server through a socket
- // regardless if sjavac runs as a background service or not.
- // This will most likely change in the future.
- JavacService javacService = new JavacServiceClient(options.getServerConf());
- again = javac_state.performJavaCompilations(javacService, options, recently_compiled, rc);
+ // Create an sjavac implementation to be used for compilation
+ if (background) {
+ sjavac = new SjavacClient(options);
+ } else {
+ int poolsize = Util.extractIntOption("poolsize", options.getServerConf());
+ if (poolsize <= 0)
+ poolsize = Runtime.getRuntime().availableProcessors();
+ sjavac = new PooledSjavac(new SjavacImpl(), poolsize);
+ }
+
+ again = javac_state.performJavaCompilations(sjavac, options, recently_compiled, rc);
if (!rc[0]) break;
} while (again);
// Only update the state if the compile went well.
@@ -357,6 +375,8 @@
// Remove artifacts that were generated during the last compile, but not this one.
javac_state.removeSuperfluousArtifacts(recently_compiled);
}
+ if (!background)
+ sjavac.shutdown();
return rc[0] ? 0 : -1;
} catch (ProblemException e) {
Log.error(e.getMessage());
@@ -375,8 +395,6 @@
err = "Please specify output directory.";
} else if (options.isJavaFilesAmongJavacArgs()) {
err = "Sjavac does not handle explicit compilation of single .java files.";
- } else if (options.isAtFilePresent()) {
- err = "Sjavac does not handle @-files.";
} else if (options.getServerConf() == null) {
err = "No server configuration provided.";
} else if (!options.getImplicitPolicy().equals("none")) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Module.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Module.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,10 +36,10 @@
* The module is the root of a set of packages/sources/artifacts.
* At the moment there is only one module in use, the empty/no-name/default module.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class Module implements Comparable<Module> {
private String name;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import com.sun.tools.javac.util.Assert;
/**
* The Package class maintains meta information about a package.
@@ -54,10 +55,10 @@
* the visible recompilation of the dependent packages indicates how much circular
* dependencies your code has.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class Package implements Comparable<Package> {
// The module this package belongs to. (There is a legacy module with an empty string name,
@@ -83,9 +84,9 @@
public Package(Module m, String n) {
int c = n.indexOf(":");
- assert(c != -1);
+ Assert.check(c != -1);
String mn = n.substring(0,c);
- assert(m.name().equals(m.name()));
+ Assert.check(m.name().equals(m.name()));
name = n;
dirname = n.replace('.', File.separatorChar);
if (m.name().length() > 0) {
@@ -256,7 +257,7 @@
}
public void setArtifacts(Set<URI> as) {
- assert(!artifacts.isEmpty());
+ Assert.check(!artifacts.isEmpty());
artifacts = new HashMap<>();
addArtifacts(as);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/ProblemException.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/ProblemException.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,10 @@
/**
* Used to signal serious problems when running sjavac.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class ProblemException extends Exception {
static final long serialVersionUID = -3387516993124229949L;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java Thu Aug 28 14:53:49 2014 -0700
@@ -37,10 +37,10 @@
* The class also knows how to find source files (scanRoot) given include/exclude
* patterns and a root.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class Source implements Comparable<Source> {
// The package the source belongs to.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java Thu Aug 28 14:53:49 2014 -0700
@@ -31,7 +31,7 @@
import java.util.Map;
import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
/**
* The transform interface is used to transform content inside a package, from one form to another.
@@ -39,13 +39,12 @@
* but can also be an unpredictable number of generated source files (eg idl2java)
* or a single predictable output file (eg when copying,cleaning or compiling a properties file).
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
-public interface Transformer
-{
+public interface Transformer {
/**
* The transform method takes a set of package names, mapped to their source files and to the
* pubapis of the packages.
@@ -83,7 +82,7 @@
* If num_cores is set to a non-zero value. The transform should attempt to use no more than these
* number of threads for heavy work.
*/
- boolean transform(JavacService javacService,
+ boolean transform(Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSources,
Map<URI,Set<String>> visibleClasses,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java Thu Aug 28 14:53:49 2014 -0700
@@ -26,8 +26,6 @@
package com.sun.tools.sjavac;
import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
@@ -37,10 +35,10 @@
/**
* Utilities.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class Util {
@@ -64,7 +62,8 @@
public static String justPackageName(String pkgName) {
int c = pkgName.indexOf(":");
- assert(c != -1);
+ if (c == -1)
+ throw new IllegalArgumentException("Expected ':' in package name (" + pkgName + ")");
return pkgName.substring(c+1);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.client;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+import com.sun.tools.sjavac.Log;
+import com.sun.tools.sjavac.ProblemException;
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.PortFile;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SjavacServer;
+import com.sun.tools.sjavac.server.SysInfo;
+import com.sun.tools.sjavac.options.Options;
+
+/**
+ * Sjavac implementation that delegates requests to a SjavacServer.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class SjavacClient implements Sjavac {
+
+ // The id can perhaps be used in the future by the javac server to reuse the
+ // JavaCompiler instance for several compiles using the same id.
+ private final String id;
+ private final String portfileName;
+ private final String logfile;
+ private final String stdouterrfile;
+ private final boolean background;
+
+ // Default keepalive for server is 120 seconds.
+ // I.e. it will accept 120 seconds of inactivity before quitting.
+ private final int keepalive;
+ private final int poolsize;
+
+ // The sjavac option specifies how the server part of sjavac is spawned.
+ // If you have the experimental sjavac in your path, you are done. If not, you have
+ // to point to a com.sun.tools.sjavac.Main that supports --startserver
+ // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
+ private final String sjavacForkCmd;
+
+ // Wait 2 seconds for response, before giving up on javac server.
+ static int CONNECTION_TIMEOUT = 2000;
+ static int MAX_CONNECT_ATTEMPTS = 3;
+ static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 2000;
+
+ // Store the server conf settings here.
+ private final String settings;
+
+ public SjavacClient(Options options) {
+ String tmpServerConf = options.getServerConf();
+ String serverConf = (tmpServerConf!=null)? tmpServerConf : "";
+ String tmpId = Util.extractStringOption("id", serverConf);
+ id = (tmpId!=null) ? tmpId : "id"+(((new java.util.Random()).nextLong())&Long.MAX_VALUE);
+ String p = Util.extractStringOption("portfile", serverConf);
+ portfileName = (p!=null) ? p : options.getStateDir().toFile().getAbsolutePath()+File.separatorChar+"javac_server";
+ logfile = Util.extractStringOption("logfile", serverConf, portfileName + ".javaclog");
+ stdouterrfile = Util.extractStringOption("stdouterrfile", serverConf, portfileName + ".stdouterr");
+ background = Util.extractBooleanOption("background", serverConf, true);
+ sjavacForkCmd = Util.extractStringOption("sjavac", serverConf, "sjavac");
+ int poolsize = Util.extractIntOption("poolsize", serverConf);
+ keepalive = Util.extractIntOption("keepalive", serverConf, 120);
+
+ this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
+ settings = (serverConf.equals("")) ? "id="+id+",portfile="+portfileName : serverConf;
+ }
+
+ /**
+ * Hand out the server settings.
+ * @return The server settings, possibly a default value.
+ */
+ public String serverSettings() {
+ return settings;
+ }
+
+ /**
+ * Make a request to the server only to get the maximum possible heap size to use for compilations.
+ *
+ * @param port_file The port file used to synchronize creation of this server.
+ * @param id The identify of the compilation.
+ * @param out Standard out information.
+ * @param err Standard err information.
+ * @return The maximum heap size in bytes.
+ */
+ @Override
+ public SysInfo getSysInfo() {
+ try (Socket socket = tryConnect()) {
+ // The ObjectInputStream constructor will block until the
+ // corresponding ObjectOutputStream has written and flushed the
+ // header, so it is important that the ObjectOutputStreams on server
+ // and client are opened before the ObjectInputStreams.
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+ oos.writeObject(id);
+ oos.writeObject(SjavacServer.CMD_SYS_INFO);
+ oos.flush();
+ return (SysInfo) ois.readObject();
+ } catch (IOException | ClassNotFoundException ex) {
+ Log.error("[CLIENT] Exception caught: " + ex);
+ StringWriter sw = new StringWriter();
+ ex.printStackTrace(new PrintWriter(sw));
+ }
+ return null;
+ }
+
+ @Override
+ public CompilationResult compile(String protocolId,
+ String invocationId,
+ String[] args,
+ List<File> explicitSources,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources) {
+ CompilationResult result;
+ try (Socket socket = tryConnect()) {
+ // The ObjectInputStream constructor will block until the
+ // corresponding ObjectOutputStream has written and flushed the
+ // header, so it is important that the ObjectOutputStreams on server
+ // and client are opened before the ObjectInputStreams.
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+ oos.writeObject(id);
+ oos.writeObject(SjavacServer.CMD_COMPILE);
+ oos.writeObject(protocolId);
+ oos.writeObject(invocationId);
+ oos.writeObject(args);
+ oos.writeObject(explicitSources);
+ oos.writeObject(sourcesToCompile);
+ oos.writeObject(visibleSources);
+ oos.flush();
+ result = (CompilationResult) ois.readObject();
+ } catch (IOException | ClassNotFoundException ex) {
+ Log.error("Exception caught: " + ex);
+ result = new CompilationResult(CompilationResult.ERROR_FATAL);
+ result.stderr = ex.getMessage();
+ }
+ return result;
+ }
+
+ private Socket tryConnect() throws IOException {
+
+ PortFile portFile;
+ try {
+ // This should be taken care of at a higher level (JDK-8048451)
+ portFile = SjavacServer.getPortFile(portfileName);
+ } catch (FileNotFoundException e) {
+ // Reached for instance if directory of port file does not exist
+ Log.error("Port file inaccessable: " + e);
+ throw new RuntimeException(e);
+ }
+ for (int i = 0; i < MAX_CONNECT_ATTEMPTS; i++) {
+ Log.info(String.format("Trying to connect (attempt %d of %d)",
+ i+1, MAX_CONNECT_ATTEMPTS));
+ try {
+ if (!makeSureServerIsRunning(portFile))
+ continue;
+ Socket socket = new Socket();
+ InetAddress localhost = InetAddress.getByName(null);
+ socket.connect(new InetSocketAddress(localhost, portFile.getPort()),
+ CONNECTION_TIMEOUT);
+ return socket;
+ } catch (ProblemException | IOException ex) {
+ Log.error("Caught exception during tryConnect: " + ex);
+ }
+
+ try {
+ Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ throw new IOException("Could not connect to server");
+ }
+
+ private boolean makeSureServerIsRunning(PortFile portFile)
+ throws IOException, ProblemException, FileNotFoundException {
+
+ synchronized (portFile) {
+ portFile.lock();
+ portFile.getValues();
+ portFile.unlock();
+ }
+
+ if (!portFile.containsPortInfo()) {
+ String forkCmd = SjavacServer.fork(sjavacForkCmd,
+ portFile.getFilename(),
+ logfile,
+ poolsize,
+ keepalive,
+ System.err,
+ stdouterrfile,
+ background);
+ if (!portFile.waitForValidValues()) {
+ // This can be simplified once JDK-8048457 has been addressed
+ // since we won't have an SjavacClient if background = false
+ if (background) {
+ // There seems be some problem with spawning the external
+ // process (for instance no fork command provided and no
+ // sjavac on path)
+ StringWriter sw = new StringWriter();
+ SjavacClient.printFailedAttempt(forkCmd,
+ stdouterrfile,
+ new PrintWriter(sw));
+ Log.error(sw.toString());
+ }
+ }
+ }
+ return portFile.containsPortInfo();
+ }
+
+
+ public static void printFailedAttempt(String cmd, String f, PrintWriter err) {
+ err.println("---- Failed to start javac server with this command -----");
+ err.println(cmd);
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(f));
+ err.println("---- stdout/stderr output from attempt to start javac server -----");
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ break;
+ }
+ err.println(l);
+ }
+ err.println("------------------------------------------------------------------");
+ } catch (Exception e) {
+ err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
+ }
+ }
+
+ @Override
+ public void shutdown() {
+ // Nothing to clean up
+ }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/AttrWithDeps.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/AttrWithDeps.java Thu Aug 28 14:53:49 2014 -0700
@@ -30,10 +30,10 @@
/** Subclass to Attr that overrides reportDepedence.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class AttrWithDeps extends Attr {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/Dependencies.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/Dependencies.java Thu Aug 28 14:53:49 2014 -0700
@@ -34,6 +34,7 @@
import java.util.Set;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Name;
@@ -41,10 +42,10 @@
/** Utility class containing dependency information between packages
* and the pubapi for a package.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class Dependencies {
protected static final Context.Key<Dependencies> dependenciesKey = new Context.Key<>();
@@ -154,7 +155,7 @@
Name n = ((ClassSymbol)e).fullname;
Name p = ((ClassSymbol)e).packge().fullname;
StringBuffer sb = publicApiPerClass.get(n);
- assert(sb == null);
+ Assert.check(sb == null);
sb = new StringBuffer();
PubapiVisitor v = new PubapiVisitor(sb);
v.visit(e);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavaCompilerWithDeps.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavaCompilerWithDeps.java Thu Aug 28 14:53:49 2014 -0700
@@ -32,29 +32,29 @@
/** Subclass to Resolve that overrides collect.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class JavaCompilerWithDeps extends JavaCompiler {
/** The dependency database
*/
protected Dependencies deps;
- protected JavacServiceImpl javacService;
+ protected SjavacErrorHandler errorHandler;
- public JavaCompilerWithDeps(Context context, JavacServiceImpl jsi) {
+ public JavaCompilerWithDeps(Context context, SjavacErrorHandler eh) {
super(context);
deps = Dependencies.instance(context);
- javacService = jsi;
+ errorHandler = eh;
needRootClasses = true;
}
- public static void preRegister(Context context, final JavacServiceImpl t) {
+ public static void preRegister(Context context, final SjavacErrorHandler eh) {
context.put(compilerKey, new Context.Factory<JavaCompiler>() {
public JavaCompiler make(Context c) {
- JavaCompiler instance = new JavaCompilerWithDeps(c, t);
+ JavaCompiler instance = new JavaCompilerWithDeps(c, eh);
c.put(JavaCompiler.class, instance);
return instance;
}
@@ -97,7 +97,7 @@
// Now check if the truncated uri ends with the path. (It does not == failure!)
if (path.length() > 0 && !path.equals("/unnamed package/") && !pp.endsWith(path)) {
- javacService.logError("Error: The source file "+sym.sourcefile.getName()+
+ errorHandler.logError("Error: The source file "+sym.sourcefile.getName()+
" is located in the wrong package directory, because it contains the class "+
sym.getQualifiedName());
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavacServiceImpl.java Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.comp;
-
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import javax.tools.JavaCompiler.CompilationTask;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-
-import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.sjavac.Util;
-import com.sun.tools.sjavac.server.CompilationResult;
-import com.sun.tools.sjavac.server.JavacServer;
-import com.sun.tools.sjavac.server.JavacService;
-import com.sun.tools.sjavac.server.SysInfo;
-
-public class JavacServiceImpl implements JavacService {
-
- JavacServer javacServer;
- private ThreadLocal<Boolean> forcedExit;
-
- public JavacServiceImpl(JavacServer javacServer) {
- this.javacServer = javacServer;
-
- }
-
- public void logError(String msg) {
-// stderr.println(msg);
- forcedExit.set(true);
- }
-
- @Override
- public SysInfo getSysInfo() {
- return new SysInfo(Runtime.getRuntime().availableProcessors(),
- Runtime.getRuntime().maxMemory());
- }
-
- @Override
- public CompilationResult compile(String protocolId,
- String invocationId,
- String[] args,
- List<File> explicitSources,
- Set<URI> sourcesToCompile,
- Set<URI> visibleSources) {
-
- JavacTool compiler = JavacTool.create();
- StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
- SmartFileManager smartFileManager = new SmartFileManager(fileManager);
- Context context = new Context();
- ResolveWithDeps.preRegister(context);
- AttrWithDeps.preRegister(context);
- JavaCompilerWithDeps.preRegister(context, this);
-
- // Now setup the actual compilation....
- CompilationResult compilationResult = new CompilationResult(0);
-
- // First deal with explicit source files on cmdline and in at file.
- ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
- for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(explicitSources)) {
- compilationUnits.append(i);
- }
- // Now deal with sources supplied as source_to_compile.
- ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
- for (URI u : sourcesToCompile) {
- sourcesToCompileFiles.append(new File(u));
- }
- for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
- compilationUnits.append(i);
- }
- // Log the options to be used.
- StringBuilder options = new StringBuilder();
- for (String s : args) {
- options.append(">").append(s).append("< ");
- }
- javacServer.log(protocolId+" <"+invocationId+"> options "+options.toString());
-
- forcedExit.set(false);
- // Create a new logger.
- StringWriter stdoutLog = new StringWriter();
- StringWriter stderrLog = new StringWriter();
- PrintWriter stdout = new PrintWriter(stdoutLog);
- PrintWriter stderr = new PrintWriter(stderrLog);
- com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
- try {
- if (compilationUnits.size() > 0) {
- smartFileManager.setVisibleSources(visibleSources);
- smartFileManager.cleanArtifacts();
- smartFileManager.setLog(stdout);
-
-
- // Do the compilation!
- CompilationTask task = compiler.getTask(stderr, smartFileManager, null, Arrays.asList(args), null, compilationUnits, context);
- rc = ((JavacTaskImpl) task).doCall();
- smartFileManager.flush();
- }
- } catch (Exception e) {
- stderr.println(e.getMessage());
- forcedExit.set(true);
- }
-
- compilationResult.packageArtifacts = smartFileManager.getPackageArtifacts();
-
- Dependencies deps = Dependencies.instance(context);
- compilationResult.packageDependencies = deps.getDependencies();
- compilationResult.packagePubapis = deps.getPubapis();
-
- compilationResult.stdout = stdoutLog.toString();
- compilationResult.stderr = stderrLog.toString();
- compilationResult.returnCode = rc.exitCode == 0 && forcedExit.get() ? -1 : rc.exitCode;
-
- return compilationResult;
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.io.File;
+import java.net.URI;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.sun.tools.sjavac.Log;
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SysInfo;
+
+/**
+ * An sjavac implementation that limits the number of concurrent calls by
+ * wrapping invocations in Callables and delegating them to a FixedThreadPool.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class PooledSjavac implements Sjavac {
+
+ final Sjavac delegate;
+ final ExecutorService pool;
+
+ public PooledSjavac(Sjavac delegate, int poolsize) {
+ Objects.requireNonNull(delegate);
+ this.delegate = delegate;
+ pool = Executors.newFixedThreadPool(poolsize, new ThreadFactory() {
+ AtomicInteger count = new AtomicInteger();
+ @Override
+ public Thread newThread(Runnable runnable) {
+ String cls = PooledSjavac.class.getSimpleName();
+ int num = count.incrementAndGet();
+ Thread t = new Thread(runnable, cls + "-" + num);
+ t.setDaemon(true);
+ return t;
+ }
+ });
+ }
+
+ @Override
+ public SysInfo getSysInfo() {
+ try {
+ return pool.submit(new Callable<SysInfo>() {
+ @Override
+ public SysInfo call() throws Exception {
+ return delegate.getSysInfo();
+ }
+ }).get();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("Error during getSysInfo", e);
+ }
+ }
+
+ @Override
+ public CompilationResult compile(final String protocolId,
+ final String invocationId,
+ final String[] args,
+ final List<File> explicitSources,
+ final Set<URI> sourcesToCompile,
+ final Set<URI> visibleSources) {
+ try {
+ return pool.submit(new Callable<CompilationResult>() {
+ @Override
+ public CompilationResult call() throws Exception {
+ return delegate.compile(protocolId,
+ invocationId,
+ args,
+ explicitSources,
+ sourcesToCompile,
+ visibleSources);
+ }
+ }).get();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("Error during compile", e);
+ }
+ }
+
+ @Override
+ public void shutdown() {
+ pool.shutdown(); // Disable new tasks from being submitted
+ try {
+ // Wait a while for existing tasks to terminate
+ if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
+ pool.shutdownNow(); // Cancel currently executing tasks
+ // Wait a while for tasks to respond to being cancelled
+ if (!pool.awaitTermination(60, TimeUnit.SECONDS))
+ Log.error("ThreadPool did not terminate");
+ }
+ // Grace period for thread termination
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {
+ // (Re-)Cancel if current thread also interrupted
+ pool.shutdownNow();
+ // Preserve interrupt status
+ Thread.currentThread().interrupt();
+ }
+
+ delegate.shutdown();
+ }
+
+ @Override
+ public String serverSettings() {
+ return delegate.serverSettings();
+ }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,10 +37,10 @@
/** Utility class that constructs a textual representation
* of the public api of a class.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class PubapiVisitor extends ElementScanner9<Void, Void> {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/ResolveWithDeps.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/ResolveWithDeps.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,10 +30,10 @@
/** Subclass to Resolve that overrides collect.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class ResolveWithDeps extends Resolve {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacErrorHandler.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+/**
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public interface SjavacErrorHandler {
+ void logError(String msg);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Options;
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SysInfo;
+
+/**
+ * The sjavac implementation that interacts with javac and performs the actual
+ * compilation.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class SjavacImpl implements Sjavac {
+
+ @Override
+ public SysInfo getSysInfo() {
+ return new SysInfo(Runtime.getRuntime().availableProcessors(),
+ Runtime.getRuntime().maxMemory());
+ }
+
+ @Override
+ public CompilationResult compile(String protocolId,
+ String invocationId,
+ String[] args,
+ List<File> explicitSources,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources) {
+ final AtomicBoolean forcedExit = new AtomicBoolean();
+
+ JavacTool compiler = JavacTool.create();
+ StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+ SmartFileManager smartFileManager = new SmartFileManager(fileManager);
+ Context context = new Context();
+ ResolveWithDeps.preRegister(context);
+ AttrWithDeps.preRegister(context);
+ JavaCompilerWithDeps.preRegister(context, new SjavacErrorHandler() {
+ @Override
+ public void logError(String msg) {
+ forcedExit.set(true);
+ }
+ });
+
+ // Now setup the actual compilation....
+ CompilationResult compilationResult = new CompilationResult(0);
+
+ // First deal with explicit source files on cmdline and in at file.
+ ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
+ for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(explicitSources)) {
+ compilationUnits.append(i);
+ }
+ // Now deal with sources supplied as source_to_compile.
+ ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
+ for (URI u : sourcesToCompile) {
+ sourcesToCompileFiles.append(new File(u));
+ }
+ for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
+ compilationUnits.append(i);
+ }
+ forcedExit.set(false);
+ // Create a new logger.
+ StringWriter stdoutLog = new StringWriter();
+ StringWriter stderrLog = new StringWriter();
+ PrintWriter stdout = new PrintWriter(stdoutLog);
+ PrintWriter stderr = new PrintWriter(stderrLog);
+ com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
+ try {
+ if (compilationUnits.size() > 0) {
+ smartFileManager.setVisibleSources(visibleSources);
+ smartFileManager.cleanArtifacts();
+ smartFileManager.setLog(stdout);
+
+ // Do the compilation!
+ CompilationTask task = compiler.getTask(stderr,
+ smartFileManager,
+ null,
+ Arrays.asList(args),
+ null,
+ compilationUnits,
+ context);
+ smartFileManager.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
+ rc = ((JavacTaskImpl) task).doCall();
+ smartFileManager.flush();
+ }
+ } catch (Exception e) {
+ stderrLog.append(e.getMessage());
+ forcedExit.set(true);
+ }
+
+ compilationResult.packageArtifacts = smartFileManager.getPackageArtifacts();
+
+ Dependencies deps = Dependencies.instance(context);
+ compilationResult.packageDependencies = deps.getDependencies();
+ compilationResult.packagePubapis = deps.getPubapis();
+
+ compilationResult.stdout = stdoutLog.toString();
+ compilationResult.stderr = stderrLog.toString();
+
+ compilationResult.returnCode = rc.exitCode == 0 && forcedExit.get() ? -1 : rc.exitCode;
+
+ return compilationResult;
+ }
+
+ @Override
+ public void shutdown() {
+ // Nothing to clean up
+ // ... maybe we should wait for any current request to finish?
+ }
+
+
+ @Override
+ public String serverSettings() {
+ return "";
+ }
+
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java Thu Aug 28 14:53:49 2014 -0700
@@ -37,7 +37,6 @@
import javax.tools.JavaFileObject.Kind;
import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.ListBuffer;
/**
@@ -50,10 +49,10 @@
* Can also blind out the filemanager from seeing certain files in the file system.
* Necessary to prevent javac from seeing some sources where the source path points.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager> {
@@ -97,9 +96,7 @@
public Iterable<JavaFileObject> list(Location location,
String packageName,
Set<Kind> kinds,
- boolean recurse)
- throws IOException
- {
+ boolean recurse) throws IOException {
// Acquire the list of files.
Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
if (visibleSources.isEmpty()) {
@@ -112,8 +109,7 @@
String t = uri.toString();
if (t.startsWith("jar:")
|| t.endsWith(".class")
- || visibleSources.contains(uri))
- {
+ || visibleSources.contains(uri)) {
filteredFiles.add(f);
}
}
@@ -128,9 +124,7 @@
@Override
public JavaFileObject getJavaFileForInput(Location location,
String className,
- Kind kind)
- throws IOException
- {
+ Kind kind) throws IOException {
JavaFileObject file = super.getJavaFileForInput(location, className, kind);
if (file == null || visibleSources.isEmpty()) {
return file;
@@ -146,9 +140,7 @@
public JavaFileObject getJavaFileForOutput(Location location,
String className,
Kind kind,
- FileObject sibling)
- throws IOException
- {
+ FileObject sibling) throws IOException {
JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
if (file == null) return file;
int dp = className.lastIndexOf('.');
@@ -165,9 +157,7 @@
@Override
public FileObject getFileForInput(Location location,
String packageName,
- String relativeName)
- throws IOException
- {
+ String relativeName) throws IOException {
FileObject file = super.getFileForInput(location, packageName, relativeName);
if (file == null || visibleSources.isEmpty()) {
return file;
@@ -183,9 +173,7 @@
public FileObject getFileForOutput(Location location,
String packageName,
String relativeName,
- FileObject sibling)
- throws IOException
- {
+ FileObject sibling) throws IOException {
FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
if (file == null) return file;
if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,10 +36,10 @@
* and compare the new content with the old content on disk. Only if they differ,
* will the file be updated.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class SmartFileObject implements JavaFileObject {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartWriter.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartWriter.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,9 +34,9 @@
* If not, the file is not touched.
*
* <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class SmartWriter extends Writer {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java Thu Aug 28 14:53:49 2014 -0700
@@ -27,6 +27,12 @@
import java.util.Iterator;
+/**
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
public class ArgumentIterator implements Iterator<String> {
/** The underlying argument iterator */
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java Thu Aug 28 14:53:49 2014 -0700
@@ -47,6 +47,11 @@
* This enum represents all options from (1) and (2). Note that instances of
* this enum only entail static information about the option. For storage of
* option values, refer to com.sun.tools.sjavac.options.Options.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public enum Option {
@@ -231,7 +236,14 @@
helper.logLevel("info");
}
},
- PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Keep unidentified artifacts in destination directory") {
+ PERMIT_ARTIFACT("--permit-artifact=", "Allow this artifact in destination directory") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ String a = iter.current().substring(arg.length());
+ helper.permitArtifact(Paths.get(a).toFile().getAbsolutePath());
+ }
+ },
+ PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Allow unidentified artifacts in destination directory") {
@Override
protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
helper.permitUnidentifiedArtifacts();
@@ -274,8 +286,16 @@
if (dir != null)
helper.headerDir(dir);
}
+ },
+ STATE_DIR("--state-dir=", "Directory used to store sjavac state and log files.") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ String p = iter.current().substring(arg.length());
+ helper.stateDir(Paths.get(p));
+ }
};
+
public final String arg;
final String description;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,17 +25,23 @@
package com.sun.tools.sjavac.options;
-import java.nio.file.Files;
+import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
+import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.sjavac.Transformer;
/**
* This class is used to decode sjavac options.
* See com.sun.tools.sjavac.options.Options for example usage.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public abstract class OptionHelper {
@@ -78,6 +84,9 @@
/** Record path for reference source list */
public abstract void compareFoundSources(Path referenceList);
+ /** Record a single permitted artifact */
+ public abstract void permitArtifact(String f);
+
/** Record the fact that unidentified artifacts are permitted */
public abstract void permitUnidentifiedArtifacts();
@@ -102,6 +111,9 @@
/** Sets the directory for generated headers */
public abstract void headerDir(Path dir);
+ /** Sets the directory for state and log files generated by sjavac */
+ public abstract void stateDir(Path dir);
+
/** Sets the implicit policy */
public abstract void implicit(String policy);
@@ -112,7 +124,11 @@
* @param args the arguments to traverse.
*/
void traverse(String[] args) {
-
+ try {
+ args = CommandLine.parse(args); // Detect @file and load it as a command line.
+ } catch (java.io.IOException e) {
+ throw new IllegalArgumentException("Problem reading @"+e.getMessage());
+ }
ArgumentIterator argIter = new ArgumentIterator(Arrays.asList(args));
nextArg:
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Thu Aug 28 14:53:49 2014 -0700
@@ -32,16 +32,23 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
import com.sun.tools.sjavac.Transformer;
/**
* Instances of this class represent values for sjavac command line options.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class Options {
// Output directories
- private Path destDir, genSrcDir, headerDir;
+ private Path destDir, genSrcDir, headerDir, stateDir;
// Input directories
private List<SourceLocation> sources = new ArrayList<>();
@@ -51,7 +58,8 @@
private String logLevel = "info";
- private boolean permitUnidentifiedArtifact = false;
+ private Set<String> permitted_artifacts = new HashSet<>();
+ private boolean permitUnidentifiedArtifacts = false;
private boolean permitSourcesInDefaultPackage = false;
private Path sourceReferenceList;
@@ -86,6 +94,11 @@
return headerDir;
}
+ /** Get the path for the state directory, defaults to destDir. */
+ public Path getStateDir() {
+ return stateDir != null ? stateDir : destDir;
+ }
+
/** Get all source locations for files to be compiled */
public List<SourceLocation> getSources() {
return sources;
@@ -114,10 +127,15 @@
return logLevel;
}
+ /** Returns true iff the artifact is permitted in the output dir. */
+ public boolean isUnidentifiedArtifactPermitted(String f) {
+ return permitted_artifacts.contains(f);
+ }
+
/** Returns true iff artifacts in the output directories should be kept,
* even if they would not be generated in a clean build. */
- public boolean isUnidentifiedArtifactPermitted() {
- return permitUnidentifiedArtifact;
+ public boolean areUnidentifiedArtifactsPermitted() {
+ return permitUnidentifiedArtifacts;
}
/** Returns true iff sources in the default package should be permitted. */
@@ -176,14 +194,6 @@
return false;
}
- /** Returns true iff an @-file is among the javac arguments */
- public boolean isAtFilePresent() {
- for (String javacArg : javacArgs)
- if (javacArg.startsWith("@"))
- return true;
- return false;
- }
-
/**
* Returns a string representation of the options that affect the result of
* the compilation. (Used for saving the state of the options used in a
@@ -239,6 +249,9 @@
if (destDir != null)
args.addArg(Option.D, destDir.normalize());
+ if (stateDir != null)
+ args.addArg(Option.STATE_DIR, stateDir.normalize());
+
// Source roots
args.addSourceLocations(Option.SRC, sources);
args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths);
@@ -249,7 +262,11 @@
if (permitSourcesInDefaultPackage)
args.addArg(Option.PERMIT_SOURCES_WITHOUT_PACKAGE);
- if (permitUnidentifiedArtifact)
+ for (String f : permitted_artifacts) {
+ args.addArg(Option.PERMIT_ARTIFACT, f);
+ }
+
+ if (permitUnidentifiedArtifacts)
args.addArg(Option.PERMIT_UNIDENTIFIED_ARTIFACTS);
// Translation rules
@@ -327,6 +344,7 @@
boolean headerProvided = false;
boolean genSrcProvided = false;
+ boolean stateProvided = false;
@Override
public void reportError(String msg) {
@@ -399,8 +417,13 @@
}
@Override
+ public void permitArtifact(String f) {
+ permitted_artifacts.add(f);
+ }
+
+ @Override
public void permitUnidentifiedArtifacts() {
- permitUnidentifiedArtifact = true;
+ permitUnidentifiedArtifacts = true;
}
@Override
@@ -465,6 +488,16 @@
headerDir = dir.toAbsolutePath();
}
+ @Override
+ public void stateDir(Path dir) {
+ if (stateProvided) {
+ reportError("State directory already specified.");
+ return;
+ }
+ stateProvided = true;
+ stateDir = dir.toAbsolutePath();
+ }
+
private List<SourceLocation> createSourceLocations(List<Path> paths) {
List<SourceLocation> result = new ArrayList<>();
for (Path path : paths) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java Thu Aug 28 14:53:49 2014 -0700
@@ -37,6 +37,11 @@
/**
* Represents a directory to be used for input to sjavac. (For instance a
* sourcepath or classpath.)
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
public class SourceLocation {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,28 +25,35 @@
package com.sun.tools.sjavac.server;
+import java.io.Serializable;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-public class CompilationResult {
+/**
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class CompilationResult implements Serializable {
+
+ static final long serialVersionUID = 46739181113L;
// Return code constants
- public final static int ERROR_BUT_TRY_AGAIN = -4712;
public final static int ERROR_FATAL = -1;
public int returnCode;
public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
public Map<String, Set<String>> packageDependencies = new HashMap<>();
public Map<String, String> packagePubapis = new HashMap<>();
- public SysInfo sysinfo;
- public String stdout;
- public String stderr;
+ public String stdout = "";
+ public String stderr = "";
public CompilationResult(int returnCode) {
this.returnCode = returnCode;
- this.sysinfo = new SysInfo(-1, -1);
}
public void setReturnCode(int returnCode) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilerPool.java Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.server;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Semaphore;
-import java.util.Stack;
-import java.util.concurrent.Future;
-
-import com.sun.tools.sjavac.comp.JavacServiceImpl;
-
-/** The compiler pool maintains compiler threads.
- *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
- */
-public class CompilerPool {
- // The javac server that created this pool.
- private JavacServer javacServer;
- // A semaphore protecting the poolsize number of threads.
- private Semaphore available;
- // The stack of compiler threads.
- private Stack<CompilerThread> compilers = new Stack<>();
- // And the executor server to spawn threads.
- private final ExecutorService executorPool;
- // How many requests are active right now?
- private int concurrentRequests = 0;
- // When was the last request finished?
- private long lastRequestFinished = 0;
- // The total number of requests to this pool.
- private int numRequests = 0;
- // Protect access to the three above values.
- private static final Object conc = new Object();
-
- /**
- * Return the javac server that this pool belongs to.
- */
- public JavacServer getJavacServer() {
- return javacServer;
- }
-
- /**
- * Return how many threads are running at this very moment.
- */
- public int numActiveRequests()
- {
- synchronized (conc) {
- return concurrentRequests;
- }
- }
-
- /**
- * Return when the last request was finished.
- * I.e. the pool has been idle since.
- */
- public long lastRequestFinished()
- {
- synchronized (conc) {
- return lastRequestFinished;
- }
- }
-
- /**
- * Up the number of active requests.
- */
- public int startRequest() {
- int n;
- synchronized (conc) {
- concurrentRequests++;
- numRequests++;
- n = numRequests;
- }
- return n;
- }
-
- /**
- * Down the number of active requests. Return the current time.
- */
- public long stopRequest() {
- synchronized (conc) {
- concurrentRequests--;
- lastRequestFinished = System.currentTimeMillis();
- }
- return lastRequestFinished;
- }
-
- /**
- * Create a new compiler pool.
- */
- CompilerPool(int poolsize, JavacServer server) {
- available = new Semaphore(poolsize, true);
- javacServer = server;
- executorPool = Executors.newFixedThreadPool(poolsize);
- lastRequestFinished = System.currentTimeMillis();
- }
-
- /**
- * Execute a compiler thread.
- */
- public void execute(CompilerThread ct) {
- executorPool.execute(ct);
- }
-
- /**
- * Execute a minor task, for example generating bytecodes and writing them to disk,
- * that belong to a major compiler thread task.
- */
- public Future<?> executeSubtask(CompilerThread t, Runnable r) {
- return executorPool.submit(r);
- }
-
- /**
- * Shutdown the pool.
- */
- public void shutdown() {
- executorPool.shutdown();
- }
-
- /**
- * Acquire a compiler thread from the pool, or block until a thread is available.
- * If the pools is empty, create a new thread, but never more than is "available".
- */
- public CompilerThread grabCompilerThread() throws InterruptedException {
- available.acquire();
- if (compilers.empty()) {
- return new CompilerThread(this, new JavacServiceImpl(javacServer));
- }
- return compilers.pop();
- }
-
- /**
- * Return the specified compiler thread to the pool.
- */
- public void returnCompilerThread(CompilerThread h) {
- compilers.push(h);
- available.release();
- }
-}
-
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilerThread.java Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,412 +0,0 @@
-/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.server;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.Socket;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Future;
-
-import javax.tools.JavaCompiler.CompilationTask;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-
-import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Options;
-import com.sun.tools.javac.util.StringUtils;
-import com.sun.tools.sjavac.comp.AttrWithDeps;
-import com.sun.tools.sjavac.comp.Dependencies;
-import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
-import com.sun.tools.sjavac.comp.JavacServiceImpl;
-import com.sun.tools.sjavac.comp.ResolveWithDeps;
-import com.sun.tools.sjavac.comp.SmartFileManager;
-
-/**
- * The compiler thread maintains a JavaCompiler instance and
- * can receive a request from the client, perform the compilation
- * requested and report back the results.
- *
- * * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
- */
-public class CompilerThread implements Runnable {
- private JavacServer javacServer;
- private CompilerPool compilerPool;
- private JavacServiceImpl javacServiceImpl;
- private List<Future<?>> subTasks;
-
- // Communicating over this socket.
- private Socket socket;
-
- // The necessary classes to do a compilation.
- private com.sun.tools.javac.api.JavacTool compiler;
- private StandardJavaFileManager fileManager;
- private SmartFileManager smartFileManager;
- private Context context;
-
- // If true, then this thread is serving a request.
- private boolean inUse = false;
-
- CompilerThread(CompilerPool cp, JavacServiceImpl javacServiceImpl) {
- compilerPool = cp;
- javacServer = cp.getJavacServer();
- this.javacServiceImpl = javacServiceImpl;
- }
-
- /**
- * Execute a minor task, for example generating bytecodes and writing them to disk,
- * that belong to a major compiler thread task.
- */
- public synchronized void executeSubtask(Runnable r) {
- subTasks.add(compilerPool.executeSubtask(this, r));
- }
-
- /**
- * Count the number of active sub tasks.
- */
- public synchronized int numActiveSubTasks() {
- int c = 0;
- for (Future<?> f : subTasks) {
- if (!f.isDone() && !f.isCancelled()) {
- c++;
- }
- }
- return c;
- }
-
- /**
- * Use this socket for the upcoming request.
- */
- public void setSocket(Socket s) {
- socket = s;
- }
-
- /**
- * Prepare the compiler thread for use. It is not yet started.
- * It will be started by the executor service.
- */
- public synchronized void use() {
- assert(!inUse);
- inUse = true;
- compiler = com.sun.tools.javac.api.JavacTool.create();
- fileManager = compiler.getStandardFileManager(null, null, null);
- smartFileManager = new SmartFileManager(fileManager);
- context = new Context();
- ResolveWithDeps.preRegister(context);
- AttrWithDeps.preRegister(context);
- JavaCompilerWithDeps.preRegister(context, javacServiceImpl);
- subTasks = new ArrayList<>();
- }
-
- /**
- * Prepare the compiler thread for idleness.
- */
- public synchronized void unuse() {
- assert(inUse);
- inUse = false;
- compiler = null;
- fileManager = null;
- smartFileManager = null;
- context = null;
- subTasks = null;
- }
-
- /**
- * Expect this key on the next line read from the reader.
- */
- private static boolean expect(BufferedReader in, String key) throws IOException {
- String s = in.readLine();
- if (s != null && s.equals(key)) {
- return true;
- }
- return false;
- }
-
- // The request identifier, for example GENERATE_NEWBYTECODE
- String id = "";
-
- public String currentRequestId() {
- return id;
- }
-
- PrintWriter stdout;
- PrintWriter stderr;
- int forcedExitCode = 0;
-
- public void logError(String msg) {
- stderr.println(msg);
- forcedExitCode = -1;
- }
-
- /**
- * Invoked by the executor service.
- */
- public void run() {
- // Unique nr that identifies this request.
- int thisRequest = compilerPool.startRequest();
- long start = System.currentTimeMillis();
- int numClasses = 0;
- StringBuilder compiledPkgs = new StringBuilder();
- use();
-
- PrintWriter out = null;
- try {
- javacServer.log("<"+thisRequest+"> Connect from "+socket.getRemoteSocketAddress()+" activethreads="+compilerPool.numActiveRequests());
- BufferedReader in = new BufferedReader(new InputStreamReader(
- socket.getInputStream()));
- out = new PrintWriter(new OutputStreamWriter(
- socket.getOutputStream()));
- if (!expect(in, JavacServer.PROTOCOL_COOKIE_VERSION)) {
- javacServer.log("<"+thisRequest+"> Bad protocol from ip "+socket.getRemoteSocketAddress());
- return;
- }
-
- String cookie = in.readLine();
- if (cookie == null || !cookie.equals(""+javacServer.getCookie())) {
- javacServer.log("<"+thisRequest+"> Bad cookie from ip "+socket.getRemoteSocketAddress());
- return;
- }
- if (!expect(in, JavacServer.PROTOCOL_CWD)) {
- return;
- }
- String cwd = in.readLine();
- if (cwd == null)
- return;
- if (!expect(in, JavacServer.PROTOCOL_ID)) {
- return;
- }
- id = in.readLine();
- if (id == null)
- return;
- if (!expect(in, JavacServer.PROTOCOL_ARGS)) {
- return;
- }
- ArrayList<String> the_options = new ArrayList<>();
- ArrayList<File> the_classes = new ArrayList<>();
- Iterable<File> path = Arrays.<File> asList(new File(cwd));
-
- for (;;) {
- String l = in.readLine();
- if (l == null)
- return;
- if (l.equals(JavacServer.PROTOCOL_SOURCES_TO_COMPILE))
- break;
- if (l.startsWith("--server:"))
- continue;
- if (!l.startsWith("-") && l.endsWith(".java")) {
- the_classes.add(new File(l));
- numClasses++;
- } else {
- the_options.add(l);
- }
- continue;
- }
-
- // Load sources to compile
- Set<URI> sourcesToCompile = new HashSet<>();
- for (;;) {
- String l = in.readLine();
- if (l == null)
- return;
- if (l.equals(JavacServer.PROTOCOL_VISIBLE_SOURCES))
- break;
- try {
- sourcesToCompile.add(new URI(l));
- numClasses++;
- } catch (URISyntaxException e) {
- return;
- }
- }
- // Load visible sources
- Set<URI> visibleSources = new HashSet<>();
- boolean fix_drive_letter_case =
- StringUtils.toLowerCase(System.getProperty("os.name")).startsWith("windows");
- for (;;) {
- String l = in.readLine();
- if (l == null)
- return;
- if (l.equals(JavacServer.PROTOCOL_END))
- break;
- try {
- URI u = new URI(l);
- if (fix_drive_letter_case) {
- // Make sure the driver letter is lower case.
- String s = u.toString();
- if (s.startsWith("file:/") &&
- Character.isUpperCase(s.charAt(6))) {
- u = new URI("file:/"+Character.toLowerCase(s.charAt(6))+s.substring(7));
- }
- }
- visibleSources.add(u);
- } catch (URISyntaxException e) {
- return;
- }
- }
-
- // A completed request has been received.
-
- // Now setup the actual compilation....
- // First deal with explicit source files on cmdline and in at file.
- ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
- for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(the_classes)) {
- compilationUnits.append(i);
- }
- // Now deal with sources supplied as source_to_compile.
- ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
- for (URI u : sourcesToCompile) {
- sourcesToCompileFiles.append(new File(u));
- }
- for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
- compilationUnits.append(i);
- }
- // Log the options to be used.
- StringBuilder options = new StringBuilder();
- for (String s : the_options) {
- options.append(">").append(s).append("< ");
- }
- javacServer.log(id+" <"+thisRequest+"> options "+options.toString());
-
- forcedExitCode = 0;
- // Create a new logger.
- StringWriter stdoutLog = new StringWriter();
- StringWriter stderrLog = new StringWriter();
- stdout = new PrintWriter(stdoutLog);
- stderr = new PrintWriter(stderrLog);
- com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
- try {
- if (compilationUnits.size() > 0) {
- smartFileManager.setVisibleSources(visibleSources);
- smartFileManager.cleanArtifacts();
- smartFileManager.setLog(stdout);
-
- // Do the compilation!
- CompilationTask task = compiler.getTask(stderr, smartFileManager, null, the_options, null, compilationUnits, context);
- smartFileManager.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
- rc = ((JavacTaskImpl) task).doCall();
-
- while (numActiveSubTasks()>0) {
- try { Thread.sleep(1000); } catch (InterruptedException e) { }
- }
-
- smartFileManager.flush();
- }
- } catch (Exception e) {
- stderr.println(e.getMessage());
- forcedExitCode = -1;
- }
-
- // Send the response..
- out.println(JavacServer.PROTOCOL_STDOUT);
- out.print(stdoutLog);
- out.println(JavacServer.PROTOCOL_STDERR);
- out.print(stderrLog);
- // The compilation is complete! And errors will have already been printed on out!
- out.println(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS);
- Map<String,Set<URI>> pa = smartFileManager.getPackageArtifacts();
- for (String aPkgName : pa.keySet()) {
- out.println("+"+aPkgName);
- Set<URI> as = pa.get(aPkgName);
- for (URI a : as) {
- out.println(" "+a.toString());
- }
- }
- Dependencies deps = Dependencies.instance(context);
- out.println(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES);
- Map<String,Set<String>> pd = deps.getDependencies();
- for (String aPkgName : pd.keySet()) {
- out.println("+"+aPkgName);
- Set<String> ds = pd.get(aPkgName);
- // Everything depends on java.lang
- if (!ds.contains(":java.lang")) ds.add(":java.lang");
- for (String d : ds) {
- out.println(" "+d);
- }
- }
- out.println(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS);
- Map<String,String> pp = deps.getPubapis();
- for (String aPkgName : pp.keySet()) {
- out.println("+"+aPkgName);
- String ps = pp.get(aPkgName);
- // getPubapis added a space to each line!
- out.println(ps);
- compiledPkgs.append(aPkgName+" ");
- }
- out.println(JavacServer.PROTOCOL_SYSINFO);
- out.println("num_cores=" + Runtime.getRuntime().availableProcessors());
- out.println("max_memory=" + Runtime.getRuntime().maxMemory());
- out.println(JavacServer.PROTOCOL_RETURN_CODE);
-
- // Errors from sjavac that affect compilation status!
- int rcv = rc.exitCode;
- if (rcv == 0 && forcedExitCode != 0) {
- rcv = forcedExitCode;
- }
- out.println("" + rcv);
- out.println(JavacServer.PROTOCOL_END);
- out.flush();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (out != null) out.close();
- if (!socket.isClosed()) {
- socket.close();
- }
- socket = null;
- } catch (Exception e) {
- javacServer.log("ERROR "+e);
- e.printStackTrace();
- }
- compilerPool.stopRequest();
- long duration = System.currentTimeMillis()-start;
- javacServer.addBuildTime(duration);
- float classpersec = ((float)numClasses)*(((float)1000.0)/((float)duration));
- javacServer.log(id+" <"+thisRequest+"> "+compiledPkgs+" duration " + duration+ " ms num_classes="+numClasses+
- " classpersec="+classpersec+" subtasks="+subTasks.size());
- javacServer.flushLog();
- unuse();
- compilerPool.returnCompilerThread(this);
- }
- }
-}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * An sjavac implementation that keeps track of idleness and shuts down the
+ * given Terminable upon idleness timeout.
+ *
+ * An idleness timeout kicks in {@code idleTimeout} milliseconds after the last
+ * request is completed.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class IdleResetSjavac implements Sjavac {
+
+ private final Sjavac delegate;
+ private final AtomicInteger outstandingCalls = new AtomicInteger();
+ private final Terminable toShutdown;
+ private final Timer idlenessTimer = new Timer();
+ private final long idleTimeout;
+
+ // Class invariant: idlenessTimerTask != null <-> idlenessTimerTask is scheduled
+ private TimerTask idlenessTimerTask;
+
+ public IdleResetSjavac(Sjavac delegate,
+ Terminable toShutdown,
+ long idleTimeout) {
+ this.delegate = delegate;
+ this.toShutdown = toShutdown;
+ this.idleTimeout = idleTimeout;
+ scheduleTimeout();
+ }
+
+ @Override
+ public SysInfo getSysInfo() {
+ startCall();
+ try {
+ return delegate.getSysInfo();
+ } finally {
+ endCall();
+ }
+ }
+
+ @Override
+ public CompilationResult compile(String protocolId,
+ String invocationId,
+ String[] args,
+ List<File> explicitSources,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources) {
+ startCall();
+ try {
+ return delegate.compile(protocolId,
+ invocationId,
+ args,
+ explicitSources,
+ sourcesToCompile,
+ visibleSources);
+ } finally {
+ endCall();
+ }
+ }
+
+ private void startCall() {
+ // Was there no outstanding calls before this call?
+ if (outstandingCalls.incrementAndGet() == 1) {
+ // Then the timer task must have been scheduled
+ if (idlenessTimerTask == null)
+ throw new IllegalStateException("Idle timeout already cancelled");
+ // Cancel timeout task
+ idlenessTimerTask.cancel();
+ idlenessTimerTask = null;
+ }
+ }
+
+ private void endCall() {
+ if (outstandingCalls.decrementAndGet() == 0) {
+ // No more outstanding calls. Schedule timeout.
+ scheduleTimeout();
+ }
+ }
+
+ private void scheduleTimeout() {
+ if (idlenessTimerTask != null)
+ throw new IllegalStateException("Idle timeout already scheduled");
+ idlenessTimerTask = new TimerTask() {
+ public void run() {
+ toShutdown.shutdown("Server has been idle for " + (idleTimeout / 1000) + " seconds.");
+ }
+ };
+ idlenessTimer.schedule(idlenessTimerTask, idleTimeout);
+ }
+
+ @Override
+ public void shutdown() {
+ idlenessTimer.cancel();
+ delegate.shutdown();
+ }
+
+ @Override
+ public String serverSettings() {
+ return delegate.serverSettings();
+ }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacServer.java Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,382 +0,0 @@
-/*
- * Copyright (c) 2011-2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.tools.sjavac.server;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.FileNotFoundException;
-import java.util.HashMap;
-import java.util.Map;
-
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Random;
-
-import com.sun.tools.sjavac.Util;
-import com.sun.tools.sjavac.ProblemException;
-import java.io.*;
-
-/**
- * The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
- *
- * <p><b>This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are
- * subject to change or deletion without notice.</b></p>
- */
-public class JavacServer {
- // Responding to this tcp/ip port on localhost.
-
- private final ServerSocket serverSocket;
- // The secret cookie shared between server and client through the port file.
- private final long myCookie;
- // When the server was started.
- private long serverStart;
- // Accumulated build time for all requests, not counting idle time.
- private long totalBuildTime;
- // The javac server specific log file.
- PrintWriter theLog;
- // The compiler pool that maintains the compiler threads.
- CompilerPool compilerPool;
- // For the client, all port files fetched, one per started javac server.
- // Though usually only one javac server is started by a client.
- private static Map<String, PortFile> allPortFiles;
- private static Map<String, Long> maxServerMemory;
- final static String PROTOCOL_COOKIE_VERSION = "----THE-COOKIE-V2----";
- final static String PROTOCOL_CWD = "----THE-CWD----";
- final static String PROTOCOL_ID = "----THE-ID----";
- final static String PROTOCOL_ARGS = "----THE-ARGS----";
- final static String PROTOCOL_SOURCES_TO_COMPILE = "----THE-SOURCES-TO-COMPILE----";
- final static String PROTOCOL_VISIBLE_SOURCES = "----THE-VISIBLE-SOURCES----";
- final static String PROTOCOL_END = "----THE-END----";
- final static String PROTOCOL_STDOUT = "----THE-STDOUT----";
- final static String PROTOCOL_STDERR = "----THE-STDERR----";
- final static String PROTOCOL_PACKAGE_ARTIFACTS = "----THE-PACKAGE_ARTIFACTS----";
- final static String PROTOCOL_PACKAGE_DEPENDENCIES = "----THE-PACKAGE_DEPENDENCIES----";
- final static String PROTOCOL_PACKAGE_PUBLIC_APIS = "----THE-PACKAGE-PUBLIC-APIS----";
- final static String PROTOCOL_SYSINFO = "----THE-SYSINFO----";
- final static String PROTOCOL_RETURN_CODE = "----THE-RETURN-CODE----";
- // Check if the portfile is gone, every 5 seconds.
- static int CHECK_PORTFILE_INTERVAL = 5;
- // Wait 2 seconds for response, before giving up on javac server.
- static int CONNECTION_TIMEOUT = 2;
- static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 1;
- static int MAX_NUM_CONNECT_ATTEMPTS = 3;
-
- /**
- * Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
- */
- public static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
- if (allPortFiles == null) {
- allPortFiles = new HashMap<>();
- }
- PortFile pf = allPortFiles.get(filename);
-
- // Port file known. Does it still exist?
- if (pf != null) {
- try {
- if (!pf.exists())
- pf = null;
- } catch (IOException ioex) {
- ioex.printStackTrace();
- }
- }
-
- if (pf == null) {
- pf = new PortFile(filename);
- allPortFiles.put(filename, pf);
- }
- return pf;
- }
-
- /**
- * Get the cookie used for this server.
- */
- long getCookie() {
- return myCookie;
- }
-
- /**
- * Get the port used for this server.
- */
- int getPort() {
- return serverSocket.getLocalPort();
- }
-
- /**
- * Sum up the total build time for this javac server.
- */
- public void addBuildTime(long inc) {
- totalBuildTime += inc;
- }
-
- /**
- * Log this message.
- */
- public void log(String msg) {
- if (theLog != null) {
- theLog.println(msg);
- } else {
- System.err.println(msg);
- }
- }
-
- /**
- * Make sure the log is flushed.
- */
- public void flushLog() {
- if (theLog != null) {
- theLog.flush();
- }
- }
-
- /**
- * Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
- * is sent as the settings parameter. Returns 0 on success, -1 on failure.
- */
- public static int startServer(String settings, PrintStream err) {
- try {
- String portfile = Util.extractStringOption("portfile", settings);
- // The log file collects more javac server specific log information.
- String logfile = Util.extractStringOption("logfile", settings);
- // The stdouterr file collects all the System.out and System.err writes to disk.
- String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
- // We could perhaps use System.setOut and setErr here.
- // But for the moment we rely on the client to spawn a shell where stdout
- // and stderr are redirected already.
- // The pool size is a limit the number of concurrent compiler threads used.
- // The server might use less than these to avoid memory problems.
- int defaultPoolSize = Runtime.getRuntime().availableProcessors();
- int poolsize = Util.extractIntOption("poolsize", settings, defaultPoolSize);
-
- // How many seconds of inactivity will the server accept before quitting?
- int keepalive = Util.extractIntOption("keepalive", settings, 120);
-
- // The port file is locked and the server port and cookie is written into it.
- PortFile portFile = getPortFile(portfile);
- JavacServer s;
-
- synchronized (portFile) {
- portFile.lock();
- portFile.getValues();
- if (portFile.containsPortInfo()) {
- err.println("Javac server not started because portfile exists!");
- portFile.unlock();
- return -1;
- }
- s = new JavacServer(poolsize, logfile);
- portFile.setValues(s.getPort(), s.getCookie());
- portFile.unlock();
- }
-
- // Run the server. Will delete the port file when shutting down.
- // It will shut down automatically when no new requests have come in
- // during the last 125 seconds.
- s.run(portFile, err, keepalive);
- // The run loop for the server has exited.
- return 0;
- } catch (Exception e) {
- e.printStackTrace(err);
- return -1;
- }
- }
-
- /**
- * Spawn the server instance.
- */
-
- private JavacServer(int poolSize, String logfile) throws IOException {
- serverStart = System.currentTimeMillis();
- // Create a server socket on a random port that is bound to the localhost/127.0.0.1 interface.
- // I.e only local processes can connect to this port.
- serverSocket = new ServerSocket(0, 128, InetAddress.getByName(null));
- compilerPool = new CompilerPool(poolSize, this);
- Random rnd = new Random();
- myCookie = rnd.nextLong();
- theLog = new PrintWriter(logfile);
- log("Javac server started. port=" + getPort() + " date=" + (new java.util.Date()) + " with poolsize=" + poolSize);
- flushLog();
- }
-
- /**
- * Fork a background process. Returns the command line used that can be printed if something failed.
- */
- public static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
- final PrintStream err, String stdouterrfile, boolean background)
- throws IOException, ProblemException {
- if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
- stdouterrfile = null;
- }
- final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
-
- if (background) {
- sjavac += "%20" + startserver;
- sjavac = sjavac.replaceAll("%20", " ");
- sjavac = sjavac.replaceAll("%2C", ",");
- // If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
- String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
- if (!(new File("/bin/sh")).canExecute()) {
- ArrayList<String> wincmd = new ArrayList<>();
- wincmd.add("cmd");
- wincmd.add("/c");
- wincmd.add("start");
- wincmd.add("cmd");
- wincmd.add("/c");
- wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
- cmd = wincmd.toArray(new String[wincmd.size()]);
- }
- Process pp = null;
- try {
- pp = Runtime.getRuntime().exec(cmd);
- } catch (Exception e) {
- e.printStackTrace(err);
- e.printStackTrace(new PrintWriter(stdouterrfile));
- }
- StringBuilder rs = new StringBuilder();
- for (String s : cmd) {
- rs.append(s + " ");
- }
- return rs.toString();
- }
-
- // Do not spawn a background server, instead run it within the same JVM.
- Thread t = new Thread() {
- @Override
- public void run() {
- try {
- JavacServer.startServer(startserver, err);
- } catch (Throwable t) {
- t.printStackTrace(err);
- }
- }
- };
- t.start();
- return "";
- }
-
- /**
- * Run the server thread until it exits. Either because of inactivity or because the port file has been deleted by someone else, or overtaken by some other
- * javac server.
- */
- private void run(PortFile portFile, PrintStream err, int keepalive) {
- boolean fileDeleted = false;
- long timeSinceLastCompile;
- try {
- // Every 5 second (check_portfile_interval) we test if the portfile has disappeared => quit
- // Or if the last request was finished more than 125 seconds ago => quit
- // 125 = seconds_of_inactivity_before_shutdown+check_portfile_interval
- serverSocket.setSoTimeout(CHECK_PORTFILE_INTERVAL*1000);
- for (;;) {
- try {
- Socket s = serverSocket.accept();
- CompilerThread ct = compilerPool.grabCompilerThread();
- ct.setSocket(s);
- compilerPool.execute(ct);
- flushLog();
- } catch (java.net.SocketTimeoutException e) {
- if (compilerPool.numActiveRequests() > 0) {
- // Never quit while there are active requests!
- continue;
- }
- // If this is the timeout after the portfile
- // has been deleted by us. Then we truly stop.
- if (fileDeleted) {
- log("Quitting because of "+(keepalive+CHECK_PORTFILE_INTERVAL)+" seconds of inactivity!");
- break;
- }
- // Check if the portfile is still there.
- if (!portFile.exists()) {
- // Time to quit because the portfile was deleted by another
- // process, probably by the makefile that is done building.
- log("Quitting because portfile was deleted!");
- flushLog();
- break;
- }
- // Check if portfile.stop is still there.
- if (portFile.markedForStop()) {
- // Time to quit because another process touched the file
- // server.port.stop to signal that the server should stop.
- // This is necessary on some operating systems that lock
- // the port file hard!
- log("Quitting because a portfile.stop file was found!");
- portFile.delete();
- flushLog();
- break;
- }
- // Does the portfile still point to me?
- if (!portFile.stillMyValues()) {
- // Time to quit because another build has started.
- log("Quitting because portfile is now owned by another javac server!");
- flushLog();
- break;
- }
-
- // Check how long since the last request finished.
- long diff = System.currentTimeMillis() - compilerPool.lastRequestFinished();
- if (diff < keepalive * 1000) {
- // Do not quit if we have waited less than 120 seconds.
- continue;
- }
- // Ok, time to quit because of inactivity. Perhaps the build
- // was killed and the portfile not cleaned up properly.
- portFile.delete();
- fileDeleted = true;
- log("" + keepalive + " seconds of inactivity quitting in "
- + CHECK_PORTFILE_INTERVAL + " seconds!");
- flushLog();
- // Now we have a second 5 second grace
- // period where javac remote requests
- // that have loaded the data from the
- // recently deleted portfile can connect
- // and complete their requests.
- }
- }
- } catch (Exception e) {
- e.printStackTrace(err);
- e.printStackTrace(theLog);
- flushLog();
- } finally {
- compilerPool.shutdown();
- }
- long realTime = System.currentTimeMillis() - serverStart;
- log("Shutting down.");
- log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
- flushLog();
- }
-
- public static void cleanup(String... args) {
- String settings = Util.findServerSettings(args);
- if (settings == null) return;
- String portfile = Util.extractStringOption("portfile", settings);
- String background = Util.extractStringOption("background", settings);
- if (background != null && background.equals("false")) {
- // If the server runs within this jvm, then delete the portfile,
- // since this jvm is about to exit soon.
- File f = new File(portfile);
- f.delete();
- }
- }
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacService.java Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.server;
-
-import java.io.File;
-import java.net.URI;
-import java.util.List;
-import java.util.Set;
-
-public interface JavacService {
-
- SysInfo getSysInfo();
-
- CompilationResult compile(String protocolId,
- String invocationId,
- String[] args,
- List<File> explicitSources,
- Set<URI> sourcesToCompile,
- Set<URI> visibleSources);
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacServiceClient.java Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,433 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.server;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.URI;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.sun.tools.sjavac.Util;
-
-import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
-import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
-
-public class JavacServiceClient implements JavacService {
-
-
- // The id can perhaps be used in the future by the javac server to reuse the
- // JavaCompiler instance for several compiles using the same id.
- private final String id;
- private final String portfile;
- private final String logfile;
- private final String stdouterrfile;
- private final boolean background;
-
- // Default keepalive for server is 120 seconds.
- // I.e. it will accept 120 seconds of inactivity before quitting.
- private final int keepalive;
- private final int poolsize;
-
- // The sjavac option specifies how the server part of sjavac is spawned.
- // If you have the experimental sjavac in your path, you are done. If not, you have
- // to point to a com.sun.tools.sjavac.Main that supports --startserver
- // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
- private final String sjavac;
-
- public JavacServiceClient(String settings) {
- id = Util.extractStringOption("id", settings);
- portfile = Util.extractStringOption("portfile", settings);
- logfile = Util.extractStringOption("logfile", settings, portfile + ".javaclog");
- stdouterrfile = Util.extractStringOption("stdouterrfile", settings, portfile + ".stdouterr");
- background = Util.extractBooleanOption("background", settings, true);
- sjavac = Util.extractStringOption("sjavac", settings, "sjavac");
- int poolsize = Util.extractIntOption("poolsize", settings);
- keepalive = Util.extractIntOption("keepalive", settings, 120);
-
- this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
- }
-
-
- /**
- * Make a request to the server only to get the maximum possible heap size to use for compilations.
- *
- * @param port_file The port file used to synchronize creation of this server.
- * @param id The identify of the compilation.
- * @param out Standard out information.
- * @param err Standard err information.
- * @return The maximum heap size in bytes.
- */
- @Override
- public SysInfo getSysInfo() {
- try {
- CompilationResult cr = useServer(new String[0],
- Collections.<URI>emptySet(),
- Collections.<URI>emptySet(),
- Collections.<URI, Set<String>>emptyMap());
- return cr.sysinfo;
- } catch (Exception e) {
- return new SysInfo(-1, -1);
- }
- }
-
- @Override
- public CompilationResult compile(String protocolId,
- String invocationId,
- String[] args,
- List<File> explicitSources,
- Set<URI> sourcesToCompile,
- Set<URI> visibleSources) {
- // Delegate to useServer, which delegates to compileHelper
- return useServer(args, sourcesToCompile, visibleSources, null);
- }
-
- /**
- * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
- * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
- */
- public CompilationResult compileHelper(String id,
- String[] args,
- Set<URI> sourcesToCompile,
- Set<URI> visibleSources) {
-
- CompilationResult rc = new CompilationResult(-3);
-
- try {
- PortFile portFile = JavacServer.getPortFile(this.portfile);
-
- int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
- if (port == 0) {
- return new CompilationResult(ERROR_BUT_TRY_AGAIN);
- }
- long cookie = portFile.getCookie();
- // Acquire the localhost/127.0.0.1 address.
- InetAddress addr = InetAddress.getByName(null);
- SocketAddress sockaddr = new InetSocketAddress(addr, port);
- Socket sock = new Socket();
- int timeoutMs = JavacServer.CONNECTION_TIMEOUT * 1000;
- try {
- sock.connect(sockaddr, timeoutMs);
- } catch (java.net.ConnectException e) {
- rc.setReturnCode(ERROR_BUT_TRY_AGAIN);
- rc.stderr = "Could not connect to javac server found in portfile: " + portFile.getFilename() + " " + e;
- return rc;
- }
- if (!sock.isConnected()) {
- rc.setReturnCode(ERROR_BUT_TRY_AGAIN);
- rc.stderr = "Could not connect to javac server found in portfile: " + portFile.getFilename();
- return rc;
- }
-
- //
- // Send arguments
- //
- BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
- PrintWriter sockout = new PrintWriter(sock.getOutputStream());
-
- sockout.println(JavacServer.PROTOCOL_COOKIE_VERSION);
- sockout.println("" + cookie);
- sockout.println(JavacServer.PROTOCOL_CWD);
- sockout.println(System.getProperty("user.dir"));
- sockout.println(JavacServer.PROTOCOL_ID);
- sockout.println(id);
- sockout.println(JavacServer.PROTOCOL_ARGS);
- for (String s : args) {
- StringBuffer buf = new StringBuffer();
- String[] paths = s.split(File.pathSeparator);
- int c = 0;
- for (String path : paths) {
- File f = new File(path);
- if (f.isFile() || f.isDirectory()) {
- buf.append(f.getAbsolutePath());
- c++;
- if (c < paths.length) {
- buf.append(File.pathSeparator);
- }
- } else {
- buf = new StringBuffer(s);
- break;
- }
- }
- sockout.println(buf.toString());
- }
- sockout.println(JavacServer.PROTOCOL_SOURCES_TO_COMPILE);
- for (URI uri : sourcesToCompile) {
- sockout.println(uri.toString());
- }
- sockout.println(JavacServer.PROTOCOL_VISIBLE_SOURCES);
- for (URI uri : visibleSources) {
- sockout.println(uri.toString());
- }
- sockout.println(JavacServer.PROTOCOL_END);
- sockout.flush();
-
- //
- // Receive result
- //
- StringBuffer stdout = new StringBuffer();
- StringBuffer stderr = new StringBuffer();
-
- if (!JavacServiceClient.expect(in, JavacServer.PROTOCOL_STDOUT)) {
- return new CompilationResult(ERROR_FATAL);
- }
- // Load stdout
- for (;;) {
- String l = in.readLine();
- if (l == null) {
- return new CompilationResult(ERROR_FATAL);
- }
- if (l.equals(JavacServer.PROTOCOL_STDERR)) {
- break;
- }
- stdout.append(l);
- stdout.append('\n');
- }
- // Load stderr
- for (;;) {
- String l = in.readLine();
- if (l == null) {
- return new CompilationResult(ERROR_FATAL);
- }
- if (l.equals(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS)) {
- break;
- }
- stderr.append(l);
- stderr.append('\n');
- }
- // Load the package artifacts
- Set<URI> lastUriSet = null;
- for (;;) {
- String l = in.readLine();
- if (l == null) {
- return new CompilationResult(ERROR_FATAL);
- }
- if (l.equals(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES)) {
- break;
- }
- if (l.length() > 1 && l.charAt(0) == '+') {
- String pkg = l.substring(1);
- lastUriSet = new HashSet<>();
- rc.packageArtifacts.put(pkg, lastUriSet);
- } else if (l.length() > 1 && lastUriSet != null) {
- lastUriSet.add(new URI(l.substring(1)));
- }
- }
- // Load package dependencies
- Set<String> lastPackageSet = null;
- for (;;) {
- String l = in.readLine();
- if (l == null) {
- return new CompilationResult(ERROR_FATAL);
- }
- if (l.equals(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS)) {
- break;
- }
- if (l.length() > 1 && l.charAt(0) == '+') {
- String pkg = l.substring(1);
- lastPackageSet = new HashSet<>();
- rc.packageDependencies.put(pkg, lastPackageSet);
- } else if (l.length() > 1 && lastPackageSet != null) {
- lastPackageSet.add(l.substring(1));
- }
- }
- // Load package pubapis
- Map<String, StringBuffer> tmp = new HashMap<>();
- StringBuffer lastPublicApi = null;
- for (;;) {
- String l = in.readLine();
- if (l == null) {
- return new CompilationResult(ERROR_FATAL);
- }
- if (l.equals(JavacServer.PROTOCOL_SYSINFO)) {
- break;
- }
- if (l.length() > 1 && l.charAt(0) == '+') {
- String pkg = l.substring(1);
- lastPublicApi = new StringBuffer();
- tmp.put(pkg, lastPublicApi);
- } else if (l.length() > 1 && lastPublicApi != null) {
- lastPublicApi.append(l.substring(1));
- lastPublicApi.append("\n");
- }
- }
- for (String p : tmp.keySet()) {
- //assert (packagePublicApis.get(p) == null);
- String api = tmp.get(p).toString();
- rc.packagePubapis.put(p, api);
- }
- // Now reading the max memory possible.
- for (;;) {
- String l = in.readLine();
- if (l == null) {
- return new CompilationResult(ERROR_FATAL);
- }
- if (l.equals(JavacServer.PROTOCOL_RETURN_CODE)) {
- break;
- }
- if (l.startsWith("num_cores=")) {
- rc.sysinfo.numCores = Integer.parseInt(l.substring(10));
- }
- if (l.startsWith("max_memory=")) {
- rc.sysinfo.maxMemory = Long.parseLong(l.substring(11));
- }
- }
- String l = in.readLine();
- if (l == null) {
- rc.setReturnCode(ERROR_FATAL);
- rc.stderr = "No return value from the server!";
- return rc;
- }
- rc.setReturnCode(Integer.parseInt(l));
- rc.stdout = stdout.toString();
- rc.stderr = stderr.toString();
- } catch (Exception e) {
- StringWriter sw = new StringWriter();
- e.printStackTrace(new PrintWriter(sw));
- rc.stderr = sw.toString();
- }
- return rc;
- }
-
- /**
- * Dispatch a compilation request to a javac server.
- *
- * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
- *
- * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
- *
- * @param sources_to_compile The sources to compile.
- *
- * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
- * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
- *
- * @param visibleClasses If visible classes for a specific root/jar has a non zero size, then visible_classes are the only class files that the javac server
- * can see, in that root/jar. It maps from a classpath root or a jar file to the set of visible classes for that root/jar.
- *
- * The server return meta data about the build in the following parameters.
- * @param package_artifacts, map from package name to set of created artifacts for that package.
- * @param package_dependencies, map from package name to set of packages that it depends upon.
- * @param package_pubapis, map from package name to unique string identifying its pub api.
- */
- public CompilationResult useServer(String[] args,
- Set<URI> sourcesToCompile,
- Set<URI> visibleSources,
- Map<URI, Set<String>> visibleClasses) {
- try {
- if (portfile == null) {
- CompilationResult cr = new CompilationResult(CompilationResult.ERROR_FATAL);
- cr.stderr = "No portfile was specified!";
- return cr;
- }
-
- int attempts = 0;
- CompilationResult rc;
- do {
- PortFile port_file = JavacServer.getPortFile(portfile);
- synchronized (port_file) {
- port_file.lock();
- port_file.getValues();
- port_file.unlock();
- }
- if (!port_file.containsPortInfo()) {
- String cmd = JavacServer.fork(sjavac, port_file.getFilename(), logfile, poolsize, keepalive, System.err, stdouterrfile, background);
-
- if (background && !port_file.waitForValidValues()) {
- // Ouch the server did not start! Lets print its stdouterrfile and the command used.
- StringWriter sw = new StringWriter();
- JavacServiceClient.printFailedAttempt(cmd, stdouterrfile, new PrintWriter(sw));
- // And give up.
- CompilationResult cr = new CompilationResult(ERROR_FATAL);
- cr.stderr = sw.toString();
- return cr;
- }
- }
- rc = compileHelper(id, args, sourcesToCompile, visibleSources);
- // Try again until we manage to connect. Any error after that
- // will cause the compilation to fail.
- if (rc.returnCode == CompilationResult.ERROR_BUT_TRY_AGAIN) {
- // We could not connect to the server. Try again.
- attempts++;
- try {
- Thread.sleep(JavacServer.WAIT_BETWEEN_CONNECT_ATTEMPTS * 1000);
- } catch (InterruptedException e) {
- }
- }
- } while (rc.returnCode == ERROR_BUT_TRY_AGAIN && attempts < JavacServer.MAX_NUM_CONNECT_ATTEMPTS);
- return rc;
- } catch (Exception e) {
- StringWriter sw = new StringWriter();
- e.printStackTrace(new PrintWriter(sw));
- CompilationResult cr = new CompilationResult(ERROR_FATAL);
- cr.stderr = sw.toString();
- return cr;
- }
- }
-
- public static void printFailedAttempt(String cmd, String f, PrintWriter err) {
- err.println("---- Failed to start javac server with this command -----");
- err.println(cmd);
- try {
- BufferedReader in = new BufferedReader(new FileReader(f));
- err.println("---- stdout/stderr output from attempt to start javac server -----");
- for (;;) {
- String l = in.readLine();
- if (l == null) {
- break;
- }
- err.println(l);
- }
- err.println("------------------------------------------------------------------");
- } catch (Exception e) {
- err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
- }
- }
-
- /**
- * Expect this key on the next line read from the reader.
- */
- public static boolean expect(BufferedReader in, String key) throws IOException {
- String s = in.readLine();
- if (s != null && s.equals(key)) {
- return true;
- }
- return false;
- }
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/PortFile.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/PortFile.java Thu Aug 28 14:53:49 2014 -0700
@@ -33,6 +33,7 @@
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.FileLockInterruptionException;
+import com.sun.tools.javac.util.Assert;
import com.sun.tools.sjavac.Log;
/**
@@ -41,12 +42,12 @@
* primitives to avoid race conditions when several javac clients are started at the same. Note that file
* system locking is not always supported on a all operating systems and/or file systems.
*
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
*/
-class PortFile {
+public class PortFile {
// Port file format:
// byte ordering: high byte first = big endian
@@ -72,8 +73,7 @@
* Create a new portfile.
* @param filename is the path to the file.
*/
- public PortFile(String fn) throws FileNotFoundException
- {
+ public PortFile(String fn) throws FileNotFoundException {
filename = fn;
file = new File(filename);
stopFile = new File(filename+".stop");
@@ -88,7 +88,7 @@
/**
* Lock the port file.
*/
- void lock() throws IOException {
+ public void lock() throws IOException {
lock = channel.lock();
}
@@ -115,7 +115,7 @@
containsPortInfo = false;
}
}
- } catch (Exception e) {
+ } catch (IOException e) {
containsPortInfo = false;
}
}
@@ -131,7 +131,7 @@
* If so, then we can acquire the tcp/ip port on localhost.
*/
public int getPort() {
- assert(containsPortInfo);
+ Assert.check(containsPortInfo);
return serverPort;
}
@@ -139,7 +139,7 @@
* If so, then we can acquire the server cookie.
*/
public long getCookie() {
- assert(containsPortInfo);
+ Assert.check(containsPortInfo);
return serverCookie;
}
@@ -147,7 +147,7 @@
* Store the values into the locked port file.
*/
public void setValues(int port, long cookie) throws IOException {
- assert(lock != null);
+ Assert.check(lock != null);
rwfile.seek(0);
// Write the magic nr that identifes a port file.
rwfile.writeInt(magicNr);
@@ -192,7 +192,7 @@
* Unlock the port file.
*/
public void unlock() throws IOException {
- assert(lock != null);
+ Assert.check(lock != null);
lock.release();
lock = null;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/PortFileMonitor.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.IOException;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Monitors the presence of a port file and shuts down the given SjavacServer
+ * whenever the port file is deleted or invalidated.
+ *
+ * TODO: JDK-8046882
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class PortFileMonitor {
+
+ // Check if the portfile is gone, every 5 seconds.
+ private final static int CHECK_PORTFILE_INTERVAL = 5000;
+
+ final private Timer timer = new Timer();
+ final private PortFile portFile;
+ final private SjavacServer server;
+
+ public PortFileMonitor(PortFile portFile,
+ SjavacServer server) {
+ this.portFile = portFile;
+ this.server = server;
+ }
+
+ public void start() {
+ TimerTask shutdownCheck = new TimerTask() {
+ public void run() {
+ try {
+ if (!portFile.exists()) {
+ // Time to quit because the portfile was deleted by another
+ // process, probably by the makefile that is done building.
+ server.shutdown("Quitting because portfile was deleted!");
+ } else if (portFile.markedForStop()) {
+ // Time to quit because another process touched the file
+ // server.port.stop to signal that the server should stop.
+ // This is necessary on some operating systems that lock
+ // the port file hard!
+ server.shutdown("Quitting because a portfile.stop file was found!");
+ } else if (!portFile.stillMyValues()) {
+ // Time to quit because another build has started.
+ server.shutdown("Quitting because portfile is now owned by another javac server!");
+ }
+ } catch (IOException e) {
+ e.printStackTrace(server.theLog);
+ server.flushLog();
+ }
+ }
+ };
+
+ timer.schedule(shutdownCheck, 0, CHECK_PORTFILE_INTERVAL);
+ }
+
+ public void shutdown() {
+ timer.cancel();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.Socket;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+import com.sun.tools.sjavac.Log;
+
+/**
+ * A RequestHandler handles requests performed over a socket. Specifically it
+ * - Reads the command string specifying which method is to be invoked
+ * - Reads the appropriate arguments
+ * - Delegates the actual invocation to the given sjavac implementation
+ * - Writes the result back to the socket output stream
+ *
+ * None of the work performed by this class is really bound by the CPU. It
+ * should be completely fine to have a large number of RequestHandlers active.
+ * To limit the number of concurrent compilations, use PooledSjavac.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class RequestHandler implements Runnable {
+
+ private final Socket socket;
+ private final Sjavac sjavac;
+
+ public RequestHandler(Socket socket, Sjavac sjavac) {
+ this.socket = socket;
+ this.sjavac = sjavac;
+ }
+
+ @Override
+ public void run() {
+ try (ObjectOutputStream oout = new ObjectOutputStream(socket.getOutputStream());
+ ObjectInputStream oin = new ObjectInputStream(socket.getInputStream())) {
+ String id = (String) oin.readObject();
+ String cmd = (String) oin.readObject();
+ Log.info("Handling request, id: " + id + " cmd: " + cmd);
+ switch (cmd) {
+ case SjavacServer.CMD_SYS_INFO: handleSysInfoRequest(oin, oout); break;
+ case SjavacServer.CMD_COMPILE: handleCompileRequest(oin, oout); break;
+ default: Log.error("Unknown command: " + cmd);
+ }
+ } catch (Exception ex) {
+ // Not much to be done at this point. The client side request
+ // code will most likely throw an IOException and the
+ // compilation will fail.
+ StringWriter sw = new StringWriter();
+ ex.printStackTrace(new PrintWriter(sw));
+ Log.error(sw.toString());
+ }
+ }
+
+ private void handleSysInfoRequest(ObjectInputStream oin,
+ ObjectOutputStream oout) throws IOException {
+ oout.writeObject(sjavac.getSysInfo());
+ oout.flush();
+ }
+
+ @SuppressWarnings("unchecked")
+ private void handleCompileRequest(ObjectInputStream oin,
+ ObjectOutputStream oout) throws IOException {
+ try {
+ // Read request arguments
+ String protocolId = (String) oin.readObject();
+ String invocationId = (String) oin.readObject();
+ String[] args = (String[]) oin.readObject();
+ List<File> explicitSources = (List<File>) oin.readObject();
+ Set<URI> sourcesToCompile = (Set<URI>) oin.readObject();
+ Set<URI> visibleSources = (Set<URI>) oin.readObject();
+
+ // Perform compilation
+ CompilationResult cr = sjavac.compile(protocolId,
+ invocationId,
+ args,
+ explicitSources,
+ sourcesToCompile,
+ visibleSources);
+ // Write request response
+ oout.writeObject(cr);
+ oout.flush();
+ } catch (ClassNotFoundException cnfe) {
+ throw new IOException(cnfe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Interface of the SjavacImpl, the sjavac client and all wrappers such as
+ * PooledSjavac etc.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public interface Sjavac {
+
+ SysInfo getSysInfo();
+
+ CompilationResult compile(String protocolId,
+ String invocationId,
+ String[] args,
+ List<File> explicitSources,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources);
+
+ void shutdown();
+ String serverSettings();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.sun.tools.sjavac.ProblemException;
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.comp.SjavacImpl;
+import com.sun.tools.sjavac.comp.PooledSjavac;
+
+/**
+ * The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class SjavacServer implements Terminable {
+
+ // Used in protocol to indicate which method to invoke
+ public final static String CMD_COMPILE = "compile";
+ public final static String CMD_SYS_INFO = "sys-info";
+
+ final private String portfilename;
+ final private String logfile;
+ final private String stdouterrfile;
+ final private int poolsize;
+ final private int keepalive;
+ final private PrintStream err;
+
+ // The secret cookie shared between server and client through the port file.
+ // Used to prevent clients from believing that they are communicating with
+ // an old server when a new server has started and reused the same port as
+ // an old server.
+ private final long myCookie;
+
+ // Accumulated build time, not counting idle time, used for logging purposes
+ private long totalBuildTime;
+
+ // The javac server specific log file.
+ PrintWriter theLog;
+
+ // The sjavac implementation to delegate requests to
+ Sjavac sjavac;
+
+ private ServerSocket serverSocket;
+
+ private PortFile portFile;
+ private PortFileMonitor portFileMonitor;
+
+ // Set to false break accept loop
+ final AtomicBoolean keepAcceptingRequests = new AtomicBoolean();
+
+ // For the client, all port files fetched, one per started javac server.
+ // Though usually only one javac server is started by a client.
+ private static Map<String, PortFile> allPortFiles;
+ private static Map<String, Long> maxServerMemory;
+
+ public SjavacServer(String settings, PrintStream err) throws FileNotFoundException {
+ // Extract options. TODO: Change to proper constructor args
+ portfilename = Util.extractStringOption("portfile", settings);
+ logfile = Util.extractStringOption("logfile", settings);
+ stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
+ keepalive = Util.extractIntOption("keepalive", settings, 120);
+ poolsize = Util.extractIntOption("poolsize", settings,
+ Runtime.getRuntime().availableProcessors());
+ this.err = err;
+
+ myCookie = new Random().nextLong();
+ theLog = new PrintWriter(logfile);
+ }
+
+
+ /**
+ * Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
+ */
+ public static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
+ if (allPortFiles == null) {
+ allPortFiles = new HashMap<>();
+ }
+ PortFile pf = allPortFiles.get(filename);
+
+ // Port file known. Does it still exist?
+ if (pf != null) {
+ try {
+ if (!pf.exists())
+ pf = null;
+ } catch (IOException ioex) {
+ ioex.printStackTrace();
+ }
+ }
+
+ if (pf == null) {
+ pf = new PortFile(filename);
+ allPortFiles.put(filename, pf);
+ }
+ return pf;
+ }
+
+ /**
+ * Get the cookie used for this server.
+ */
+ long getCookie() {
+ return myCookie;
+ }
+
+ /**
+ * Get the port used for this server.
+ */
+ int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ /**
+ * Sum up the total build time for this javac server.
+ */
+ public void addBuildTime(long inc) {
+ totalBuildTime += inc;
+ }
+
+ /**
+ * Log this message.
+ */
+ public void log(String msg) {
+ if (theLog != null) {
+ theLog.println(msg);
+ } else {
+ System.err.println(msg);
+ }
+ }
+
+ /**
+ * Make sure the log is flushed.
+ */
+ public void flushLog() {
+ if (theLog != null) {
+ theLog.flush();
+ }
+ }
+
+ /**
+ * Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
+ * is sent as the settings parameter. Returns 0 on success, -1 on failure.
+ */
+ public int startServer() throws IOException {
+ long serverStart = System.currentTimeMillis();
+
+ // The port file is locked and the server port and cookie is written into it.
+ portFile = getPortFile(portfilename);
+
+ synchronized (portFile) {
+ portFile.lock();
+ portFile.getValues();
+ if (portFile.containsPortInfo()) {
+ err.println("Javac server not started because portfile exists!");
+ portFile.unlock();
+ return -1;
+ }
+
+ // .-----------. .--------. .------.
+ // socket -->| IdleReset |-->| Pooled |-->| Impl |--> javac
+ // '-----------' '--------' '------'
+ sjavac = new SjavacImpl();
+ sjavac = new PooledSjavac(sjavac, poolsize);
+ sjavac = new IdleResetSjavac(sjavac,
+ this,
+ keepalive * 1000);
+
+ serverSocket = new ServerSocket();
+ InetAddress localhost = InetAddress.getByName(null);
+ serverSocket.bind(new InetSocketAddress(localhost, 0));
+
+ // At this point the server accepts connections, so it is now safe
+ // to publish the port / cookie information
+ portFile.setValues(getPort(), getCookie());
+ portFile.unlock();
+ }
+
+ portFileMonitor = new PortFileMonitor(portFile, this);
+ portFileMonitor.start();
+
+ log("Sjavac server started. Accepting connections...");
+ log(" port: " + getPort());
+ log(" time: " + new java.util.Date());
+ log(" poolsize: " + poolsize);
+ flushLog();
+
+ keepAcceptingRequests.set(true);
+ do {
+ try {
+ Socket socket = serverSocket.accept();
+ new Thread(new RequestHandler(socket, sjavac)).start();
+ } catch (SocketException se) {
+ // Caused by serverSocket.close() and indicates shutdown
+ }
+ } while (keepAcceptingRequests.get());
+
+ log("Shutting down.");
+
+ // No more connections accepted. If any client managed to connect after
+ // the accept() was interrupted but before the server socket is closed
+ // here, any attempt to read or write to the socket will result in an
+ // IOException on the client side.
+
+ long realTime = System.currentTimeMillis() - serverStart;
+ log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
+ flushLog();
+
+ // Shut down
+ sjavac.shutdown();
+
+ return 0;
+ }
+
+ /**
+ * Fork a background process. Returns the command line used that can be printed if something failed.
+ */
+ public static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
+ final PrintStream err, String stdouterrfile, boolean background)
+ throws IOException, ProblemException {
+ if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
+ stdouterrfile = null;
+ }
+ final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
+
+ if (background) {
+ sjavac += "%20" + startserver;
+ sjavac = sjavac.replaceAll("%20", " ");
+ sjavac = sjavac.replaceAll("%2C", ",");
+ // If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
+ String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
+ if (!(new File("/bin/sh")).canExecute()) {
+ ArrayList<String> wincmd = new ArrayList<>();
+ wincmd.add("cmd");
+ wincmd.add("/c");
+ wincmd.add("start");
+ wincmd.add("cmd");
+ wincmd.add("/c");
+ wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
+ cmd = wincmd.toArray(new String[wincmd.size()]);
+ }
+ Process pp = null;
+ try {
+ pp = Runtime.getRuntime().exec(cmd);
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ e.printStackTrace(new PrintWriter(stdouterrfile));
+ }
+ StringBuilder rs = new StringBuilder();
+ for (String s : cmd) {
+ rs.append(s + " ");
+ }
+ return rs.toString();
+ }
+
+ // Do not spawn a background server, instead run it within the same JVM.
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ SjavacServer server = new SjavacServer(startserver, err);
+ server.startServer();
+ } catch (Throwable t) {
+ t.printStackTrace(err);
+ }
+ }
+ };
+ t.setDaemon(true);
+ t.start();
+ return "";
+ }
+
+ @Override
+ public void shutdown(String quitMsg) {
+ if (!keepAcceptingRequests.compareAndSet(false, true)) {
+ // Already stopped, no need to shut down again
+ return;
+ }
+
+ log("Quitting: " + quitMsg);
+ flushLog();
+
+ portFileMonitor.shutdown(); // No longer any need to monitor port file
+
+ // Unpublish port before shutting down socket to minimize the number of
+ // failed connection attempts
+ try {
+ portFile.delete();
+ } catch (IOException e) {
+ e.printStackTrace(theLog);
+ }
+ try {
+ serverSocket.close();
+ } catch (IOException e) {
+ e.printStackTrace(theLog);
+ }
+ }
+
+ public static void cleanup(String... args) {
+ String settings = Util.findServerSettings(args);
+ if (settings == null) return;
+ String portfile = Util.extractStringOption("portfile", settings);
+ String background = Util.extractStringOption("background", settings);
+ if (background != null && background.equals("false")) {
+ // If the server runs within this jvm, then delete the portfile,
+ // since this jvm is about to exit soon.
+ File f = new File(portfile);
+ f.delete();
+ }
+ }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SysInfo.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SysInfo.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,18 @@
*/
package com.sun.tools.sjavac.server;
-public class SysInfo {
+import java.io.Serializable;
+
+/**
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class SysInfo implements Serializable {
+
+ static final long serialVersionUID = -3096346807579L;
+
public int numCores;
public long maxMemory;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Terminable.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+/**
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public interface Terminable {
+ void shutdown(String quitMsg);
+}
--- a/langtools/test/com/sun/javadoc/lib/JavadocTester.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/com/sun/javadoc/lib/JavadocTester.java Thu Aug 28 14:53:49 2014 -0700
@@ -38,6 +38,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
+import java.util.Arrays;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
@@ -290,6 +291,7 @@
break;
}
}
+ out.println("args: " + Arrays.toString(args));
// log.setOutDir(outputDir);
outputDirectoryCheck.check(outputDir);
--- a/langtools/test/tools/apt/Basics/CheckAptIsRemovedTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/apt/Basics/CheckAptIsRemovedTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 4908512 5024825 4957203 4993280 4996963 6174696 6177059 7041249
* @summary Make sure apt is removed and doesn't come back
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main CheckAptIsRemovedTest
*/
@@ -34,7 +34,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
-//original test: test/tools/apt/Basics/apt.sh
+// Original test: test/tools/apt/Basics/apt.sh
public class CheckAptIsRemovedTest {
//I think this class can be let with the imports only and that should be enough for as test's purpose
private static final String NullAPFSrc =
@@ -77,20 +77,18 @@
Path aptLin = Paths.get(testJDK, "bin", "apt");
Path aptWin = Paths.get(testJDK, "bin", "apt.exe");
-// if [ -f "${TESTJAVA}/bin/apt" -o -f "${TESTJAVA}/bin/apt.exe" ];then
if (Files.exists(aptLin) || Files.exists(aptWin)) {
throw new AssertionError("apt executable should not exist");
}
-// JAVAC="${TESTJAVA}/bin/javac ${TESTTOOLVMOPTS} -source 1.5 -sourcepath ${TESTSRC} -classpath ${TESTJAVA}/lib/tools.jar -d . "
-// $JAVAC ${TESTSRC}/NullAPF.java
Path classpath = Paths.get(testJDK, "lib", "tools.jar");
- ToolBox.JavaToolArgs javacArgs =
- new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
- .setOptions("-sourcepath", ".",
- "-classpath", classpath.toString())
- .setSources(NullAPFSrc);
- ToolBox.javac(javacArgs);
+ ToolBox tb = new ToolBox();
+ tb.new JavacTask()
+ .classpath(classpath.toString()) // TODO: add overload
+ .sourcepath(".")
+ .sources(NullAPFSrc)
+ .run(ToolBox.Expect.FAIL)
+ .writeAll();
}
}
--- a/langtools/test/tools/javac/4846262/CheckEBCDICLocaleTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/4846262/CheckEBCDICLocaleTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,17 @@
* @test
* @bug 4846262
* @summary check that javac operates correctly in EBCDIC locale
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main CheckEBCDICLocaleTest
*/
import java.io.File;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
+import java.util.List;
public class CheckEBCDICLocaleTest {
@@ -58,39 +60,32 @@
}
public void test() throws Exception {
- String native2asciiBinary = Paths.get(
- System.getProperty("test.jdk"),"bin", "native2ascii").toString();
-
- ToolBox.createJavaFileFromSource(TestSrc);
- Files.createDirectory(Paths.get("output"));
+ ToolBox tb = new ToolBox();
+ Path native2asciiBinary = tb.getJDKTool("native2ascii");
- ToolBox.AnyToolArgs nativeCmdParams =
- new ToolBox.AnyToolArgs()
- .appendArgs(native2asciiBinary)
- .appendArgs(ToolBox.testToolVMOpts)
- .appendArgs("-reverse", "-encoding", "IBM1047", "Test.java",
- "output/Test.java");
- ToolBox.executeCommand(nativeCmdParams);
+ tb.writeFile("Test.java", TestSrc);
+ tb.createDirectories("output");
+
+ tb.new ExecTask(native2asciiBinary)
+ .args("-reverse", "-encoding", "IBM1047", "Test.java", "output/Test.java")
+ .run();
- ToolBox.AnyToolArgs javacParams =
- new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
- .appendArgs(ToolBox.javacBinary)
- .appendArgs(ToolBox.testToolVMOpts)
- .appendArgs("-J-Duser.language=en",
- "-J-Duser.region=US", "-J-Dfile.encoding=IBM1047",
- "output/Test.java")
- .setErrOutput(new File("Test.tmp"));
- ToolBox.executeCommand(javacParams);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .redirect(ToolBox.OutputKind.STDERR, "Test.tmp")
+ .options("-J-Duser.language=en",
+ "-J-Duser.region=US",
+ "-J-Dfile.encoding=IBM1047")
+ .files("output/Test.java")
+ .run(ToolBox.Expect.FAIL);
- nativeCmdParams = new ToolBox.AnyToolArgs()
- .appendArgs(native2asciiBinary)
- .appendArgs(ToolBox.testToolVMOpts)
- .appendArgs("-encoding", "IBM1047", "Test.tmp", "Test.out");
- ToolBox.executeCommand(nativeCmdParams);
+ tb.new ExecTask(native2asciiBinary)
+ .args("-encoding", "IBM1047", "Test.tmp", "Test.out")
+ .run();
- String goldenFile = String.format(TestOutTemplate, File.separator);
- ToolBox.compareLines(Paths.get("Test.out"),
- Arrays.asList(goldenFile.split("\n")), null, true);
+ List<String> expectLines = Arrays.asList(
+ String.format(TestOutTemplate, File.separator).split("\n"));
+ List<String> actualLines = Files.readAllLines(Paths.get("Test.out"));
+ tb.checkEqual(expectLines, actualLines);
}
}
--- a/langtools/test/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
* @bug 6302184 6350124 6357979
* @summary javac hidden options that generate source should use the given
* encoding, if available
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run compile -encoding iso-8859-1 -XD-printsource T6302184.java
* @run main HiddenOptionsShouldUseGivenEncodingTest
@@ -34,16 +34,19 @@
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.List;
-//original test: test/tools/javac/6302184/T6302184.sh
+// Original test: test/tools/javac/6302184/T6302184.sh
public class HiddenOptionsShouldUseGivenEncodingTest {
public static void main(String[] args) throws Exception {
-//"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -cp ${TC} -encoding iso-8859-1 -XD-printsource ${TS}${FS}T6302184.java 2>&1
-//diff ${DIFFOPTS} -c ${TC}${FS}T6302184.java ${TS}${FS}T6302184.out
- Path path1 = Paths.get(System.getProperty("test.classes"), "T6302184.java");
- Path path2 = Paths.get(System.getProperty("test.src"), "T6302184.out");
- ToolBox.compareLines(path1, path2, "iso-8859-1");
+ ToolBox tb = new ToolBox();
+ String encoding = "iso-8859-1";
+ Path path1 = Paths.get(ToolBox.testClasses, "T6302184.java");
+ List<String> file1 = tb.readAllLines(path1, encoding);
+ Path path2 = Paths.get(ToolBox.testSrc, "T6302184.out");
+ List<String> file2 = tb.readAllLines(path2, encoding);
+ tb.checkEqual(file1, file2);
}
}
--- a/langtools/test/tools/javac/AnonymousSubclassTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/AnonymousSubclassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,19 +25,18 @@
* @test
* @bug 8023945
* @summary javac wrongly allows a subclass of an anonymous class
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main AnonymousSubclassTest
*/
-import java.util.ArrayList;
-import java.io.IOException;
-
public class AnonymousSubclassTest {
public static void main(String... args) throws Exception {
new AnonymousSubclassTest().run();
}
+ ToolBox tb = new ToolBox();
+
// To trigger the error we want, first we need to compile
// a class with an anonymous inner class: Foo$1.
final String foo =
@@ -65,20 +64,21 @@
"}";
void compOk(String code) throws Exception {
- ToolBox.javac(new ToolBox.JavaToolArgs().setSources(code));
+ tb.new JavacTask()
+ .sources(code)
+ .run();
}
void compFail(String code) throws Exception {
- ArrayList<String> errors = new ArrayList<>();
- ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs();
- args.setSources(code)
- .appendArgs("-cp", ".", "-XDrawDiagnostics")
- .set(ToolBox.Expect.FAIL)
- .setErrOutput(errors);
- ToolBox.javac(args);
+ String errs = tb.new JavacTask()
+ .sources(code)
+ .classpath(".")
+ .options("-XDrawDiagnostics")
+ .run(ToolBox.Expect.FAIL)
+ .writeAll()
+ .getOutput(ToolBox.OutputKind.DIRECT);
- if (!errors.get(0).contains("cant.inherit.from.anon")) {
- System.out.println(errors.get(0));
+ if (!errs.contains("cant.inherit.from.anon")) {
throw new Exception("test failed");
}
}
--- a/langtools/test/tools/javac/ClassPathTest/ClassPathTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/ClassPathTest/ClassPathTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,19 +25,14 @@
* @test
* @bug 4241229 4785453
* @summary Test -classpath option and classpath defaults.
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main ClassPathTest
*/
import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-//original test: test/tools/javac/ClassPathTest/ClassPathTest.sh
+// Original test: test/tools/javac/ClassPathTest/ClassPathTest.sh
public class ClassPathTest {
private static final String ClassPathTest1Src =
@@ -70,12 +65,12 @@
"package pkg;\n" +
"public class ClassPathTestAux3 {}";
- ProcessBuilder pb = null;
-
public static void main(String[] args) throws Exception {
new ClassPathTest().test();
}
+ ToolBox tb = new ToolBox();
+
public void test() throws Exception {
createOutputDirAndSourceFiles();
checkCompileCommands();
@@ -83,14 +78,16 @@
void createOutputDirAndSourceFiles() throws Exception {
//dirs and files creation
- ToolBox.createJavaFileFromSource(ClassPathTest1Src);
- ToolBox.createJavaFileFromSource(ClassPathTest2Src);
- ToolBox.createJavaFileFromSource(ClassPathTest3Src);
- ToolBox.createJavaFileFromSource(Paths.get("foo"),
+ tb.writeJavaFiles(Paths.get("."),
+ ClassPathTest1Src,
+ ClassPathTest2Src,
+ ClassPathTest3Src);
+ tb.writeJavaFiles(Paths.get("foo"),
fooPkgClassPathTestAux1Src);
- ToolBox.createJavaFileFromSource(Paths.get("bar"),
+ tb.writeJavaFiles(Paths.get("bar"),
barPkgClassPathTestAux2Src);
- ToolBox.createJavaFileFromSource(pkgClassPathTestAux3Src);
+ tb.writeJavaFiles(Paths.get("."),
+ pkgClassPathTestAux3Src);
}
void checkCompileCommands() throws Exception {
@@ -99,80 +96,55 @@
// automatically but this is not happening when called using ProcessBuilder
// testJavac success ClassPathTest3.java
- List<String> mainArgs = new ArrayList<>();
- mainArgs.add(ToolBox.javacBinary.toString());
- if (ToolBox.testToolVMOpts != null) {
- mainArgs.addAll(ToolBox.testToolVMOpts);
- }
-
- List<String> commonArgs = new ArrayList<>();
- commonArgs.addAll(mainArgs);
- commonArgs.addAll(Arrays.asList("-cp", "."));
-
- ToolBox.AnyToolArgs successParams = new ToolBox.AnyToolArgs()
- .appendArgs(commonArgs)
- .appendArgs("ClassPathTest3.java");
- ToolBox.executeCommand(successParams);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .classpath(".")
+ .files("ClassPathTest3.java")
+ .run();
// testJavac failure ClassPathTest1.java
- ToolBox.AnyToolArgs failParams =
- new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
- .appendArgs(commonArgs)
- .appendArgs("ClassPathTest1.java");
- ToolBox.executeCommand(failParams);
-
-// This is done inside the executeCommand method
-// CLASSPATH=bar; export CLASSPATH
-
- Map<String, String> extVars = new TreeMap<>();
- extVars.put("CLASSPATH", "bar");
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .classpath(".")
+ .files("ClassPathTest1.java")
+ .run(ToolBox.Expect.FAIL);
// testJavac success ClassPathTest2.java
- successParams = new ToolBox.AnyToolArgs()
- .appendArgs(mainArgs)
- .appendArgs("ClassPathTest2.java")
- .set(extVars);
- ToolBox.executeCommand(successParams);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .envVar("CLASSPATH", "bar")
+ .files("ClassPathTest2.java")
+ .run();
// testJavac failure ClassPathTest1.java
- failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
- .appendArgs(mainArgs)
- .appendArgs("ClassPathTest1.java")
- .set(extVars);
- ToolBox.executeCommand(failParams);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .envVar("CLASSPATH", "bar")
+ .files("ClassPathTest1.java")
+ .run(ToolBox.Expect.FAIL);
// testJavac failure ClassPathTest3.java
- failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
- .appendArgs(mainArgs)
- .appendArgs("ClassPathTest3.java")
- .set(extVars);
- ToolBox.executeCommand(failParams);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .envVar("CLASSPATH", "bar")
+ .files("ClassPathTest3.java")
+ .run(ToolBox.Expect.FAIL);
// testJavac success -classpath foo ClassPathTest1.java
-
- commonArgs.clear();
- commonArgs.addAll(mainArgs);
- commonArgs.addAll(Arrays.asList("-cp", "foo"));
-
- successParams = new ToolBox.AnyToolArgs()
- .appendArgs(commonArgs)
- .appendArgs("ClassPathTest1.java")
- .set(extVars);
- ToolBox.executeCommand(successParams);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .envVar("CLASSPATH", "bar")
+ .classpath("foo")
+ .files("ClassPathTest1.java")
+ .run();
// testJavac failure -classpath foo ClassPathTest2.java
- failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
- .appendArgs(commonArgs)
- .appendArgs("ClassPathTest2.java")
- .set(extVars);
- ToolBox.executeCommand(failParams);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .envVar("CLASSPATH", "bar")
+ .classpath("foo")
+ .files("ClassPathTest2.java")
+ .run(ToolBox.Expect.FAIL);
// testJavac failure -classpath foo ClassPathTest3.java
- failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
- .appendArgs(commonArgs)
- .appendArgs("ClassPathTest3.java")
- .set(extVars);
- ToolBox.executeCommand(failParams);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .envVar("CLASSPATH", "bar")
+ .classpath("foo")
+ .files("ClassPathTest3.java")
+ .run(ToolBox.Expect.FAIL);
}
}
--- a/langtools/test/tools/javac/ConstFoldTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/ConstFoldTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 8025505
* @summary Constant folding deficiency
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main ConstFoldTest
*/
@@ -45,23 +45,23 @@
int x;
if (1 != 2) x=1; else x=0;
if (1 == 2) x=1; else x=0;
- if ("" != null) x=1; else x=0;
- if ("" == null) x=1; else x=0;
+ if ("" != null) x=1; else x=0;
+ if ("" == null) x=1; else x=0;
if (null == null) x=1; else x=0;
if (null != null) x=1; else x=0;
x = 1 != 2 ? 1 : 0;
x = 1 == 2 ? 1 : 0;
- x = "" != null ? 1 : 0;
- x = "" == null ? 1 : 0;
+ x = "" != null ? 1 : 0;
+ x = "" == null ? 1 : 0;
x = null == null ? 1 : 0;
x = null != null ? 1 : 0;
boolean b;
b = 1 != 2 && true;
b = 1 == 2 || true;
- b = ("" != null) && true;
- b = ("" == null) || true;
+ b = ("" != null) && true;
+ b = ("" == null) || true;
b = (null == null) && true;
b = (null != null) || true;
}
@@ -72,11 +72,17 @@
final String regex = "\\sif(?:null|nonnull|eq|ne){1}\\s";
void run() throws Exception {
+ ToolBox tb = new ToolBox();
+
URL url = ConstFoldTest.class.getResource("ConstFoldTest$CFTest.class");
- String result = ToolBox.javap(new ToolBox.JavaToolArgs().setAllArgs("-c", url.getFile()));
- System.out.println(result);
+ List<String> result = tb.new JavapTask()
+ .options("-c")
+ .classes(url.getFile())
+ .run()
+ .write(ToolBox.OutputKind.DIRECT)
+ .getOutputLines(ToolBox.OutputKind.DIRECT);
- List<String> bad_codes = ToolBox.grep(regex, result, "\n");
+ List<String> bad_codes = tb.grep(regex, result);
if (!bad_codes.isEmpty()) {
for (String code : bad_codes)
System.out.println("Bad OpCode Found: " + code);
--- a/langtools/test/tools/javac/ExtDirs/ExtDirTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/ExtDirs/ExtDirTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,14 @@
* @test
* @bug 4204897 4256097 4785453 4863609
* @summary Test that '.jar' files in -extdirs are found.
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main ExtDirTest
*/
import java.io.File;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.List;
-//original test: test/tools/javac/ExtDirs/ExtDirs.sh
+// Original test: test/tools/javac/ExtDirs/ExtDirs.sh
public class ExtDirTest {
private static final String ExtDirTestClass1Src =
@@ -100,72 +96,73 @@
"SHA-Digest: ILJOhwHg5US+yuw1Sc1d+Avu628=\n" +
"MD5-Digest: j8wnz8wneEcuJ/gjXBBQNA==\n";
- List<String> ouputDirParam = Arrays.asList("-d", ".");
-
public static void main(String args[]) throws Exception {
new ExtDirTest().run();
}
+ private final ToolBox tb = new ToolBox();
+
void run() throws Exception {
createJars();
compileWithExtDirs();
}
void createJars() throws Exception {
- sun.tools.jar.Main jarGenerator =
- new sun.tools.jar.Main(System.out, System.err, "jar");
+ tb.new JavacTask()
+ .outdir(".")
+ .sources(ExtDirTestClass1Src)
+ .run();
- ToolBox.JavaToolArgs javacParams =
- new ToolBox.JavaToolArgs()
- .setOptions(ouputDirParam)
- .setSources(ExtDirTestClass1Src);
- ToolBox.javac(javacParams);
+ tb.new JarTask("pkg1.jar")
+ .manifest(jar1Manifest)
+ .files("pkg1/ExtDirTestClass1.class")
+ .run();
- ToolBox.writeFile(Paths.get("pkg1", "MANIFEST.MF"), jar1Manifest);
- jarGenerator.run(new String[] {"cfm", "pkg1.jar", "pkg1/MANIFEST.MF",
- "pkg1/ExtDirTestClass1.class"});
-
- javacParams.setSources(ExtDirTestClass2Src);
- ToolBox.javac(javacParams);
+ tb.new JavacTask()
+ .outdir(".")
+ .sources(ExtDirTestClass2Src)
+ .run();
- ToolBox.writeFile(Paths.get("pkg2", "MANIFEST.MF"), jar2Manifest);
- jarGenerator.run(new String[] {"cfm", "pkg2.jar", "pkg2/MANIFEST.MF",
- "pkg2/ExtDirTestClass2.class"});
-
- ToolBox.copyFile(Paths.get("ext1", "pkg1.jar"), Paths.get("pkg1.jar"));
- ToolBox.copyFile(Paths.get("ext2", "pkg2.jar"), Paths.get("pkg2.jar"));
- ToolBox.copyFile(Paths.get("ext3", "pkg1.jar"), Paths.get("pkg1.jar"));
- ToolBox.copyFile(Paths.get("ext3", "pkg2.jar"), Paths.get("pkg2.jar"));
+ tb.new JarTask("pkg2.jar")
+ .manifest(jar2Manifest)
+ .files("pkg2/ExtDirTestClass2.class")
+ .run();
- Files.delete(Paths.get("pkg1.jar"));
- Files.delete(Paths.get("pkg2.jar"));
+ tb.createDirectories("ext1", "ext2", "ext3");
+ tb.copyFile("pkg1.jar", "ext1");
+ tb.copyFile("pkg2.jar", "ext2");
+ tb.copyFile("pkg1.jar", "ext3");
+ tb.copyFile("pkg2.jar", "ext3");
- Files.delete(Paths.get("pkg1", "ExtDirTestClass1.class"));
- Files.delete(Paths.get("pkg1", "MANIFEST.MF"));
- Files.delete(Paths.get("pkg1"));
- Files.delete(Paths.get("pkg2", "ExtDirTestClass2.class"));
- Files.delete(Paths.get("pkg2", "MANIFEST.MF"));
- Files.delete(Paths.get("pkg2"));
+ tb.deleteFiles(
+ "pkg1.jar",
+ "pkg2.jar",
+ "pkg1/ExtDirTestClass1.class",
+ "pkg1",
+ "pkg2/ExtDirTestClass2.class",
+ "pkg2"
+ );
}
void compileWithExtDirs() throws Exception {
-
-//javac -extdirs ext1 ExtDirTest_1.java
- ToolBox.JavaToolArgs params =
- new ToolBox.JavaToolArgs()
- .setOptions("-d", ".", "-extdirs", "ext1")
- .setSources(ExtDirTest_1Src);
- ToolBox.javac(params);
+ tb.new JavacTask()
+ .outdir(".")
+ .options("-extdirs", "ext1")
+ .sources(ExtDirTest_1Src)
+ .run()
+ .writeAll();
-//javac -extdirs ext1:ext2 ExtDirTest_2.java
- params.setOptions("-d", ".", "-extdirs", "ext1" + File.pathSeparator + "ext2")
- .setSources(ExtDirTest_2Src);
- ToolBox.javac(params);
+ tb.new JavacTask()
+ .outdir(".")
+ .options("-extdirs", "ext1" + File.pathSeparator + "ext2")
+ .sources(ExtDirTest_2Src)
+ .run();
-//javac -extdirs ext3 ExtDirTest_3.java
- params.setOptions("-d", ".", "-extdirs", "ext3")
- .setSources(ExtDirTest_3Src);
- ToolBox.javac(params);
+ tb.new JavacTask()
+ .outdir(".")
+ .options("-extdirs", "ext3")
+ .sources(ExtDirTest_3Src)
+ .run();
}
}
--- a/langtools/test/tools/javac/IncorrectInheritance/IncorrectInheritanceTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/IncorrectInheritance/IncorrectInheritanceTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 8034924
* @summary Incorrect inheritance of inaccessible static method
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main IncorrectInheritanceTest
*/
@@ -59,10 +59,11 @@
}
public void test() throws Exception {
- ToolBox.JavaToolArgs javacParams =
- new ToolBox.JavaToolArgs()
- .setSources(ASrc, BSrc, CSrc);
- ToolBox.javac(javacParams);
+ ToolBox tb = new ToolBox();
+
+ tb.new JavacTask()
+ .sources(ASrc, BSrc, CSrc)
+ .run();
}
}
--- a/langtools/test/tools/javac/MissingInclude/MissingIncludeTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/MissingInclude/MissingIncludeTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,25 +26,26 @@
* @bug 4509051 4785453
* @summary javac <AT>sourcefiles should catch Exception, when sourcefiles
* doesn't exist.
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main MissingIncludeTest
*/
-//original test: test/tools/javac/MissingInclude.sh
+// Original test: test/tools/javac/MissingInclude.sh
public class MissingIncludeTest {
- private static final String MissingIncludeSrc =
- "class MissingInclude {}";
+ private static final String MissingIncludeFile = "MissingInclude.java";
+ private static final String MissingIncludeSrc = "class MissingInclude {}";
public static void main(String[] args) throws Exception {
- ToolBox.createJavaFileFromSource(MissingIncludeSrc);
+ ToolBox tb = new ToolBox();
+
+ tb.writeFile(MissingIncludeFile, MissingIncludeSrc);
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} @/nonexistent_file MissingInclude.java 2> ${TMP1}
- ToolBox.JavaToolArgs params =
- new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
- .setAllArgs("@/nonexistent_file", "MissingInclude.java");
- ToolBox.javac(params);
+ tb.new JavacTask(ToolBox.Mode.CMDLINE)
+ .options("@/nonexistent_file")
+ .files(MissingIncludeFile)
+ .run(ToolBox.Expect.FAIL);
}
}
--- a/langtools/test/tools/javac/Paths/AbsolutePathTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/Paths/AbsolutePathTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -23,36 +23,49 @@
/*
* @test
+ * @ignore 8055500 [javac] fix for 8030046 is incorrect
* @bug 8030046
* @summary javac incorrectly handles absolute paths in manifest classpath
* @author govereau
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main AbsolutePathTest
*/
import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
public class AbsolutePathTest {
public static void main(String... cmdline) throws Exception {
+ ToolBox tb = new ToolBox();
+
// compile test.Test
- ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs();
- args.appendArgs("-d", "."); // this is needed to get the classfiles in test
- ToolBox.javac(args.setSources("package test; public class Test{}"));
+ tb.new JavacTask()
+ .outdir(".") // this is needed to get the classfiles in test
+ .sources("package test; public class Test{}")
+ .run();
// build test.jar containing test.Test
// we need the jars in a directory different from the working
- // directory to trigger the bug. I will reuse test/
- ToolBox.jar("cf", "test/test.jar", "test/Test.class");
+ // directory to trigger the bug.
+ Files.createDirectory(Paths.get("jars"));
+ tb.new JarTask("jars/test.jar")
+ .files("test/Test.class")
+ .run();
- // build second jar in test directory using
+ // build second jar in jars directory using
// an absolute path reference to the first jar
- String path = new File("test/test.jar").getAbsolutePath();
- ToolBox.mkManifestWithClassPath(null, path);
- ToolBox.jar("cfm", "test/test2.jar", "MANIFEST.MF");
+ tb.new JarTask("jars/test2.jar")
+ .classpath(new File("jars/test.jar").getAbsolutePath())
+ .run();
// this should not fail
- args.appendArgs("-cp", ".");
- ToolBox.javac(args.setSources("import test.Test; class Test2 {}"));
+ tb.new JavacTask()
+ .outdir(".")
+ .classpath("jars/test2.jar")
+ .sources("import test.Test; class Test2 {}")
+ .run()
+ .writeAll();
}
}
--- a/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClassesTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClassesTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,13 @@
* @test
* @bug 4087314 4800342 4307565
* @summary Verify allowed access to protected class from another package
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main ProtectedInnerClassesTest
*/
-//original tests: test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh
-//and test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java
+// Original tests: test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh
+// and test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java
public class ProtectedInnerClassesTest {
private static final String protectedInnerClass1Src =
@@ -74,45 +74,36 @@
new ProtectedInnerClassesTest().run();
}
+ ToolBox tb = new ToolBox();
+
void run() throws Exception {
compileAndExecute();
compileOnly();
}
void compileAndExecute() throws Exception {
-//"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d "${TESTCLASSES}" "${TESTSRC}${FS}p1${FS}ProtectedInnerClass1.java" "${TESTSRC}${FS}p2${FS}ProtectedInnerClass2.java"
- ToolBox.JavaToolArgs javacParams =
- new ToolBox.JavaToolArgs()
- .setOptions("-d", ".")
- .setSources(protectedInnerClass1Src, protectedInnerClass2Src);
-
- ToolBox.javac(javacParams);
+ tb.new JavacTask()
+ .outdir(".")
+ .sources(protectedInnerClass1Src, protectedInnerClass2Src)
+ .run();
-//"${TESTJAVA}${FS}bin${FS}java" ${TESTVMOPTS} -classpath "${CLASSPATH}${PS}${TESTCLASSES}" p2.ProtectedInnerClass2
- ToolBox.AnyToolArgs javaParams =
- new ToolBox.AnyToolArgs()
- .appendArgs(ToolBox.javaBinary)
- .appendArgs(ToolBox.testVMOpts)
- .appendArgs("-classpath", System.getProperty("user.dir"),
- "p2.ProtectedInnerClass2");
- ToolBox.executeCommand(javaParams);
+ tb.new JavaTask()
+ .classpath(System.getProperty("user.dir"))
+ .className("p2.ProtectedInnerClass2")
+ .run();
}
//from test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java
void compileOnly() throws Exception {
-//@run compile p1/ProtectedInnerClass1.java
- ToolBox.JavaToolArgs javacParams =
- new ToolBox.JavaToolArgs()
- .appendArgs("-d", ".")
- .setSources(protectedInnerClass1Src);
+ tb.new JavacTask()
+ .outdir(".")
+ .sources(protectedInnerClass1Src)
+ .run();
- ToolBox.javac(javacParams);
-
-//@run compile/fail p2/ProtectedInnerClass3.java
- javacParams = new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
- .appendArgs("-d", ".")
- .setSources(protectedInnerClass3Src);
- ToolBox.javac(javacParams);
+ tb.new JavacTask()
+ .outdir(".")
+ .sources(protectedInnerClass3Src)
+ .run(ToolBox.Expect.FAIL);
}
}
--- a/langtools/test/tools/javac/T5090006/AssertionFailureTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T5090006/AssertionFailureTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @bug 5090006
* @summary javac fails with assertion error
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main AssertionFailureTest
*/
@@ -33,7 +33,7 @@
import java.io.File;
import java.nio.file.Paths;
-//original test: test/tools/javac/T5090006/compiler.sh
+// Original test: test/tools/javac/T5090006/compiler.sh
public class AssertionFailureTest {
private static final String testSrc =
@@ -54,16 +54,14 @@
"}";
public static void main(String args[]) throws Exception {
- String classpath = Paths.get(System.getProperty("test.src"), "broken.jar")
- .toString();
- classpath = new StringBuilder(classpath)
- .append(File.pathSeparator).append(".").toString();
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -verbose -d "${TESTCLASSES}" -cp "${TESTSRC}${FS}broken.jar" "${TESTSRC}${FS}$1"
- ToolBox.JavaToolArgs params =
- new ToolBox.JavaToolArgs()
- .setOptions("-cp", classpath)
- .setSources(testSrc);
- ToolBox.javac(params);
+ ToolBox tb = new ToolBox();
+ String classpath = Paths.get(tb.testSrc, "broken.jar")
+ + File.pathSeparator
+ + ".";
+ tb.new JavacTask()
+ .classpath(classpath)
+ .sources(testSrc)
+ .run();
}
}
--- a/langtools/test/tools/javac/T6970173/DebugPointerAtBadPositionTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T6970173/DebugPointerAtBadPositionTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @bug 6970173
* @summary Debug pointer at bad position
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main DebugPointerAtBadPositionTest
*/
@@ -75,9 +75,10 @@
}
void compileTestClass() throws Exception {
- ToolBox.JavaToolArgs javacSuccessArgs =
- new ToolBox.JavaToolArgs().setSources(testSource);
- ToolBox.javac(javacSuccessArgs);
+ ToolBox tb = new ToolBox();
+ tb.new JavacTask()
+ .sources(testSource)
+ .run();
}
void checkClassFile(final File cfile, String methodToFind) throws Exception {
--- a/langtools/test/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @bug 7008643
* @summary inlined finally clauses confuse debuggers
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main InlinedFinallyConfuseDebuggersTest
*/
@@ -73,6 +73,8 @@
new InlinedFinallyConfuseDebuggersTest().run();
}
+ ToolBox tb = new ToolBox();
+
void run() throws Exception {
compileTestClass();
checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
@@ -80,9 +82,9 @@
}
void compileTestClass() throws Exception {
- ToolBox.JavaToolArgs javacSuccessArgs =
- new ToolBox.JavaToolArgs().setSources(testSource);
- ToolBox.javac(javacSuccessArgs);
+ tb.new JavacTask()
+ .sources(testSource)
+ .run();
}
void checkClassFile(final File cfile, String methodToFind) throws Exception {
--- a/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,14 +27,13 @@
* @test
* @bug 8009640
* @summary -profile <compact> does not work when -bootclasspath specified
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main CheckRejectProfileBCPOptionsIfUsedTogetherTest
*/
import com.sun.tools.javac.util.Assert;
-import java.util.ArrayList;
-import java.util.List;
+import java.nio.file.Paths;
public class CheckRejectProfileBCPOptionsIfUsedTogetherTest {
@@ -44,21 +43,16 @@
"}";
public static void main(String args[]) throws Exception {
- List<String> errOutput = new ArrayList<>();
- String testJDK = ToolBox.jdkUnderTest;
- ToolBox.createJavaFileFromSource(TestSrc);
+ ToolBox tb = new ToolBox();
- ToolBox.AnyToolArgs javacParams =
- new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
- .appendArgs(ToolBox.javacBinary)
- .appendArgs(ToolBox.testToolVMOpts)
- .appendArgs("-profile", "compact1", "-bootclasspath",
- testJDK + "/jre/lib/rt.jar", "Test.java")
- .setErrOutput(errOutput);
+ ToolBox.Result result = tb.new JavacTask(ToolBox.Mode.CMDLINE)
+ .options("-profile", "compact1",
+ "-bootclasspath", Paths.get(ToolBox.testJDK, "jre/lib/rt.jar").toString())
+ .sources(TestSrc)
+ .run(ToolBox.Expect.FAIL);
- ToolBox.executeCommand(javacParams);
-
- Assert.check(errOutput.get(0).startsWith(
+ String out = result.getOutput(ToolBox.OutputKind.DIRECT);
+ Assert.check(out.startsWith(
"javac: profile and bootclasspath options cannot be used together"),
"Incorrect javac error output");
}
--- a/langtools/test/tools/javac/T8010659/CompilerCrashWhenMixingBinariesAndSourcesTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8010659/CompilerCrashWhenMixingBinariesAndSourcesTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @test
* @bug 8010659
* @summary Javac Crashes while building OpenJFX
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main CompilerCrashWhenMixingBinariesAndSourcesTest
*/
@@ -48,19 +48,18 @@
" Object m(int i) {return null;}\n" +
"}";
- public static void main (String[] args) throws Exception{
- ToolBox.JavaToolArgs javacParams = new ToolBox.JavaToolArgs()
- .setSources(ASource, BSource, CSource, DSource);
- ToolBox.javac(javacParams);
+ public static void main(String[] args) throws Exception {
+ ToolBox tb = new ToolBox();
+
+ tb.new JavacTask()
+ .sources(ASource, BSource, CSource, DSource)
+ .run();
- ToolBox.rm("A.class");
- ToolBox.rm("A$1.class");
- ToolBox.rm("C.class");
- ToolBox.rm("D.class");
+ tb.deleteFiles("A.class", "A$1.class", "C.class", "D.class");
- javacParams = new ToolBox.JavaToolArgs()
- .setOptions("-cp", ".")
- .setSources(ASource, CSource, DSource);
- ToolBox.javac(javacParams);
+ tb.new JavacTask()
+ .classpath(".")
+ .sources(ASource, CSource, DSource)
+ .run();
}
}
--- a/langtools/test/tools/javac/T8013394/CompileErrorWithIteratorTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8013394/CompileErrorWithIteratorTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @test
* @bug 8013394
* @summary compile of iterator use fails with error "defined in an inaccessible class or interface"
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main CompileErrorWithIteratorTest
*/
@@ -71,15 +71,16 @@
new CompileErrorWithIteratorTest().run();
}
+ ToolBox tb = new ToolBox();
+
void run() throws Exception {
compile();
}
void compile() throws Exception {
- ToolBox.JavaToolArgs javacParams =
- new ToolBox.JavaToolArgs()
- .setSources(TestCollectionSrc, TestSrc);
- ToolBox.javac(javacParams);
+ tb.new JavacTask()
+ .sources(TestCollectionSrc, TestSrc)
+ .run();
}
}
--- a/langtools/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @test
* @bug 8019486 8026861 8027142
* @summary javac, generates erroneous LVT for a test case with lambda code
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main WrongLNTForLambdaTest
*/
@@ -125,6 +125,8 @@
new WrongLNTForLambdaTest().run();
}
+ ToolBox tb = new ToolBox();
+
void run() throws Exception {
compileTestClass();
checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
@@ -146,9 +148,9 @@
}
void compileTestClass() throws Exception {
- ToolBox.JavaToolArgs javacSuccessArgs =
- new ToolBox.JavaToolArgs().setSources(testSource);
- ToolBox.javac(javacSuccessArgs);
+ tb.new JavacTask()
+ .sources(testSource)
+ .run();
}
void checkClassFile(final File cfile, String methodToFind, int[][] expectedLNT) throws Exception {
--- a/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,11 @@
* @test
* @bug 8022162
* @summary Incorrect signature determination for certain inner class generics
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main IncorrectSignatureDeterminationForInnerClassesTest
*/
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
public class IncorrectSignatureDeterminationForInnerClassesTest {
private static final String DSrc =
@@ -69,21 +66,20 @@
}
void compile() throws Exception {
- Files.createDirectory(Paths.get("classes"));
+ ToolBox tb = new ToolBox();
+ tb.createDirectories("classes");
- ToolBox.JavaToolArgs javacParams =
- new ToolBox.JavaToolArgs()
- .appendArgs("-d", "classes")
- .setSources(DSrc);
-
- ToolBox.javac(javacParams);
+ tb.new JavacTask()
+ .outdir("classes")
+ .sources(DSrc)
+ .run();
// compile class H against the class files for classes D and Q
- javacParams =
- new ToolBox.JavaToolArgs()
- .appendArgs("-d", "classes", "-cp", "classes")
- .setSources(HSrc);
- ToolBox.javac(javacParams);
+ tb.new JavacTask()
+ .outdir("classes")
+ .classpath("classes")
+ .sources(HSrc)
+ .run();
}
}
--- a/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @test
* @bug 8024039
* @summary javac, previous solution for JDK-8022186 was incorrect
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main NoDeadCodeGenerationOnTrySmtTest
*/
@@ -76,6 +76,8 @@
static final String[] methodsToLookFor = {"m1", "m2"};
+ ToolBox tb = new ToolBox();
+
public static void main(String[] args) throws Exception {
new NoDeadCodeGenerationOnTrySmtTest().run();
}
@@ -87,9 +89,9 @@
}
void compileTestClass() throws Exception {
- ToolBox.JavaToolArgs javacSuccessArgs =
- new ToolBox.JavaToolArgs().setSources(testSource);
- ToolBox.javac(javacSuccessArgs);
+ tb.new JavacTask()
+ .sources(testSource)
+ .run();
}
void checkClassFile(final File cfile, String[] methodsToFind) throws Exception {
--- a/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @test
* @bug 8024437
* @summary Inferring the exception thrown by a lambda: sometimes fails to compile
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main ExceptionInferenceFromClassFileTest
*/
@@ -56,19 +56,19 @@
"}";
public static void main(String[] args) throws Exception {
- Files.createDirectory(Paths.get("out"));
+ ToolBox tb = new ToolBox();
+ tb.createDirectories("out");
- ToolBox.JavaToolArgs compileABParams =
- new ToolBox.JavaToolArgs()
- .setOptions("-d", "out")
- .setSources(ABSrc);
- ToolBox.javac(compileABParams);
+ tb.new JavacTask()
+ .outdir("out")
+ .sources(ABSrc)
+ .run();
- ToolBox.JavaToolArgs compileCParams =
- new ToolBox.JavaToolArgs()
- .setOptions("-d", "out", "-cp", "out")
- .setSources(CSrc);
- ToolBox.javac(compileCParams);
+ tb.new JavacTask()
+ .outdir("out")
+ .classpath("out")
+ .sources(CSrc)
+ .run();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/InvalidPackageAnno.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8054964
+ * @summary Invalid package annotations
+ * @author sogoel
+ *
+ * @compile/fail/ref=InvalidPackageAnno.out -XDrawDiagnostics bar/package-info.java
+ */
+
+package bar;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/InvalidPackageAnno.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+package-info.java:24:1: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/annotations/neg/NoAnnotationMethods.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/NoAnnotationMethods.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6393539
* @summary no compile-time error for clone, etc. in annotation type
* @author Peter von der Ah\u00e9
- * @compile/fail NoAnnotationMethods.java
+ * @compile/fail/ref=NoAnnotationMethods.out -XDrawDiagnostics NoAnnotationMethods.java
*/
public @interface NoAnnotationMethods {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoAnnotationMethods.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+NoAnnotationMethods.java:10:9: compiler.err.intf.annotation.member.clash: annotationType(), java.lang.annotation.Annotation
+1 error
--- a/langtools/test/tools/javac/annotations/neg/NoClone.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/NoClone.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6393539
* @summary no compile-time error for clone, etc. in annotation type
* @author Peter von der Ah\u00e9
- * @compile/fail NoClone.java
+ * @compile/fail/ref=NoClone.out -XDrawDiagnostics NoClone.java
*/
public @interface NoClone {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoClone.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,3 @@
+NoClone.java:10:5: compiler.err.invalid.annotation.member.type
+NoClone.java:10:12: compiler.err.intf.annotation.member.clash: clone(), java.lang.Object
+2 errors
--- a/langtools/test/tools/javac/annotations/neg/NoObjectMethods.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/NoObjectMethods.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6393539
* @summary no compile-time error for clone, etc. in annotation type
* @author Peter von der Ah\u00e9
- * @compile/fail NoObjectMethods.java
+ * @compile/fail/ref=NoObjectMethods.out -XDrawDiagnostics NoObjectMethods.java
*/
public @interface NoObjectMethods {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoObjectMethods.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+NoObjectMethods.java:10:9: compiler.err.intf.annotation.member.clash: clone(), java.lang.Object
+1 error
--- a/langtools/test/tools/javac/annotations/neg/ObjectMembers.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/ObjectMembers.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4901264
* @summary JSR175 (2): don't allow annotating members from Object
* @author gafter
*
- * @compile/fail ObjectMembers.java
+ * @compile/fail/ref=ObjectMembers.out -XDrawDiagnostics ObjectMembers.java
*/
@ObjectMembers(hashCode = 23)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/ObjectMembers.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+ObjectMembers.java:10:16: compiler.err.no.annotation.member: hashCode, ObjectMembers
+1 error
--- a/langtools/test/tools/javac/annotations/neg/OverrideNo.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/OverrideNo.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4901275 4989669
* @summary JSR175 (7): implement <at>Overrides
* @author gafter
*
- * @compile/fail OverrideNo.java
+ * @compile/fail/ref=OverrideNo.out -XDrawDiagnostics OverrideNo.java
*/
package overrideNo;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/OverrideNo.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+OverrideNo.java:16:5: compiler.err.method.does.not.override.superclass
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Package.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Package.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4901290
* @summary Package annotations
* @author gafter
*
- * @compile/fail Package.java
+ * @compile/fail/ref=Package.out -XDrawDiagnostics Package.java
*/
@java.lang.annotation.Documented
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Package.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Package.java:10:1: compiler.err.pkg.annotations.sb.in.package-info.java
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Recovery.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Recovery.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4993451
* @summary compiler crash with malformed annotations
* @author gafter
*
- * @compile/fail Recovery.java
+ * @compile/fail/ref=Recovery.out -XDrawDiagnostics Recovery.java
*/
import java.lang.annotation.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Recovery.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Recovery.java:12:2: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.annotation.RetentionPolicy, java.lang.annotation.Annotation)
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Recovery1.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Recovery1.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4963450
* @summary Assertion error is thrown when an annotation class cannot be found.
* @author gafter
*
- * @compile/fail Recovery1.java
+ * @compile/fail/ref=Recovery1.out -XDrawDiagnostics Recovery1.java
*/
package recovery1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Recovery1.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,4 @@
+Recovery1.java:14:5: compiler.err.cant.resolve.location: kindname.class, Marker, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
+Recovery1.java:14:30: compiler.err.cant.resolve.location: kindname.class, Marker, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
+Recovery1.java:18:43: compiler.err.cant.resolve.location.args: kindname.method, markerToo, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
+3 errors
--- a/langtools/test/tools/javac/annotations/neg/Scope.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Scope.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4901280
* @summary name lookup scope for annotations
* @author gafter
*
- * @compile/fail Scope.java
+ * @compile/fail/ref=Scope.out -XDrawDiagnostics Scope.java
*/
package annotation.scope;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Scope.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Scope.java:12:4: compiler.err.cant.resolve: kindname.variable, red, ,
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Syntax1.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Syntax1.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4974524
* @summary compiler crash with ill-formed annotation
* @author gafter
*
- * @compile/fail Syntax1.java
+ * @compile/fail/ref=Syntax1.out -XDrawDiagnostics Syntax1.java
*/
package syntax1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Syntax1.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,4 @@
+Syntax1.java:17:20: compiler.err.annotation.value.must.be.name.value
+Syntax1.java:17:40: compiler.err.annotation.value.must.be.name.value
+Syntax1.java:17:1: compiler.err.annotation.missing.default.value: java.lang.annotation.Target, value
+3 errors
--- a/langtools/test/tools/javac/annotations/neg/WrongTarget.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/WrongTarget.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,35 +1,14 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4901271
* @summary java.lang.annotation.Target
* @author gafter
*
- * @compile/fail WrongTarget.java
+ * @compile/fail/ref=WrongTarget.out -XDrawDiagnostics WrongTarget.java
*/
+import static java.lang.annotation.ElementType.*;
+
@java.lang.annotation.Target({FIELD})
@interface foo {
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/WrongTarget.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+WrongTarget.java:16:1: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/annotations/neg/WrongTarget2.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/WrongTarget2.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4973504
* @summary Compiler allows Inherited meta-attribute on local variable declaration.
* @author gafter
*
- * @compile/fail WrongTarget2.java
+ * @compile/fail/ref=WrongTarget2.out -XDrawDiagnostics WrongTarget2.java
*/
import java.lang.annotation.Inherited;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/WrongTarget2.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+WrongTarget2.java:12:6: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/annotations/neg/WrongValue.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/WrongValue.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4951298
* @summary compiler: crashes when attributes with same elements are used in place of other
* @author gafter
*
- * @compile/fail WrongValue.java
+ * @compile/fail/ref=WrongValue.out -XDrawDiagnostics WrongValue.java
*/
@interface TestM2 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/WrongValue.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+WrongValue.java:25:5: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TestM3, TestM2)
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z1.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z1.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z1.java
+ * @compile/fail/ref=Z1.out -XDrawDiagnostics Z1.java
*/
enum Color { red, green, blue }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z1.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z1.java:16:10: compiler.err.cant.resolve: kindname.variable, teal, ,
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z10.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z10.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,12 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z10.java
+ * @compile/fail/ref=Z10.out -XDrawDiagnostics Z10.java
*/
-enum Color { red, green, blue }
-
@interface An {
int[][] a();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z10.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z10.java:11:8: compiler.err.invalid.annotation.member.type
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z11.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z11.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,12 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z11.java
+ * @compile/fail/ref=Z11.out -XDrawDiagnostics Z11.java
*/
-enum Color { red, green, blue }
-
class X {}
@interface An {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z11.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z11.java:13:5: compiler.err.invalid.annotation.member.type
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z12.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z12.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,12 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z12.java
+ * @compile/fail/ref=Z12.out -XDrawDiagnostics Z12.java
*/
-enum Color { red, green, blue }
-
@interface An {
void a();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z12.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z12.java:11:5: compiler.err.invalid.annotation.member.type
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z13.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z13.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z13.java
+ * @compile/fail/ref=Z13.out -XDrawDiagnostics Z13.java
*/
@interface An {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z13.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z13.java:11:20: compiler.err.throws.not.allowed.in.intf.annotation
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z14.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z14.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z14.java
+ * @compile/fail/ref=Z14.out -XDrawDiagnostics Z14.java
*/
@interface An<T> {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z14.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z14.java:10:15: compiler.err.intf.annotation.cant.have.type.params
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z15.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z15.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z15.java
+ * @compile/fail/ref=Z15.out -XDrawDiagnostics Z15.java
*/
@interface An {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z15.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z15.java:11:36: compiler.err.attribute.value.must.be.constant
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z16.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z16.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z16.java
+ * @compile/fail/ref=Z16.out -XDrawDiagnostics Z16.java
*/
enum Color { red, green, blue }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z16.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z16.java:13:27: compiler.err.cant.resolve.location: kindname.variable, redx, , , (compiler.misc.location: kindname.annotation, Colored, null)
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z2.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z2.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,14 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z2.java
+ * @compile/fail/ref=Z2.out -XDrawDiagnostics Z2.java
*/
enum Color { red, green, blue }
interface Colored {
- Color value() default red;
+ Color value() default Color.red;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z2.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z2.java:13:11: compiler.err.default.allowed.in.intf.annotation.member
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z3.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z3.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,14 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 4865660
+ * @test /nodynamiccopyright/
+ * @bug 4865660 8054556
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z3.java
+ * @compile/fail/ref=Z3.out -XDrawDiagnostics Z3.java
*/
enum Color { red, green, blue }
class Colored {
- Color value() default red;
+ Color value() default Color.red;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z3.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z3.java:13:11: compiler.err.default.allowed.in.intf.annotation.member
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z4.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z4.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,14 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z4.java
+ * @compile/fail/ref=Z4.out -XDrawDiagnostics Z4.java
*/
enum Color { red, green, blue }
@interface Colored {
- Color value() default teal;
+ Color value() default Color.teal;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z4.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z4.java:13:32: compiler.err.cant.resolve.location: kindname.variable, teal, , , (compiler.misc.location: kindname.class, Color, null)
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z5.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z5.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z5.java
+ * @compile/fail/ref=Z5.out -XDrawDiagnostics Z5.java
*/
interface Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z5.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z5.java:12:28: compiler.err.cant.extend.intf.annotation
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z8.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z8.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z8.java
+ * @compile/fail/ref=Z8.out -XDrawDiagnostics Z8.java
*/
@interface An {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z8.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z8.java:11:15: compiler.err.intf.annotation.members.cant.have.params
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z9.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z9.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter
*
- * @compile/fail Z9.java
+ * @compile/fail/ref=Z9.out -XDrawDiagnostics Z9.java
*/
@interface An {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z9.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z9.java:11:6: compiler.err.intf.annotation.members.cant.have.type.params
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/bar/package-info.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+@java.lang.annotation.Documented
+package bar;
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,30 +1,7 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
+ * @test /nodynamiccopyright/
* @summary Smoke test for repeating annotations
- * @compile/fail RepeatingAndContainerPresent.java
+ * @compile/fail/ref=RepeatingAndContainerPresent.out -XDrawDiagnostics RepeatingAndContainerPresent.java
* @bug 7151010
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+RepeatingAndContainerPresent.java:20:1: compiler.err.invalid.repeatable.annotation.repeated.and.container.present: Foos
+1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,30 +1,7 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
+ * @test /nodynamiccopyright/
* @summary Smoke test for repeating annotations
- * @compile/fail UseWrongRepeatable.java
+ * @compile/fail/ref=UseWrongRepeatable.out -XDrawDiagnostics UseWrongRepeatable.java
* @bug 7151010
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,4 @@
+UseWrongRepeatable.java:17:1: compiler.err.invalid.repeatable.annotation.value.return: java.lang.annotation.Target, java.lang.annotation.ElementType[], UseWrongRepeatable[]
+UseWrongRepeatable.java:17:21: compiler.err.invalid.repeatable.annotation.value.return: java.lang.annotation.Target, java.lang.annotation.ElementType[], UseWrongRepeatable[]
+UseWrongRepeatable.java:14:1: compiler.err.invalid.repeatable.annotation.value.return: java.lang.annotation.Target, java.lang.annotation.ElementType[], UseWrongRepeatable[]
+3 errors
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,35 +1,12 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
+ * @test /nodynamiccopyright/
+ * @bug 6843077 8006775
+ * @summary test type annotation on void generic methods
+ * @author Mahmood Ali
+ * @compile/fail/ref=VoidGenericMethod.out -XDrawDiagnostics VoidGenericMethod.java
*/
import java.lang.annotation.*;
-
-/*
- * @test
- * @bug 6843077 8006775
- * @summary test type annotation on void generic methods
- * @author Mahmood Ali
- * @compile/fail VoidGenericMethod.java
- */
class VoidGenericMethod {
public @A <T> void method() { }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.out Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+VoidGenericMethod.java:11:10: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/api/ToolProvider/HelloWorldTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/api/ToolProvider/HelloWorldTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,21 +25,19 @@
* @test
* @bug 6604599
* @summary ToolProvider should be less compiler-specific
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main HelloWorldTest
*/
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
// verify that running a simple program, such as this one, does not trigger
// the loading of ToolProvider or any com.sun.tools.javac class
public class HelloWorldTest {
public static void main(String... args) throws Exception {
if (args.length > 0) {
- System.err.println(Arrays.asList(args));
+ System.err.println(Arrays.toString(args));
return;
}
@@ -47,27 +45,26 @@
}
void run() throws Exception {
+ ToolBox tb = new ToolBox();
+
String classpath = System.getProperty("java.class.path");
- List<String> output = new ArrayList<>();
- ToolBox.AnyToolArgs javaParams =
- new ToolBox.AnyToolArgs()
- .appendArgs(ToolBox.javaBinary)
- .appendArgs(ToolBox.testVMOpts)
- .appendArgs(ToolBox.testJavaOpts)
- .appendArgs("-verbose:class",
- "-classpath", classpath,
- HelloWorldTest.class.getName(),
- "Hello", "World")
- .setErrOutput(output)
- .setStdOutput(output);
+ ToolBox.Result tr = tb.new JavaTask()
+ .vmOptions("-verbose:class")
+ .classpath(classpath)
+ .className(HelloWorldTest.class.getName())
+ .classArgs("Hello", "World")
+ .run();
- ToolBox.executeCommand(javaParams);
-
- for (String line : output) {
- System.err.println(line);
- if (line.contains("javax.tools.ToolProvider") || line.contains("com.sun.tools.javac."))
- error(">>> " + line);
+ if (tr.getOutput(ToolBox.OutputKind.STDOUT).contains("java.lang.Object")) {
+ for (String line : tr.getOutputLines(ToolBox.OutputKind.STDOUT)) {
+ System.err.println(line);
+ if (line.contains("javax.tools.ToolProvider") || line.contains("com.sun.tools.javac."))
+ error(">>> " + line);
+ }
+ } else {
+ tr.writeAll();
+ error("verbose output not as expected");
}
if (errors > 0)
--- a/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest1.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest1.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,11 @@
* @test
* @bug 6604599
* @summary ToolProvider should be less compiler-specific
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main ToolProviderTest1
*/
-import java.util.ArrayList;
import java.util.List;
// verify that running accessing ToolProvider by itself does not
@@ -46,24 +45,18 @@
}
void run() throws Exception {
+ ToolBox tb = new ToolBox();
String classpath = System.getProperty("java.class.path");
- List<String> output = new ArrayList<>();
- ToolBox.AnyToolArgs javaParams =
- new ToolBox.AnyToolArgs()
- .appendArgs(ToolBox.javaBinary)
- .appendArgs(ToolBox.testVMOpts)
- .appendArgs(ToolBox.testJavaOpts)
- .appendArgs("-verbose:class",
- "-classpath", classpath,
- ToolProviderTest1.class.getName(),
- "javax.tools.ToolProvider")
- .setErrOutput(output)
- .setStdOutput(output);
+ List<String> lines = tb.new JavaTask()
+ .vmOptions("-verbose:class")
+ .classpath(classpath)
+ .className(getClass().getName())
+ .classArgs("javax.tools.ToolProvider")
+ .run()
+ .getOutputLines(ToolBox.OutputKind.STDOUT);
- ToolBox.executeCommand(javaParams);
-
- for (String line : output) {
+ for (String line : lines) {
System.err.println(line);
if (line.contains("com.sun.tools.javac."))
error(">>> " + line);
--- a/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest2.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest2.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,12 @@
* @test
* @bug 6604599
* @summary ToolProvider should be less compiler-specific
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main ToolProviderTest2
*/
import javax.tools.ToolProvider;
-import java.util.ArrayList;
import java.util.List;
// control for ToolProviderTest1 -- verify that using ToolProvider to
@@ -47,25 +46,19 @@
}
void run() throws Exception {
+ ToolBox tb = new ToolBox();
String classpath = System.getProperty("java.class.path");
- List<String> output = new ArrayList<>();
- ToolBox.AnyToolArgs javaParams =
- new ToolBox.AnyToolArgs()
- .appendArgs(ToolBox.javaBinary)
- .appendArgs(ToolBox.testVMOpts)
- .appendArgs(ToolBox.testJavaOpts)
- .appendArgs( "-verbose:class",
- "-classpath", classpath,
- ToolProviderTest2.class.getName(),
- "javax.tools.ToolProvider")
- .setErrOutput(output)
- .setStdOutput(output);
-
- ToolBox.executeCommand(javaParams);
+ List<String> lines = tb.new JavaTask()
+ .vmOptions("-verbose:class")
+ .classpath(classpath)
+ .className(getClass().getName())
+ .classArgs("javax.tools.ToolProvider")
+ .run()
+ .getOutputLines(ToolBox.OutputKind.STDOUT);
boolean found = false;
- for (String line : output) {
+ for (String line : lines) {
System.err.println(line);
if (line.contains("com.sun.tools.javac."))
found = true;
--- a/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary local variable table attribute test.
* @bug 8040097
- * @library /tools/javac/lib ../lib
- * @build LocalVariableTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox LocalVariableTestBase TestBase InMemoryFileManager
* @compile -g LocalVariableTableTest.java
* @run main LocalVariableTableTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary local variable type table attribute test.
* @bug 8040097
- * @library /tools/javac/lib ../lib
- * @build LocalVariableTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox LocalVariableTestBase TestBase InMemoryFileManager
* @compile -g LocalVariableTypeTableTest.java
* @run main LocalVariableTypeTableTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/AnonymousClassTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/AnonymousClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary sourcefile attribute test for anonymous class.
* @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
* @run main AnonymousClassTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/InnerClassTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/InnerClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary sourcefile attribute test for inner class.
* @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
* @run main InnerClassTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/LocalClassTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/LocalClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary sourcefile attribute test for local class.
* @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
* @run main LocalClassTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/MixTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/MixTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary sourcefile attribute test for complex structure of nested classes and other types.
* @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
* @run main MixTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary sourcefile attribute test for file compiled without debug information.
* @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
* @compile -g:none NoSourceFileAttribute.java
* @run main NoSourceFileAttribute
*/
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary sourcefile attribute test for synthetic class.
* @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
* @run main SyntheticClassTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/TopLevelClassesOneFileTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/TopLevelClassesOneFileTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @summary sourcefile attribute test for two type in one file.
* @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
* @run main TopLevelClassesOneFileTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
* @test
* @bug 8042261
* @summary Checking that deprecated attribute does not apply to classes of deprecated package.
- * @library /tools/javac/lib ../lib
- * @build DeprecatedPackageTest TestBase TestResult InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox TestBase TestResult InMemoryFileManager
* @run main DeprecatedPackageTest
*/
--- a/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -26,8 +26,8 @@
* @bug 8042261
* @summary Checking what attribute is generated by annotation Deprecated
* or javadoc deprecated for field, method, class(inner/local), interface.
- * @library /tools/javac/lib ../lib
- * @build DeprecatedTest TestBase TestResult InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox TestBase TestResult InMemoryFileManager
* @run main DeprecatedTest
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerAnnotationTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner annotations in inner annotation.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerAnnotationsInInnerAnnotationTest
+ */
+
+public class InnerAnnotationsInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerAnnotationsInInnerAnnotationTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setOuterClassType(ClassType.ANNOTATION);
+ setInnerClassType(ClassType.ANNOTATION);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner annotations in inner class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerAnnotationsInInnerClassTest
+ */
+
+public class InnerAnnotationsInInnerClassTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerAnnotationsInInnerClassTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setForbiddenWithoutStaticInOuterMods(true);
+ setOuterClassType(ClassType.CLASS);
+ setInnerClassType(ClassType.ANNOTATION);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerEnumTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner annotations in inner enum.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerAnnotationsInInnerEnumTest
+ */
+
+public class InnerAnnotationsInInnerEnumTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerAnnotationsInInnerEnumTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC, Modifier.ABSTRACT);
+ setOuterClassType(ClassType.ENUM);
+ setInnerClassType(ClassType.ANNOTATION);
+ setPrefix("Inner {;");
+ setSuffix("}");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerInterfaceTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner annotations in inner interface.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerAnnotationsInInnerInterfaceTest
+ */
+
+public class InnerAnnotationsInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerAnnotationsInInnerInterfaceTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setOuterClassType(ClassType.INTERFACE);
+ setInnerClassType(ClassType.ANNOTATION);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesHierarchyTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Test that inner classes have in its inner classes attribute enclosing classes and its immediate members.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesHierarchyTest
+ */
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.InnerClasses_attribute.Info;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class InnerClassesHierarchyTest extends TestResult {
+
+ private final Map<String, Set<String>> innerClasses;
+ private final String outerClassName;
+
+ public InnerClassesHierarchyTest() throws IOException, ConstantPoolException {
+ innerClasses = new HashMap<>();
+ outerClassName = InnerClassesHierarchyTest.class.getSimpleName();
+ File classDir = getClassDir();
+ FilenameFilter filter =
+ (dir, name) -> name.matches(outerClassName + ".*\\.class");
+ for (File file : Arrays.asList(classDir.listFiles(filter))) {
+ ClassFile classFile = readClassFile(file);
+ String className = classFile.getName();
+ for (ConstantPool.CPInfo info : classFile.constant_pool.entries()) {
+ if (info instanceof ConstantPool.CONSTANT_Class_info) {
+ ConstantPool.CONSTANT_Class_info classInfo =
+ (ConstantPool.CONSTANT_Class_info) info;
+ String cpClassName = classInfo.getBaseName();
+ if (isInnerClass(cpClassName)) {
+ get(className).add(cpClassName);
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isInnerClass(String cpClassName) {
+ return cpClassName.contains("$");
+ }
+
+ private Set<String> get(String className) {
+ if (!innerClasses.containsKey(className)) {
+ innerClasses.put(className, new HashSet<>());
+ }
+ return innerClasses.get(className);
+ }
+
+ public static void main(String[] args) throws IOException, ConstantPoolException, TestFailedException {
+ new InnerClassesHierarchyTest().test();
+ }
+
+ private void test() throws TestFailedException {
+ addTestCase("Source file is InnerClassesHierarchyTest.java");
+ try {
+ Queue<String> queue = new LinkedList<>();
+ Set<String> visitedClasses = new HashSet<>();
+ queue.add(outerClassName);
+ while (!queue.isEmpty()) {
+ String currentClassName = queue.poll();
+ if (!currentClassName.startsWith(outerClassName)) {
+ continue;
+ }
+ ClassFile cf = readClassFile(currentClassName);
+ InnerClasses_attribute attr = (InnerClasses_attribute)
+ cf.getAttribute(Attribute.InnerClasses);
+ assertNotNull(attr, "Class should not contain "
+ + "inner classes attribute : " + currentClassName);
+ assertTrue(innerClasses.containsKey(currentClassName),
+ "map contains class name : " + currentClassName);
+ Set<String> setClasses = innerClasses.get(currentClassName);
+ if (setClasses == null) {
+ continue;
+ }
+ assertEquals(attr.number_of_classes,
+ setClasses.size(),
+ "Check number of inner classes : " + setClasses);
+ for (Info info : attr.classes) {
+ String innerClassName = info
+ .getInnerClassInfo(cf.constant_pool).getBaseName();
+ assertTrue(setClasses.contains(innerClassName),
+ currentClassName + " contains inner class : "
+ + innerClassName);
+ if (visitedClasses.add(innerClassName)) {
+ queue.add(innerClassName);
+ }
+ }
+ }
+ Set<String> allClasses = innerClasses.entrySet().stream()
+ .flatMap(entry -> entry.getValue().stream())
+ .collect(Collectors.toSet());
+
+ Set<String> a_b = removeAll(visitedClasses, allClasses);
+ Set<String> b_a = removeAll(allClasses, visitedClasses);
+ assertEquals(visitedClasses, allClasses,
+ "All classes are found\n"
+ + "visited - all classes : " + a_b
+ + "\nall classes - visited : " + b_a);
+ } catch (Exception e) {
+ addFailure(e);
+ } finally {
+ checkStatus();
+ }
+ }
+
+ private Set<String> removeAll(Set<String> set1, Set<String> set2) {
+ Set<String> set = new HashSet<>(set1);
+ set.removeAll(set2);
+ return set;
+ }
+
+ public static class A1 {
+
+ public class B1 {
+ }
+
+ public enum B2 {
+ }
+
+ public interface B3 {
+ }
+
+ public @interface B4 {
+ }
+
+ public void f() {
+ new B1() {
+ };
+ new B3() {
+ };
+ new B4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ }
+
+ Runnable r = () -> {
+ new B1() {
+ };
+ new B3() {
+ };
+ new B4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ };
+ }
+
+ public enum A2 {;
+
+ public class B1 {
+ }
+
+ public enum B2 {
+ }
+
+ public interface B3 {
+ }
+
+ public @interface B4 {
+ }
+
+ public void a2() {
+ new B1() {
+ };
+ new B3() {
+ };
+ new B4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ }
+
+ Runnable r = () -> {
+ new B1() {
+ };
+ new B3() {
+ };
+ new B4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ };
+ }
+
+ public interface A3 {
+
+ public class B1 {
+ }
+
+ public enum B2 {
+ }
+
+ public interface B3 {
+ }
+
+ public @interface B4 {
+ }
+
+ default void a1() {
+ new B1() {
+ };
+ new B3() {
+ };
+ new B4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ }
+
+ static void a2() {
+ new B1() {
+ };
+ new B3() {
+ };
+ new B4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ }
+ }
+
+ public @interface A4 {
+
+ public class B1 {
+ }
+
+ public enum B2 {
+ }
+
+ public interface B3 {
+ }
+
+ public @interface B4 {
+ }
+ }
+
+ {
+ new A1() {
+ class B1 {
+ }
+
+ public void a2() {
+ new B1() {
+ };
+ class B5 {
+ }
+ }
+ };
+ new A3() {
+ class B1 {
+ }
+
+ public void a3() {
+ new B1() {
+ };
+ class B5 {
+ }
+ }
+ };
+ new A4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+
+ class B1 {
+ }
+
+ public void a4() {
+ new B1() {
+ };
+ class B5 {
+ }
+ }
+ };
+ Runnable r = () -> {
+ new A1() {
+ };
+ new A3() {
+ };
+ new A4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ };
+ }
+
+ static {
+ new A1() {
+ class B1 {
+ }
+
+ public void a2() {
+ new B1() {
+ };
+ class B5 {
+ }
+ }
+ };
+ new A3() {
+ class B1 {
+ }
+
+ public void a3() {
+ new B1() {
+ };
+ class B5 {
+ }
+ }
+ };
+ new A4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+
+ class B1 {
+ }
+
+ public void a4() {
+ new B1() {
+ };
+ class B5 {
+ }
+ }
+ };
+ Runnable r = () -> {
+ new A1() {
+ };
+ new A3() {
+ };
+ new A4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ };
+ }
+
+ public void a5() {
+ class A5 {
+
+ class B1 {
+ }
+
+ public void a5() {
+ new B1() {
+ };
+
+ class B5 {
+ }
+ }
+ }
+ Runnable r = () -> {
+ new A1() {
+ };
+ new A3() {
+ };
+ new A4() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+ class B5 {
+ }
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInAnonymousClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in anonymous class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInAnonymousClassTest
+ */
+
+import java.util.*;
+
+public class InnerClassesInAnonymousClassTest extends InnerClassesTestBase {
+
+ private ClassType currentClassType;
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerClassesInAnonymousClassTest();
+ test.test("InnerClassesSrc$1", "Anonymous", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerAccessModifiers(Modifier.EMPTY);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
+ setOuterClassType(ClassType.OTHER);
+ setInnerClassType(ClassType.CLASS);
+ setSuffix("};}");
+ }
+
+ @Override
+ public List<TestCase> generateTestCases() {
+ currentClassType = ClassType.CLASS;
+ setPrefix("class Anonymous {} {new Anonymous() {");
+ List<TestCase> sources = super.generateTestCases();
+
+ currentClassType = ClassType.INTERFACE;
+ setPrefix("interface Anonymous {} {new Anonymous() {");
+ sources.addAll(super.generateTestCases());
+
+ currentClassType = ClassType.ANNOTATION;
+ setPrefix("@interface Anonymous {} {new Anonymous() {@Override public "
+ + "Class<? extends java.lang.annotation.Annotation> "
+ + "annotationType() {return null;}");
+ sources.addAll(super.generateTestCases());
+ return sources;
+ }
+
+ @Override
+ public void getAdditionalFlags(Map<String, Set<String>> class2Flags, ClassType type, Modifier... flags) {
+ super.getAdditionalFlags(class2Flags, type, flags);
+ class2Flags.put("Anonymous", getFlags(currentClassType, Arrays.asList(flags)));
+ class2Flags.put("1", new HashSet<>());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerAnnotationTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in inner annotation.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInInnerAnnotationTest
+ */
+
+public class InnerClassesInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerClassesInInnerAnnotationTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+ setOuterClassType(ClassType.ANNOTATION);
+ setInnerClassType(ClassType.CLASS);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8034854 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in inner class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInInnerClassTest
+ */
+
+import java.util.List;
+
+public class InnerClassesInInnerClassTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerClassesInInnerClassTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setHasSyntheticClass(true);
+ setOuterClassType(ClassType.CLASS);
+ setInnerClassType(ClassType.CLASS);
+ }
+
+ @Override
+ public List<TestCase> generateTestCases() {
+ setForbiddenWithoutStaticInOuterMods(true);
+ List<TestCase> sources = super.generateTestCases();
+
+ setForbiddenWithoutStaticInOuterMods(false);
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
+ sources.addAll(super.generateTestCases());
+
+ return sources;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTestBase.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * Base class for tests that check inner classes in inner class.
+ *
+ * @author Andrei Eremeev
+ */
+public abstract class InnerClassesInInnerClassTestBase extends InnerClassesTestBase {
+
+ public InnerClassesInInnerClassTestBase() {
+ setPrefix("Inner {");
+ setSuffix("}");
+ }
+
+ @Override
+ public void getAdditionalFlags(
+ Map<String, Set<String>> class2Flags, ClassType type, Modifier...flags) {
+ super.getAdditionalFlags(class2Flags, type, flags);
+ class2Flags.put("Inner", getFlags(type, Arrays.asList(flags)));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8034854 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in inner enum.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInInnerEnumTest
+ */
+
+public class InnerClassesInInnerEnumTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerClassesInInnerEnumTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setOuterClassType(ClassType.ENUM);
+ setInnerClassType(ClassType.CLASS);
+ setHasSyntheticClass(true);
+ setPrefix("Inner {;");
+ setSuffix("}");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerInterfaceTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in inner interface.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInInnerInterfaceTest
+ */
+
+public class InnerClassesInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerClassesInInnerInterfaceTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT);
+ setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+ setOuterClassType(ClassType.INTERFACE);
+ setInnerClassType(ClassType.CLASS);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInLocalClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in local class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInLocalClassTest
+ */
+
+import java.util.*;
+
+public class InnerClassesInLocalClassTest extends InnerClassesTestBase {
+
+ private final static Modifier[] LOCAL_CLASS_MODIFIERS =
+ new Modifier[]{Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL};
+ private final static String CLASS_TEMPLATE =
+ "public %CLASS% OuterClass {\n" +
+ "%SOURCE%\n" +
+ "}";
+
+ private final List<Data> innerClassesData;
+
+ public InnerClassesInLocalClassTest() {
+ innerClassesData = new ArrayList<>();
+ for (Modifier outerModifier : LOCAL_CLASS_MODIFIERS) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(outerModifier.getString()).append(' ');
+ sb.append("class Local {");
+ Map<String, Set<String>> class2Flags = new HashMap<>();
+ for (int i = 0; i < LOCAL_CLASS_MODIFIERS.length; ++i) {
+ Modifier innerModifier = LOCAL_CLASS_MODIFIERS[i];
+ sb.append(innerModifier.getString()).append(' ')
+ .append("class").append(' ')
+ .append('A').append(i).append("{}\n");
+ class2Flags.put("A" + i, getFlags(innerModifier));
+ }
+ sb.append("};");
+ class2Flags.put("1Local", getFlags(outerModifier));
+ innerClassesData.add(new Data(sb.toString(), class2Flags));
+ }
+ }
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerClassesInLocalClassTest();
+ test.test("OuterClass$1Local", "1Local");
+ }
+
+ @Override
+ public void setProperties() {
+ }
+
+ @Override
+ public List<TestCase> generateTestCases() {
+ List<TestCase> testCases = new ArrayList<>();
+ testCases.addAll(localClassInClassMethod());
+ testCases.addAll(localClassInInterfaceMethod());
+ return testCases;
+ }
+
+ private List<TestCase> localClassInClassMethod() {
+ List<TestCase> list = new ArrayList<>();
+ String template = CLASS_TEMPLATE.replace("%CLASS%", "class");
+ list.addAll(lambda(template));
+ list.addAll(constructor(template));
+ list.addAll(method(template,
+ new Modifier[]{Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC},
+ new Modifier[]{Modifier.EMPTY, Modifier.FINAL, Modifier.STATIC}));
+ list.addAll(staticAndInstanceInitializer(template));
+ return list;
+ }
+
+ private List<TestCase> localClassInInterfaceMethod() {
+ String template = CLASS_TEMPLATE.replace("%CLASS%", "interface");
+ return method(template,
+ new Modifier[]{Modifier.EMPTY, Modifier.PUBLIC},
+ new Modifier[]{Modifier.DEFAULT, Modifier.STATIC});
+ }
+
+ private List<TestCase> generate(String template, String prefix, String suffix) {
+ List<TestCase> list = new ArrayList<>();
+ for (Data data : innerClassesData) {
+ list.add(new TestCase(template.replace("%SOURCE%",
+ prefix + data.sources + suffix),
+ data.class2Flags));
+ }
+ return list;
+ }
+
+ private List<TestCase> lambda(String template) {
+ return generate(template, "Runnable run = () -> {", "};");
+ }
+
+ private List<TestCase> constructor(String template) {
+ List<TestCase> list = new ArrayList<>();
+ for (Modifier modifier :
+ new Modifier[]{Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC}) {
+ list.addAll(generate(template, modifier.getString() + " OuterClass() {", "}"));
+ }
+ return list;
+ }
+
+ private List<TestCase> method(String template, Modifier[] mods, Modifier[] otherMods) {
+ List<TestCase> list = new ArrayList<>();
+ for (Modifier modifier : mods) {
+ for (Modifier otherMod : otherMods) {
+ list.addAll(generate(template,
+ String.format("%s %s void method() {",
+ modifier.getString(),
+ otherMod.getString()),
+ "}"));
+ }
+ }
+ return list;
+ }
+
+ private List<TestCase> staticAndInstanceInitializer(String template) {
+ List<TestCase> list = new ArrayList<>();
+ for (Modifier modifier : new Modifier[]{Modifier.EMPTY, Modifier.STATIC}) {
+ list.addAll(generate(template, modifier.getString() + "{", "}"));
+ }
+ return list;
+ }
+
+ private Set<String> getFlags(Modifier modifier) {
+ HashSet<String> set = new HashSet<>();
+ if (modifier != Modifier.EMPTY) {
+ set.add("ACC_" + modifier.getString().toUpperCase());
+ }
+ return set;
+ }
+
+ /**
+ * Class represents part of sources which is inserted in other code.
+ */
+ private static class Data {
+ public final String sources;
+ public final Map<String, Set<String>> class2Flags;
+
+ public Data(String sources, Map<String, Set<String>> class2Flags) {
+ this.sources = sources;
+ this.class2Flags = class2Flags;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesIndexTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Test that outer_class_info_index of local and anonymous class is zero.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerClassesIndexTest
+ */
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.InnerClasses_attribute;
+import com.sun.tools.classfile.InnerClasses_attribute.Info;
+
+public class InnerClassesIndexTest extends TestResult {
+
+ public static void main(String[] args) throws TestFailedException {
+ new InnerClassesIndexTest().test();
+ }
+
+ private boolean isExcluded(String className) {
+ return !className.startsWith(InnerClassesIndexTest.class.getName())
+ || "InnerClassesIndexTest$Inner".equals(className);
+ }
+
+ private Set<String> getInnerClasses() {
+ FilenameFilter filter = (dir, name) -> name.matches("InnerClassesIndexTest\\$.*\\.class");
+ return Stream.of(getClassDir().listFiles(filter))
+ .map(File::getName)
+ .map(s -> s.replace(".class", ""))
+ .collect(Collectors.toSet());
+ }
+
+ public void test() throws TestFailedException {
+ try {
+ addTestCase("Source is InnerClassesIndexTest.java");
+ ClassFile classFile = readClassFile(InnerClassesIndexTest.class);
+ InnerClasses_attribute attr = (InnerClasses_attribute)
+ classFile.getAttribute(Attribute.InnerClasses);
+
+ Set<String> foundClasses = new HashSet<>();
+ for (Info info : attr.classes) {
+ String innerName = classFile.constant_pool.
+ getClassInfo(info.inner_class_info_index).getBaseName();
+ echo("Testing class : " + innerName);
+ if (isExcluded(innerName)) {
+ echo("Ignored : " + innerName);
+ continue;
+ }
+ foundClasses.add(innerName);
+ assertEquals(info.outer_class_info_index, 0,
+ "outer_class_info_index of " + innerName);
+ if (innerName.matches("\\$\\d+")) {
+ assertEquals(info.inner_name_index, 0,
+ "inner_name_index of anonymous class");
+ }
+ }
+ Set<String> expectedClasses = getInnerClasses();
+ expectedClasses.remove("InnerClassesIndexTest$Inner");
+ assertEquals(foundClasses, expectedClasses, "All classes are found");
+ } catch (Exception e) {
+ addFailure(e);
+ } finally {
+ checkStatus();
+ }
+ }
+
+ static class Inner {
+ }
+
+ Inner inner1 = new Inner() {
+ };
+
+ static Inner inner2 = new Inner() {
+ };
+
+ Runnable r = () -> {
+ class Local {
+ }
+ new Local() {
+ };
+ };
+
+ public void local() {
+ class Local {
+ }
+ new Local() {
+ };
+ }
+
+ public InnerClassesIndexTest() {
+ class Local {
+ }
+ new Local() {
+ };
+ }
+
+ {
+ class Local {
+ }
+ new Local() {
+ };
+ }
+
+ static {
+ class Local {
+ }
+ new Local() {
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @bug 8034854 8042251
+ * @summary Testing inner classes attributes.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerClassesTest
+ */
+
+import java.util.List;
+
+public class InnerClassesTest extends InnerClassesTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ new InnerClassesTest().test("InnerClassesSrc");
+ }
+
+ private List<TestCase> generateClasses() {
+ setInnerClassType(ClassType.CLASS);
+ setHasSyntheticClass(true);
+ return super.generateTestCases();
+ }
+
+ private List<TestCase> generateEnums() {
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setInnerClassType(ClassType.ENUM);
+ setHasSyntheticClass(false);
+ return super.generateTestCases();
+ }
+
+ private List<TestCase> generateInterfaces() {
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerClassType(ClassType.INTERFACE);
+ return super.generateTestCases();
+ }
+
+ private List<TestCase> generateAnnotations() {
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerClassType(ClassType.ANNOTATION);
+ return super.generateTestCases();
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterAccessModifiers(Modifier.EMPTY);
+ setOuterOtherModifiers(Modifier.EMPTY);
+ setOuterClassType(ClassType.OTHER);
+ }
+
+ @Override
+ public List<TestCase> generateTestCases() {
+ List<TestCase> sources = generateClasses();
+ sources.addAll(generateEnums());
+ sources.addAll(generateInterfaces());
+ sources.addAll(generateAnnotations());
+ return sources;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.InnerClasses_attribute;
+import com.sun.tools.classfile.InnerClasses_attribute.Info;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Base class for tests of inner classes attribute.
+ * The scenario of tests:
+ * 1. set possible values of class modifiers.
+ * 2. according to set class modifiers, a test generates sources
+ * and golden data with {@code generateTestCases}.
+ * 3. a test loops through all test cases and checks InnerClasses
+ * attribute with {@code test}.
+ *
+ * Example, possible flags for outer class are {@code Modifier.PRIVATE and Modifier.PUBLIC},
+ * possible flags for inner class are {@code Modifier.EMPTY}.
+ * At the second step the test generates two test cases:
+ * 1. public class A {
+ * public class B {
+ * class C {}
+ * }
+ * }
+ * 2. public class A {
+ * private class B {
+ * class C {}
+ * }
+ * }
+ */
+public abstract class InnerClassesTestBase extends TestResult {
+
+ private Modifier[] outerAccessModifiers = {Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC};
+ private Modifier[] outerOtherModifiers = {Modifier.EMPTY, Modifier.STATIC, Modifier.FINAL, Modifier.ABSTRACT};
+ private Modifier[] innerAccessModifiers = outerAccessModifiers;
+ private Modifier[] innerOtherModifiers = outerOtherModifiers;
+ private boolean isForbiddenWithoutStaticInOuterMods = false;
+
+ private ClassType outerClassType;
+ private ClassType innerClassType;
+ private boolean hasSyntheticClass;
+ private String prefix = "";
+ private String suffix = "";
+
+ /**
+ * Sets properties.
+ *
+ * Returns generated list of test cases. Method is called in {@code test()}.
+ */
+ public abstract void setProperties();
+
+ /**
+ * Runs the test.
+ *
+ * @param classToTest expected name of outer class
+ * @param skipClasses classes that names should not be checked
+ */
+ public void test(String classToTest, String...skipClasses) throws TestFailedException {
+ try {
+ for (TestCase test : generateTestCases()) {
+ addTestCase(test.getSource());
+ test(classToTest, test, skipClasses);
+ }
+ } catch (Exception e) {
+ addFailure(e);
+ } finally {
+ checkStatus();
+ }
+ }
+
+ /**
+ * If {@code flag} is {@code true} an outer class can not have static modifier.
+ *
+ * @param flag if {@code true} the outer class can not have static modifier
+ */
+ public void setForbiddenWithoutStaticInOuterMods(boolean flag) {
+ isForbiddenWithoutStaticInOuterMods = flag;
+ }
+
+ /**
+ * Sets the possible access flags of an outer class.
+ *
+ * @param mods the possible access flags of an outer class
+ */
+ public void setOuterAccessModifiers(Modifier...mods) {
+ outerAccessModifiers = mods;
+ }
+
+ /**
+ * Sets the possible flags of an outer class.
+ *
+ * @param mods the possible flags of an outer class
+ */
+ public void setOuterOtherModifiers(Modifier...mods) {
+ outerOtherModifiers = mods;
+ }
+
+ /**
+ * Sets the possible access flags of an inner class.
+ *
+ * @param mods the possible access flags of an inner class
+ */
+ public void setInnerAccessModifiers(Modifier...mods) {
+ innerAccessModifiers = mods;
+ }
+
+ /**
+ * Sets the possible flags of an inner class.
+ *
+ * @param mods the possible flags of an inner class
+ */
+ public void setInnerOtherModifiers(Modifier...mods) {
+ innerOtherModifiers = mods;
+ }
+
+ /**
+ * Sets the suffix for the generated source.
+ *
+ * @param suffix a suffix
+ */
+ public void setSuffix(String suffix) {
+ this.suffix = suffix;
+ }
+
+ /**
+ * Sets the prefix for the generated source.
+ *
+ * @param prefix a prefix
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * If {@code true} synthetic class is generated.
+ *
+ * @param hasSyntheticClass if {@code true} synthetic class is generated
+ */
+ public void setHasSyntheticClass(boolean hasSyntheticClass) {
+ this.hasSyntheticClass = hasSyntheticClass;
+ }
+
+ /**
+ * Sets the inner class type.
+ *
+ * @param innerClassType the inner class type
+ */
+ public void setInnerClassType(ClassType innerClassType) {
+ this.innerClassType = innerClassType;
+ }
+
+ /**
+ * Sets the outer class type.
+ *
+ * @param outerClassType the outer class type
+ */
+ public void setOuterClassType(ClassType outerClassType) {
+ this.outerClassType = outerClassType;
+ }
+
+ private void test(String classToTest, TestCase test, String...skipClasses) {
+ printf("Testing :\n%s\n", test.getSource());
+ try {
+ Map<String, Set<String>> class2Flags = test.getFlags();
+ ClassFile cf = readClassFile(compile(test.getSource())
+ .getClasses().get(classToTest));
+ InnerClasses_attribute innerClasses = (InnerClasses_attribute)
+ cf.getAttribute(Attribute.InnerClasses);
+ int count = 0;
+ for (Attribute a : cf.attributes.attrs) {
+ if (a instanceof InnerClasses_attribute) {
+ ++count;
+ }
+ }
+ assertEquals(1, count, "Number of inner classes attribute");
+ if (innerClasses == null) {
+ return;
+ }
+ assertEquals(cf.constant_pool.
+ getUTF8Info(innerClasses.attribute_name_index).value, "InnerClasses",
+ "innerClasses.attribute_name_index");
+ // Inner Classes attribute consists of length (2 bytes)
+ // and 8 bytes for each inner class's entry.
+ assertEquals(innerClasses.attribute_length,
+ 2 + 8 * class2Flags.size(), "innerClasses.attribute_length");
+ assertEquals(innerClasses.number_of_classes,
+ class2Flags.size(), "innerClasses.number_of_classes");
+ Set<String> visitedClasses = new HashSet<>();
+ for (Info e : innerClasses.classes) {
+ String baseName = cf.constant_pool.getClassInfo(
+ e.inner_class_info_index).getBaseName();
+ if (cf.major_version >= 51 && e.inner_name_index == 0) {
+ assertEquals(e.outer_class_info_index, 0,
+ "outer_class_info_index "
+ + "in case of inner_name_index is zero : "
+ + baseName);
+ }
+ String className = baseName.replaceFirst(".*\\$", "");
+ assertTrue(class2Flags.containsKey(className),
+ className);
+ assertTrue(visitedClasses.add(className),
+ "there are no duplicates in attribute : " + className);
+ assertEquals(e.inner_class_access_flags.getInnerClassFlags(),
+ class2Flags.get(className),
+ "inner_class_access_flags " + className);
+ if (!Arrays.asList(skipClasses).contains(className)) {
+ assertEquals(
+ cf.constant_pool.getClassInfo(e.inner_class_info_index).getBaseName(),
+ classToTest + "$" + className,
+ "inner_class_info_index of " + className);
+ if (e.outer_class_info_index > 0) {
+ assertEquals(
+ cf.constant_pool.getClassInfo(e.outer_class_info_index).getName(),
+ classToTest,
+ "outer_class_info_index of " + className);
+ }
+ }
+ }
+ } catch (Exception e) {
+ addFailure(e);
+ }
+ }
+
+ /**
+ * Methods generates list of test cases. Method generates all possible combinations
+ * of acceptable flags for nested inner classes.
+ *
+ * @return generated list of test cases
+ */
+ protected List<TestCase> generateTestCases() {
+ setProperties();
+ List<TestCase> list = new ArrayList<>();
+
+ List<List<Modifier>> outerMods = getAllCombinations(outerAccessModifiers, outerOtherModifiers);
+ List<List<Modifier>> innerMods = getAllCombinations(innerAccessModifiers, innerOtherModifiers);
+
+ for (List<Modifier> outerMod : outerMods) {
+ if (isForbiddenWithoutStaticInOuterMods && !outerMod.contains(Modifier.STATIC)) {
+ continue;
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append("public class InnerClassesSrc {")
+ .append(toString(outerMod)).append(' ')
+ .append(outerClassType).append(' ')
+ .append(prefix).append(' ').append('\n');
+ int count = 0;
+ Map<String, Set<String>> class2Flags = new HashMap<>();
+ List<String> syntheticClasses = new ArrayList<>();
+ for (List<Modifier> innerMod : innerMods) {
+ ++count;
+ String privateConstructor = "";
+ if (hasSyntheticClass && !innerMod.contains(Modifier.ABSTRACT)) {
+ privateConstructor = "private A" + count + "() {}";
+ syntheticClasses.add("new A" + count + "();");
+ }
+ sb.append(toString(innerMod)).append(' ');
+ sb.append(String.format("%s A%d {%s}\n", innerClassType, count, privateConstructor));
+ Set<String> flags = getFlags(innerClassType, innerMod);
+ class2Flags.put("A" + count, flags);
+ }
+ if (hasSyntheticClass) {
+ // Source to generate synthetic classes
+ sb.append(syntheticClasses.stream().collect(Collectors.joining(" ", "{", "}")));
+ class2Flags.put("1", new HashSet<>(Arrays.asList("ACC_STATIC", "ACC_SYNTHETIC")));
+ }
+ sb.append(suffix).append("\n}");
+ getAdditionalFlags(class2Flags, outerClassType, outerMod.toArray(new Modifier[outerMod.size()]));
+ list.add(new TestCase(sb.toString(), class2Flags));
+ }
+ return list;
+ }
+
+ /**
+ * Methods returns flags which must have type.
+ *
+ * @param type class, interface, enum or annotation
+ * @param mods modifiers
+ * @return set of access flags
+ */
+ protected Set<String> getFlags(ClassType type, List<Modifier> mods) {
+ Set<String> flags = mods.stream()
+ .map(Modifier::getString)
+ .filter(str -> !str.isEmpty())
+ .map(str -> "ACC_" + str.toUpperCase())
+ .collect(Collectors.toSet());
+ type.addSpecificFlags(flags);
+ return flags;
+ }
+
+ private List<List<Modifier>> getAllCombinations(Modifier[] accessModifiers, Modifier[] otherModifiers) {
+ List<List<Modifier>> list = new ArrayList<>();
+ for (Modifier access : accessModifiers) {
+ for (int i = 0; i < otherModifiers.length; ++i) {
+ Modifier mod1 = otherModifiers[i];
+ for (int j = i + 1; j < otherModifiers.length; ++j) {
+ Modifier mod2 = otherModifiers[j];
+ if (isForbidden(mod1, mod2)) {
+ continue;
+ }
+ list.add(Arrays.asList(access, mod1, mod2));
+ }
+ if (mod1 == Modifier.EMPTY) {
+ list.add(Arrays.asList(access));
+ }
+ }
+ }
+ return list;
+ }
+
+ private boolean isForbidden(Modifier mod1, Modifier mod2) {
+ return mod1 == Modifier.FINAL && mod2 == Modifier.ABSTRACT
+ || mod1 == Modifier.ABSTRACT && mod2 == Modifier.FINAL;
+ }
+
+ private String toString(List<Modifier> mods) {
+ return mods.stream()
+ .map(Modifier::getString)
+ .filter(s -> !s.isEmpty())
+ .collect(Collectors.joining(" "));
+ }
+
+ /**
+ * Method is called in generateTestCases().
+ * If you need to add additional access flags, you should override this method.
+ *
+ *
+ * @param class2Flags map with flags
+ * @param type class, interface, enum or @annotation
+ * @param mods modifiers
+ */
+ public void getAdditionalFlags(Map<String, Set<String>> class2Flags, ClassType type, Modifier...mods) {
+ class2Flags.values().forEach(type::addFlags);
+ }
+
+ public enum ClassType {
+ CLASS("class") {
+ @Override
+ public void addSpecificFlags(Set<String> flags) {
+ }
+ },
+ INTERFACE("interface") {
+ @Override
+ public void addFlags(Set<String> flags) {
+ flags.add("ACC_STATIC");
+ flags.add("ACC_PUBLIC");
+ }
+
+ @Override
+ public void addSpecificFlags(Set<String> flags) {
+ flags.add("ACC_INTERFACE");
+ flags.add("ACC_ABSTRACT");
+ flags.add("ACC_STATIC");
+ }
+ },
+ ANNOTATION("@interface") {
+ @Override
+ public void addFlags(Set<String> flags) {
+ flags.add("ACC_STATIC");
+ flags.add("ACC_PUBLIC");
+ }
+
+ @Override
+ public void addSpecificFlags(Set<String> flags) {
+ flags.add("ACC_INTERFACE");
+ flags.add("ACC_ABSTRACT");
+ flags.add("ACC_STATIC");
+ flags.add("ACC_ANNOTATION");
+ }
+ },
+ ENUM("enum") {
+ @Override
+ public void addSpecificFlags(Set<String> flags) {
+ flags.add("ACC_ENUM");
+ flags.add("ACC_FINAL");
+ flags.add("ACC_STATIC");
+ }
+ },
+ OTHER("") {
+ @Override
+ public void addSpecificFlags(Set<String> flags) {
+ }
+ };
+
+ private final String classType;
+
+ private ClassType(String clazz) {
+ this.classType = clazz;
+ }
+
+ public abstract void addSpecificFlags(Set<String> flags);
+
+ public String toString() {
+ return classType;
+ }
+
+ public void addFlags(Set<String> set) {
+ }
+ }
+
+ public enum Modifier {
+ PUBLIC("public"), PRIVATE("private"),
+ PROTECTED("protected"), DEFAULT("default"),
+ FINAL("final"), ABSTRACT("abstract"),
+ STATIC("static"), EMPTY("");
+
+ private final String str;
+
+ private Modifier(String str) {
+ this.str = str;
+ }
+
+ public String getString() {
+ return str;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerAnnotationTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner enums in inner annotation.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerEnumInInnerAnnotationTest
+ */
+
+public class InnerEnumInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerEnumInInnerAnnotationTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setOuterClassType(ClassType.ANNOTATION);
+ setInnerClassType(ClassType.ENUM);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerEnumTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner enums in inner enum.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerEnumInInnerEnumTest
+ */
+
+public class InnerEnumInInnerEnumTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerEnumInInnerEnumTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setOuterClassType(ClassType.ENUM);
+ setInnerClassType(ClassType.ENUM);
+ setPrefix("Inner {;");
+ setSuffix("}");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerInterfaceTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner enums in inner interface.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerEnumInInnerInterfaceTest
+ */
+
+public class InnerEnumInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerEnumInInnerInterfaceTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setOuterClassType(ClassType.INTERFACE);
+ setInnerClassType(ClassType.ENUM);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerEnumsInInnerClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner enums in inner class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerEnumsInInnerClassTest
+ */
+
+public class InnerEnumsInInnerClassTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerEnumsInInnerClassTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setForbiddenWithoutStaticInOuterMods(true);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setOuterClassType(ClassType.CLASS);
+ setInnerClassType(ClassType.ENUM);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerAnnotationTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner interfaces in inner annotation.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerInterfacesInInnerAnnotationTest
+ */
+
+public class InnerInterfacesInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerInterfacesInInnerAnnotationTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setOuterClassType(ClassType.ANNOTATION);
+ setInnerClassType(ClassType.INTERFACE);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Testing InnerClasses_attribute of inner interfaces in inner class.
+ * @author aeremeev
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerInterfacesInInnerClassTest
+ */
+
+public class InnerInterfacesInInnerClassTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerInterfacesInInnerClassTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setForbiddenWithoutStaticInOuterMods(true);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setOuterClassType(ClassType.CLASS);
+ setInnerClassType(ClassType.INTERFACE);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerEnumTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner interfaces in inner enum.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerInterfacesInInnerEnumTest
+ */
+
+public class InnerInterfacesInInnerEnumTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerInterfacesInInnerEnumTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setOuterClassType(ClassType.ENUM);
+ setInnerClassType(ClassType.INTERFACE);
+ setPrefix("Inner {;");
+ setSuffix("}");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerInterfaceTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner interfaces in inner interface.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerInterfacesInInnerInterfaceTest
+ */
+
+import java.util.List;
+
+public class InnerInterfacesInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
+
+ public static void main(String[] args) throws TestFailedException {
+ InnerClassesTestBase test = new InnerInterfacesInInnerInterfaceTest();
+ test.test("InnerClassesSrc$Inner", "Inner", "1");
+ }
+
+ @Override
+ public void setProperties() {
+ setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+ setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+ setOuterClassType(ClassType.INTERFACE);
+ setInnerClassType(ClassType.INTERFACE);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/NoInnerClassesTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Test that there are no inner classes attributes in case of there are no inner classes.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build TestBase InMemoryFileManager ToolBox
+ * @run main NoInnerClassesTest
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+
+import java.io.IOException;
+
+public class NoInnerClassesTest extends TestBase {
+
+ public static void main(String[] args) throws IOException, ConstantPoolException {
+ new NoInnerClassesTest().test();
+ }
+
+ public void test() throws IOException, ConstantPoolException {
+ ClassFile classFile = readClassFile("NoInnerClassesTest");
+ assertNull(classFile.getAttribute(Attribute.InnerClasses), "Found inner class attribute");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/README.txt Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,92 @@
+The description of the tests for the InnerClasses attribute.
+
+InnerClassesTestBase is the base class for tests of inner classes attribute.
+Each tests extends the base class.
+The scenario of tests:
+ 1. set possible values of class modifiers, outer/inner class types.
+ 2. according to set class modifiers, a test generates sources
+ and golden data with generateTestCases.
+ 3. a test loops through all test cases and checks InnerClasses attribute in method test().
+
+Example, possible flags for outer class are Modifier.PRIVATE and Modifier.PUBLIC,
+possible flags for inner class are Modifier.EMPTY, outer class type is CLASS
+and inner class type is CLASS.
+At the second step the test generates two test cases:
+ 1. public class A {
+ public class B {
+ class C {}
+ }
+ }
+ 2. public class A {
+ private class B {
+ class C {}
+ }
+ }
+
+The list of tests.
+
+Test: test if there is not inner class, the InnerClasses attribute
+is not generated (NoInnerClasses.java).
+
+Test: inner classes in anonymous class (InnerClassesInAnonymousClassTest.java).
+Possible access flags of the inner class: abstract and final.
+
+Test: inner classes in local class (InnerClassesInLocalClassTest.java).
+Locations of local class: static and instance initializer, constructor, method, lambda,
+default and static methods of interface.
+
+Test: test the outer_class_info_index and inner_name_index of
+local and anonymous classes (InnerClassesIndexTest.java).
+
+List of test cases for Inner*InInner*Test:
+ * InnerClassesInInnerClassTest
+ outer flags: all possible flags
+ inner flags: all possible flags
+ * InnerClassesInInnerEnumTest
+ outer flags: all access flags, abstract
+ inner flags: all possible flags
+ * InnerClassesInInnerAnnotationTest
+ outer flags: all access flags, abstract
+ inner flags: all flags, except private and protected
+ * InnerClassesInInnerInterfaceTest
+ outer flags: all access flags, abstract
+ inner flags: all flags, except private and protected
+
+ * InnerEnumsInInnerClassTest
+ outer flags: all possible flags
+ inner flags: all possible flags
+ * InnerEnumsInInnerEnumTest
+ outer flags: all possible flags
+ inner flags: all possible flags
+ * InnerEnumsInInnerAnnotationTest
+ outer flags: all access flags, abstract, static
+ inner flags: public, static
+ * InnerEnumsInInnerInterfaceTest
+ outer flags: all access flags, abstract, static
+ inner flags: public, static
+
+ * InnerAnnotationInInnerClassTest
+ outer flags: all possible flags, except static
+ inner flags: all access flags, abstract and static
+ * InnerAnnotationInInnerEnumTest
+ outer flags: all access flags, static
+ inner flags: all access flags, abstract and static
+ * InnerAnnotationInInnerAnnotation
+ outer flags: all access flags, static and abstract
+ inner flags: public, abstract, static
+ * InnerAnnotationInInnerInterface
+ outer flags: all access flags, static and abstract
+ inner flags: public, abstract, static
+
+ * InnerInterfaceInInnerClassTest
+ outer flags: all possible flags, except static
+ inner flags: all access flags, abstract and static
+ * InnerInterfaceInInnerEnumTest
+ outer flags: all access flags, static
+ inner flags: all access flags, abstract and static
+ * InnerInterfaceInInnerAnnotation
+ outer flags: all access flags, static and abstract
+ inner flags: public, abstract, static
+ * InnerInterfaceInInnerInterface
+ outer flags: all access flags, static and abstract
+ inner flags: public, abstract, static
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/TestCase.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Class represents test cases. This class contains source code and
+ * access flags for each inner class in source code.
+ */
+public class TestCase {
+
+ private final String sourceCode;
+ private final Map<String, Set<String>> class2Flags;
+
+ public TestCase(String sourceCode, Map<String, Set<String>> class2Flags) {
+ this.sourceCode = sourceCode;
+ this.class2Flags = class2Flags;
+ }
+
+ /**
+ * Returns source code.
+ *
+ * @return source code
+ */
+ public String getSource() {
+ return sourceCode;
+ }
+
+ /**
+ * Returns map with entries (ClassName, set of access flags for the ClassName).
+ *
+ * @return map with entries (ClassName, set of access flags for the ClassName)
+ */
+ public Map<String, Set<String>> getFlags() {
+ return class2Flags;
+ }
+}
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java Thu Aug 28 14:53:49 2014 -0700
@@ -22,22 +22,23 @@
*/
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
-import java.util.stream.Stream;
+import java.util.stream.Collectors;
+
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
-import static java.lang.String.format;
-import static java.lang.System.lineSeparator;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toList;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
/**
* Base class for class file attribute tests.
@@ -46,7 +47,7 @@
*/
public class TestBase {
- public static final String LINE_SEPARATOR = lineSeparator();
+ public static final String LINE_SEPARATOR = System.lineSeparator();
private <S> InMemoryFileManager compile(
List<String> options,
@@ -57,7 +58,7 @@
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<? extends JavaFileObject> src = sources.stream()
.map(src2JavaFileObject)
- .collect(toList());
+ .collect(Collectors.toList());
DiagnosticCollector<? super JavaFileObject> dc = new DiagnosticCollector<>();
try (InMemoryFileManager fileManager
@@ -67,7 +68,7 @@
if (!success) {
String errorMessage = dc.getDiagnostics().stream()
.map(Object::toString)
- .collect(joining("\n"));
+ .collect(Collectors.joining("\n"));
throw new CompilationException("Compilation Error\n\n" + errorMessage);
}
return fileManager;
@@ -82,7 +83,7 @@
*/
public InMemoryFileManager compile(String... sources)
throws IOException, CompilationException {
- return compile(emptyList(), sources);
+ return compile(Collections.emptyList(), sources);
}
/**
@@ -94,7 +95,7 @@
*/
public InMemoryFileManager compile(List<String> options, String... sources)
throws IOException, CompilationException {
- return compile(options, ToolBox.JavaSource::new, asList(sources));
+ return compile(options, ToolBox.JavaSource::new, Arrays.asList(sources));
}
/**
@@ -105,7 +106,7 @@
*/
public InMemoryFileManager compile(String[]... sources) throws IOException,
CompilationException {
- return compile(emptyList(), sources);
+ return compile(Collections.emptyList(), sources);
}
/**
@@ -117,12 +118,73 @@
*/
public InMemoryFileManager compile(List<String> options, String[]... sources)
throws IOException, CompilationException {
- return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), asList(sources));
+ return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), Arrays.asList(sources));
+ }
+
+ /**
+ * Returns class file that is read from {@code is}.
+ *
+ * @param is an input stream
+ * @return class file that is read from {@code is}
+ * @throws IOException if I/O error occurs
+ * @throws ConstantPoolException if constant pool error occurs
+ */
+ public ClassFile readClassFile(InputStream is) throws IOException, ConstantPoolException {
+ return ClassFile.read(is);
+ }
+
+ /**
+ * Returns class file that is read from {@code fileObject}.
+ *
+ * @param fileObject a file object
+ * @return class file that is read from {@code fileObject}
+ * @throws IOException if I/O error occurs
+ * @throws ConstantPoolException if constant pool error occurs
+ */
+ public ClassFile readClassFile(JavaFileObject fileObject) throws IOException, ConstantPoolException {
+ return readClassFile(fileObject.openInputStream());
+ }
+
+ /**
+ * Returns class file that corresponds to {@code clazz}.
+ *
+ * @param clazz a class
+ * @return class file that is read from {@code clazz}
+ * @throws IOException if I/O error occurs
+ * @throws ConstantPoolException if constant pool error occurs
+ */
+ public ClassFile readClassFile(Class<?> clazz) throws IOException, ConstantPoolException {
+ return readClassFile(getClassFile(clazz));
+ }
+
+ /**
+ * Returns class file that corresponds to {@code className}.
+ *
+ * @param className a class name
+ * @return class file that is read from {@code className}
+ * @throws IOException if I/O error occurs
+ * @throws ConstantPoolException if constant pool error occurs
+ */
+ public ClassFile readClassFile(String className) throws IOException, ConstantPoolException {
+ return readClassFile(getClassFile(className + ".class"));
+ }
+
+ /**
+ * Returns class file that is read from {@code file}.
+ *
+ * @param file a file
+ * @return class file that is read from {@code file}
+ * @throws IOException if I/O error occurs
+ * @throws ConstantPoolException if constant pool error occurs
+ */
+ public ClassFile readClassFile(File file) throws IOException, ConstantPoolException {
+ return readClassFile(new FileInputStream(file));
}
public void assertEquals(Object actual, Object expected, String message) {
if (!Objects.equals(actual, expected))
- throw new AssertionFailedException(format("%s%nGot: %s, Expected: %s", message, actual, expected));
+ throw new AssertionFailedException(String.format("%s%nGot: %s, Expected: %s",
+ message, actual, expected));
}
public void assertNull(Object actual, String message) {
@@ -169,22 +231,18 @@
* @param message string to print.
*/
public void echo(String message) {
- System.err.println(message.replace("\n", LINE_SEPARATOR));
+ printf(message + "\n");
}
/**
- * Substitutes args in template and prints result to standard error. New lines are converted to system dependent NL.
+ * Substitutes args in template and prints result to standard error.
+ * New lines are converted to system dependent NL.
*
* @param template template in standard String.format(...) format.
* @param args arguments to substitute in template.
*/
public void printf(String template, Object... args) {
- System.err.printf(template, Stream.of(args)
- .map(Objects::toString)
- .map(m -> m.replace("\n", LINE_SEPARATOR))
- .collect(toList())
- .toArray());
-
+ System.err.printf(String.format(template, args).replace("\n", LINE_SEPARATOR));
}
public static class CompilationException extends Exception {
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java Thu Aug 28 14:53:49 2014 -0700
@@ -23,13 +23,15 @@
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
+import java.util.stream.Stream;
import static java.lang.String.format;
import static java.util.stream.Collectors.joining;
+/**
+ * This class accumulates test results. Test results can be checked with method @{code checkStatus}.
+ */
public class TestResult extends TestBase {
private final List<Info> testCases;
@@ -39,15 +41,18 @@
testCases.add(new Info("Global test info"));
}
- public void addTestCase(String src) {
- testCases.add(new Info(src));
+ /**
+ * Adds new test case info.
+ *
+ * @param info the information about test case
+ */
+ public void addTestCase(String info) {
+ testCases.add(new Info(info));
}
- public String errorMessage() {
+ private String errorMessage() {
return testCases.stream().filter(Info::isFailed)
- .map(tc -> format("Failure in test case:\n%s\n%s", tc.info(),
- (tc.asserts.size() > 0 ? tc.getAssertMessage() + "\n" : "")
- + tc.getErrorMessage()))
+ .map(tc -> format("Failure in test case:\n%s\n%s", tc.info(), tc.getMessage()))
.collect(joining("\n"));
}
@@ -76,8 +81,14 @@
getLastTestCase().assertEquals(actual, true, message);
}
+ public void assertContains(Set<?> found, Set<?> expected, String message) {
+ Set<?> copy = new HashSet<>(expected);
+ copy.removeAll(found);
+ assertTrue(found.containsAll(expected), message + " : " + copy);
+ }
+
public void addFailure(Throwable th) {
- getLastTestCase().addFailure(th);
+ testCases.get(testCases.size() - 1).addFailure(th);
}
private Info getLastTestCase() {
@@ -87,6 +98,13 @@
return testCases.get(testCases.size() - 1);
}
+ /**
+ * Throws {@code TestFailedException} if one of the asserts are failed
+ * or an exception occurs. Prints error message of failed test cases.
+ *
+ * @throws TestFailedException if one of the asserts are failed
+ * or an exception occurs
+ */
public void checkStatus() throws TestFailedException {
if (testCases.stream().anyMatch(Info::isFailed)) {
echo(errorMessage());
@@ -120,7 +138,13 @@
}
public void addFailure(String message) {
- asserts.add(message);
+ String stackTrace = Stream.of(Thread.currentThread().getStackTrace())
+ // just to get stack trace without TestResult and Thread
+ .filter(e -> !"TestResult.java".equals(e.getFileName()) &&
+ !"java.lang.Thread".equals(e.getClassName()))
+ .map(e -> "\tat " + e)
+ .collect(joining("\n"));
+ asserts.add(format("%s\n%s", message, stackTrace));
printf("[ASSERT] : %s\n", message);
}
@@ -138,6 +162,10 @@
}
}
+ public String getMessage() {
+ return (asserts.size() > 0 ? getAssertMessage() + "\n" : "") + getErrorMessage();
+ }
+
public String getAssertMessage() {
return asserts.stream()
.map(failure -> "[ASSERT] : " + failure)
@@ -146,8 +174,7 @@
public String getErrorMessage() {
return errors.stream()
- .map(throwable ->
- format("[ERROR] : %s", getStackTrace(throwable)))
+ .map(throwable -> format("[ERROR] : %s", getStackTrace(throwable)))
.collect(joining("\n"));
}
--- a/langtools/test/tools/javac/defaultMethodsVisibility/DefaultMethodsNotVisibleForSourceLessThan8Test.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/defaultMethodsVisibility/DefaultMethodsNotVisibleForSourceLessThan8Test.java Thu Aug 28 14:53:49 2014 -0700
@@ -26,7 +26,7 @@
* @bug 8029240 8030855
* @summary Default methods not always visible under -source 7
* Default methods should be visible under source previous to 8
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main DefaultMethodsNotVisibleForSourceLessThan8Test
*/
@@ -111,6 +111,7 @@
String outDir;
String source;
+ ToolBox tb = new ToolBox();
void run(String source) throws Exception {
this.source = source;
@@ -127,50 +128,53 @@
/* as an extra check let's make sure that interface 'I' can't be compiled
* with source < 8
*/
- ToolBox.JavaToolArgs javacArgs =
- new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
- .setOptions("-d", outDir, "-source", source)
- .setSources(ISrc);
- ToolBox.javac(javacArgs);
+ tb.new JavacTask()
+ .outdir(outDir)
+ .options("-source", source)
+ .sources(ISrc)
+ .run(ToolBox.Expect.FAIL);
//but it should compile with source >= 8
- javacArgs =
- new ToolBox.JavaToolArgs()
- .setOptions("-d", outDir)
- .setSources(ISrc);
- ToolBox.javac(javacArgs);
+ tb.new JavacTask()
+ .outdir(outDir)
+ .sources(ISrc)
+ .run();
- javacArgs =
- new ToolBox.JavaToolArgs()
- .setOptions("-cp", outDir, "-d", outDir, "-source", source)
- .setSources(JSrc, ASrc, BSrc);
- ToolBox.javac(javacArgs);
+ tb.new JavacTask()
+ .outdir(outDir)
+ .classpath(outDir)
+ .options("-source", source)
+ .sources(JSrc, ASrc, BSrc)
+ .run();
}
void testLegacyImplementations() throws Exception {
//compile C1-4
- ToolBox.JavaToolArgs javacArgs =
- new ToolBox.JavaToolArgs()
- .setOptions("-cp", outDir, "-d", outDir, "-source", source)
- .setSources(C1Src, C2Src, C3Src, C4Src);
- ToolBox.javac(javacArgs);
+ tb.new JavacTask()
+ .outdir(outDir)
+ .classpath(outDir)
+ .options("-source", source)
+ .sources(C1Src, C2Src, C3Src, C4Src)
+ .run();
}
void testLegacyInvocations() throws Exception {
//compile LegacyInvocation
- ToolBox.JavaToolArgs javacArgs =
- new ToolBox.JavaToolArgs()
- .setOptions("-cp", outDir, "-d", outDir, "-source", source)
- .setSources(LegacyInvocationSrc);
- ToolBox.javac(javacArgs);
+ tb.new JavacTask()
+ .outdir(outDir)
+ .classpath(outDir)
+ .options("-source", source)
+ .sources(LegacyInvocationSrc)
+ .run();
}
void testSuperInvocations() throws Exception {
//compile SubA, SubB
- ToolBox.JavaToolArgs javacArgs =
- new ToolBox.JavaToolArgs()
- .setOptions("-cp", outDir, "-d", outDir, "-source", source)
- .setSources(SubASrc, SubBSrc);
- ToolBox.javac(javacArgs);
+ tb.new JavacTask()
+ .outdir(outDir)
+ .classpath(outDir)
+ .options("-source", source)
+ .sources(SubASrc, SubBSrc)
+ .run();
}
}
--- a/langtools/test/tools/javac/fatalErrors/NoJavaLangTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/fatalErrors/NoJavaLangTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,12 @@
* @test
* @bug 4263768 4785453
* @summary Verify that the compiler does not crash when java.lang is not
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main NoJavaLangTest
*/
-import java.util.ArrayList;
-import java.util.List;
-
-//original test: test/tools/javac/fatalErrors/NoJavaLang.sh
+// Original test: test/tools/javac/fatalErrors/NoJavaLang.sh
public class NoJavaLangTest {
private static final String noJavaLangSrc =
@@ -49,26 +46,20 @@
"Fatal Error: Unable to find package java.lang in classpath or bootclasspath";
public static void main(String[] args) throws Exception {
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} NoJavaLang.java 2> "${TMP1}"
- ToolBox.JavaToolArgs javacSuccessArgs =
- new ToolBox.JavaToolArgs().setSources(noJavaLangSrc);
- ToolBox.javac(javacSuccessArgs);
+ ToolBox tb = new ToolBox();
+
+ tb.new JavacTask()
+ .sources(noJavaLangSrc)
+ .run();
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -bootclasspath . NoJavaLang.java 2> "${TMP1}"
- List<String> output = new ArrayList<>();
- ToolBox.JavaToolArgs javacFailArgs =
- new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
- .setOptions("-bootclasspath", ".")
- .setSources(noJavaLangSrc)
- .setErrOutput(output);
+ String out = tb.new JavacTask()
+ .options("-bootclasspath", ".")
+ .sources(noJavaLangSrc)
+ .run(ToolBox.Expect.FAIL, 3)
+ .writeAll()
+ .getOutput(ToolBox.OutputKind.DIRECT);
- int cr = ToolBox.javac(javacFailArgs);
- if (cr != 3) {
- throw new AssertionError("Compiler exit result should be 3");
- }
-
-// diff ${DIFFOPTS} -c "${TESTSRC}${FS}NoJavaLang.out" "${TMP1}"
- if (!(output.size() == 1 && output.get(0).equals(compilerErrorMessage))) {
+ if (!out.trim().equals(compilerErrorMessage)) {
throw new AssertionError("javac generated error output is not correct");
}
}
--- a/langtools/test/tools/javac/innerClassFile/InnerClassFileTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/innerClassFile/InnerClassFileTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,15 @@
* @test
* @bug 4491755 4785453
* @summary Prob w/static inner class with same name as a regular class
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main InnerClassFileTest
*/
+import java.nio.file.Path;
import java.nio.file.Paths;
-//original test: test/tools/javac/innerClassFile/Driver.sh
+// Original test: test/tools/javac/innerClassFile/Driver.sh
public class InnerClassFileTest {
private static final String BSrc =
@@ -90,38 +91,37 @@
new InnerClassFileTest().run();
}
+ private final ToolBox tb = new ToolBox();
+
void run() throws Exception {
createFiles();
compileFiles();
}
void createFiles() throws Exception {
-// mkdir src
-// cp -r ${TESTSRC}${FS}* src
- ToolBox.createJavaFileFromSource(Paths.get("src"), BSrc);
- ToolBox.createJavaFileFromSource(Paths.get("src"), CSrc);
- ToolBox.createJavaFileFromSource(Paths.get("src"), MainSrc);
- ToolBox.createJavaFileFromSource(Paths.get("src"), R1Src);
- ToolBox.createJavaFileFromSource(Paths.get("src"), R2Src);
- ToolBox.createJavaFileFromSource(Paths.get("src"), R3Src);
+ Path srcDir = Paths.get("src");
+ tb.writeJavaFiles(srcDir, BSrc, CSrc, MainSrc, R1Src, R2Src, R3Src);
}
void compileFiles() throws Exception {
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . -classpath .
-// -sourcepath src src/x/B.java src/x/C.java src/y/Main.java
- ToolBox.JavaToolArgs args =
- new ToolBox.JavaToolArgs()
- .setAllArgs("-d", ".", "-cp" , ".", "-sourcepath", "src",
- "src/x/B.java", "src/x/C.java", "src/y/Main.java");
- ToolBox.javac(args);
+ tb.new JavacTask()
+ .outdir(".")
+ .classpath(".")
+ .sourcepath("src")
+ .files("src/x/B.java", "src/x/C.java", "src/y/Main.java")
+ .run()
+ .writeAll();
-// rm y/R3.class
- ToolBox.rm(Paths.get("y", "R3.class"));
+ tb.deleteFiles("y/R3.class");
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . -classpath .
-// -sourcepath src src/y/Main.java
- args.setAllArgs("-d", ".", "-cp", ".", "-sourcepath", "src", "src/y/Main.java");
- ToolBox.javac(args);
+ tb.new JavacTask()
+ .outdir(".")
+ .classpath(".")
+ .sourcepath("src")
+ .files("src/y/Main.java")
+ .run()
+ .writeAll();
+
}
}
--- a/langtools/test/tools/javac/javazip/JavaZipTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/javazip/JavaZipTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,16 @@
* @test
* @bug 4098712 6304984 6388453
* @summary check that source files inside zip files on the class path are ignored
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main JavaZipTest
*/
-import java.io.File;
+import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.Arrays;
-//original test: test/tools/javac/javazip/Test.sh
+// Original test: test/tools/javac/javazip/Test.sh
public class JavaZipTest {
private static final String ASrc =
@@ -62,7 +63,7 @@
{"-d", "output", "-cp", "good.jar", "A.java"},
};
- private static final String[][] unSuccessfulCompilationArgs = {
+ private static final String[][] unsuccessfulCompilationArgs = {
{"-d", "output", "A.java", "bad/B.java"},
{"-d", "output", "-cp", "bad", "A.java"},
{"-d", "output", "-sourcepath", "bad", "A.java"},
@@ -74,53 +75,57 @@
new JavaZipTest().test();
}
+ private final ToolBox tb = new ToolBox();
+
public void test() throws Exception {
createOutputDirAndSourceFiles();
createZipsAndJars();
check(ToolBox.Expect.SUCCESS, successfulCompilationArgs);
- check(ToolBox.Expect.FAIL, unSuccessfulCompilationArgs);
+ check(ToolBox.Expect.FAIL, unsuccessfulCompilationArgs);
}
void createOutputDirAndSourceFiles() throws Exception {
//create output dir
- new File("output").mkdir();
+ Files.createDirectory(Paths.get("output"));
//source file creation
- ToolBox.createJavaFileFromSource(Paths.get("good"), BGoodSrc);
- ToolBox.createJavaFileFromSource(Paths.get("bad"), BBadSrc);
- ToolBox.createJavaFileFromSource(ASrc);
+ tb.writeJavaFiles(Paths.get("good"), BGoodSrc);
+ tb.writeJavaFiles(Paths.get("bad"), BBadSrc);
+ tb.writeJavaFiles(ToolBox.currDir, ASrc);
}
void createZipsAndJars() throws Exception {
//jar and zip creation
-// check ok "${TESTJAVA}${FS}bin${FS}jar" cf "${SCR}${FS}good.jar" -C "${TESTSRC}${FS}good" B.java
-// check ok "${TESTJAVA}${FS}bin${FS}jar" cf "${SCR}${FS}good.zip" -C "${TESTSRC}${FS}good" B.java
-// check ok "${TESTJAVA}${FS}bin${FS}jar" cf "${SCR}${FS}bad.jar" -C "${TESTSRC}${FS}bad" B.java
-// check ok "${TESTJAVA}${FS}bin${FS}jar" cf "${SCR}${FS}bad.zip" -C "${TESTSRC}${FS}bad" B.java
for (String[] args: jarArgs) {
- ToolBox.jar(args);
+ tb.new JarTask().run(args).writeAll();
}
}
- void check(ToolBox.Expect whatToExpect, String[][] theArgs) throws Exception {
-// check ok "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} "${TESTSRC}${FS}A.java" "${TESTSRC}${FS}good${FS}B.java"
-// check ok "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -classpath "${TESTSRC}${FS}good" "${TESTSRC}${FS}A.java"
-// check ok "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -sourcepath "${TESTSRC}${FS}good" "${TESTSRC}${FS}A.java"
-// check ok "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -classpath "${SCR}${FS}good.zip" "${TESTSRC}${FS}A.java"
-// check ok "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -classpath "${SCR}${FS}good.jar" "${TESTSRC}${FS}A.java"
+ void check(ToolBox.Expect expectedStatus, String[][] theArgs) throws Exception {
-// check err "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} "${TESTSRC}${FS}A.java" "${TESTSRC}${FS}bad${FS}B.java"
-// check err "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -classpath "${TESTSRC}${FS}bad" "${TESTSRC}${FS}A.java"
-// check err "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -sourcepath "${TESTSRC}${FS}bad" "${TESTSRC}${FS}A.java"
-// check err "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -sourcepath "${SCR}${FS}bad.zip" "${TESTSRC}${FS}A.java"
-// check err "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -sourcepath "${SCR}${FS}bad.jar" "${TESTSRC}${FS}A.java"
- ToolBox.JavaToolArgs args =
- new ToolBox.JavaToolArgs(whatToExpect);
for (String[] allArgs: theArgs) {
- args.setAllArgs(allArgs);
- ToolBox.javac(args);
+ tb.new JavacTask()
+ .options(opts(allArgs))
+ .files(files(allArgs))
+ .run(expectedStatus)
+ .writeAll();
+
}
}
+ private String[] opts(String... allArgs) {
+ int i = allArgs.length;
+ while (allArgs[i - 1].endsWith(".java"))
+ i--;
+ return Arrays.copyOfRange(allArgs, 0, i);
+ }
+
+ private String[] files(String... allArgs) {
+ int i = allArgs.length;
+ while (allArgs[i - 1].endsWith(".java"))
+ i--;
+ return Arrays.copyOfRange(allArgs, i, allArgs.length);
+ }
+
}
--- a/langtools/test/tools/javac/lambda/lambdaNaming/TestSerializedLambdaNameStability.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/TestSerializedLambdaNameStability.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @bug 8023668
* @summary Desugar serializable lambda bodies using more robust naming scheme
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main TestSerializedLambdaNameStability
*/
@@ -125,6 +125,7 @@
static final String compiledDir = System.getProperty("user.dir");
static final String sourceBaseDir = System.getProperty("test.src");
+ final ToolBox tb = new ToolBox();
final String context;
public TestClassLoader(String context) {
@@ -154,10 +155,10 @@
else
throw new Exception("Did not expect to load " + name);
Path srcFile = Paths.get(sourceBaseDir, context, srcName + ".java");
- String testSource = new String(Files.readAllBytes(srcFile));
- ToolBox.JavaToolArgs javacSuccessArgs =
- new ToolBox.JavaToolArgs().setSources(testSource);
- ToolBox.javac(javacSuccessArgs);
+ tb.new JavacTask()
+ .outdir(compiledDir)
+ .files(srcFile)
+ .run();
Path cfFile = Paths.get(compiledDir, name + ".class");
byte[] bytes = Files.readAllBytes(cfFile);
return bytes;
--- a/langtools/test/tools/javac/lib/ToolBox.java Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1080 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URI;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.tools.FileObject;
-import javax.tools.ForwardingJavaFileManager;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
-
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.api.JavacTaskImpl;
-
-import sun.tools.jar.Main;
-
-import static java.nio.file.StandardCopyOption.*;
-
-/**
- * Toolbox for jtreg tests.
- */
-
-public class ToolBox {
-
- public static final String lineSeparator = System.getProperty("line.separator");
- public static final String jdkUnderTest = System.getProperty("test.jdk");
- public static final Path javaBinary = Paths.get(jdkUnderTest, "bin", "java");
- public static final Path javacBinary = Paths.get(jdkUnderTest, "bin", "javac");
-
- public static final List<String> testVMOpts = readOptions("test.vm.opts");
- public static final List<String> testToolVMOpts = readOptions("test.tool.vm.opts");
- public static final List<String> testJavaOpts = readOptions("test.java.opts");
-
- private static final Charset defaultCharset = Charset.defaultCharset();
-
- static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-
- private static List<String> readOptions(String property) {
- String options = System.getProperty(property, "");
- return options.length() > 0 ? Arrays.asList(options.split("\\s+")) : Collections.<String>emptyList();
- }
-
- /**
- * The expected result of command-like method execution.
- */
- public enum Expect {SUCCESS, FAIL}
-
- enum AcceptedParams {
- EXPECT,
- SOURCES,
- OPTIONS,
- STD_OUTPUT,
- ERR_OUTPUT,
- EXTRA_ENV,
- }
-
- enum OutputKind {STD, ERR}
-
- /**
- * Helper class to abstract the processing of command's output.
- */
- static abstract class WriterHelper {
- OutputKind kind;
- public abstract void pipeOutput(ProcessBuilder pb);
- public abstract void readFromStream(Process p) throws IOException;
- public abstract void addAll(Collection<? extends String> c) throws IOException;
- }
-
- /**
- * Helper class for redirecting command's output to a file.
- */
- static class FileWriterHelper extends WriterHelper {
- File file;
-
- FileWriterHelper(File file, OutputKind kind) {
- this.file = file;
- this.kind = kind;
- }
-
- @Override
- public void pipeOutput(ProcessBuilder pb) {
- if (file != null) {
- switch (kind) {
- case STD:
- pb.redirectInput(file);
- break;
- case ERR:
- pb.redirectError(file);
- break;
- }
- }
- }
-
- @Override
- public void readFromStream(Process p) throws IOException {}
-
- @Override
- public void addAll(Collection<? extends String> c) throws IOException {
- if (file.exists())
- Files.write(file.toPath(), c, defaultCharset,
- StandardOpenOption.WRITE, StandardOpenOption.APPEND);
- else
- Files.write(file.toPath(), c, defaultCharset);
- }
- }
-
- /**
- * Helper class for redirecting command's output to a String list.
- */
- static class ListWriterHelper extends WriterHelper {
- List<String> list;
-
- public ListWriterHelper(List<String> list, OutputKind kind) {
- this.kind = kind;
- this.list = list;
- }
-
- @Override
- public void pipeOutput(ProcessBuilder pb) {}
-
- @Override
- public void readFromStream(Process p) throws IOException {
- BufferedReader br = null;
- switch (kind) {
- case STD:
- br = new BufferedReader(new InputStreamReader(p.getInputStream()));
- break;
- case ERR:
- br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
- break;
- }
- String line;
- while ((line = br.readLine()) != null) {
- list.add(line);
- }
- }
-
- public void addAll(Collection<? extends String> c) {
- list.addAll(c);
- }
- }
-
- /**
- * Simple factory class for creating a WriterHelper instance.
- */
- static class WriterHelperFactory {
- static WriterHelper make(File file, OutputKind kind) {
- return new FileWriterHelper(file, kind);
- }
-
- static WriterHelper make(List<String> list, OutputKind kind) {
- return new ListWriterHelper(list, kind);
- }
- }
-
- /**
- * A generic class for holding command's arguments.
- */
- public static abstract class GenericArgs <T extends GenericArgs> {
- protected static List<Set<AcceptedParams>> minAcceptedParams;
-
- protected Set<AcceptedParams> currentParams =
- EnumSet.<AcceptedParams>noneOf(AcceptedParams.class);
-
- protected Expect whatToExpect;
- protected WriterHelper stdOutput;
- protected WriterHelper errOutput;
- protected List<String> args = new ArrayList<>();
- protected String[] argsArr;
-
- protected GenericArgs() {
- set(Expect.SUCCESS);
- }
-
- public T set(Expect whatToExpt) {
- currentParams.add(AcceptedParams.EXPECT);
- this.whatToExpect = whatToExpt;
- return (T)this;
- }
-
- public T setStdOutput(List<String> stdOutput) {
- currentParams.add(AcceptedParams.STD_OUTPUT);
- this.stdOutput = WriterHelperFactory.make(stdOutput, OutputKind.STD);
- return (T)this;
- }
-
- public T setStdOutput(File output) {
- currentParams.add(AcceptedParams.STD_OUTPUT);
- this.stdOutput = WriterHelperFactory.make(output, OutputKind.STD);
- return (T)this;
- }
-
- public T setErrOutput(List<String> errOutput) {
- currentParams.add(AcceptedParams.ERR_OUTPUT);
- this.errOutput = WriterHelperFactory.make(errOutput, OutputKind.ERR);
- return (T)this;
- }
-
- public T setErrOutput(File errOutput) {
- currentParams.add(AcceptedParams.ERR_OUTPUT);
- this.errOutput = WriterHelperFactory.make(errOutput, OutputKind.ERR);
- return (T)this;
- }
-
- public T setAllArgs(String... args) {
- currentParams.add(AcceptedParams.OPTIONS);
- this.argsArr = args;
- return (T) this;
- }
-
-
- public T appendArgs(String... args) {
- appendArgs(Arrays.asList(args));
- return (T)this;
- }
-
- public T appendArgs(Path... args) {
- if (args != null) {
- List<String> list = new ArrayList<>();
- for (int i = 0; i < args.length; i++) {
- if (args[i] != null) {
- list.add(args[i].toString());
- }
- }
- appendArgs(list);
- }
- return (T)this;
- }
-
- public T appendArgs(List<String> args) {
- if (args != null && args.size() > 0) {
- currentParams.add(AcceptedParams.OPTIONS);
- for (int i = 0; i < args.size(); i++) {
- if (args.get(i) != null) {
- this.args.add(args.get(i));
- }
- }
- }
- return (T)this;
- }
-
- public T setOptions(List<String> options) {
- currentParams.add(AcceptedParams.OPTIONS);
- this.args = options;
- return (T)this;
- }
-
- public T setOptions(String... options) {
- currentParams.add(AcceptedParams.OPTIONS);
- this.args = Arrays.asList(options);
- return (T)this;
- }
-
- public boolean hasMinParams() {
- for (Set<AcceptedParams> minSet : minAcceptedParams) {
- if (currentParams.containsAll(minSet)) {
- return true;
- }
- }
- return false;
- }
- }
-
- /**
- * A more specific class for holding javac-like command's arguments.
- */
- public static class JavaToolArgs extends GenericArgs<JavaToolArgs> {
-
- static {
- minAcceptedParams = new ArrayList<>();
- minAcceptedParams.add(EnumSet.<AcceptedParams>of(
- AcceptedParams.EXPECT, AcceptedParams.OPTIONS));
- minAcceptedParams.add(EnumSet.<AcceptedParams>of(
- AcceptedParams.EXPECT, AcceptedParams.SOURCES));
- }
-
- protected List<? extends JavaFileObject> sources;
-
- public JavaToolArgs() {
- super();
- }
-
- public JavaToolArgs(Expect whatToExpt) {
- super.set(whatToExpt);
- }
-
- public JavaToolArgs setSources(List<? extends JavaFileObject> sources) {
- currentParams.add(AcceptedParams.SOURCES);
- this.sources = sources;
- return this;
- }
-
- public JavaToolArgs setSources(JavaSource... sources) {
- return setSources(Arrays.asList(sources));
- }
-
- public JavaToolArgs setSources(String... sources) {
- List<JavaSource> javaSrcs = new ArrayList<>();
- for (String source : sources) {
- javaSrcs.add(new JavaSource(source));
- }
- return setSources(javaSrcs);
- }
- }
-
- /**
- * A more specific class for holding any command's arguments.
- */
- public static class AnyToolArgs extends GenericArgs<AnyToolArgs> {
-
- static {
- minAcceptedParams = new ArrayList<>();
- minAcceptedParams.add(EnumSet.<AcceptedParams>of(
- AcceptedParams.EXPECT, AcceptedParams.OPTIONS));
- }
-
- Map<String, String> extraEnv;
-
- public AnyToolArgs() {
- super();
- }
-
- public AnyToolArgs(Expect whatToExpt) {
- set(whatToExpt);
- }
-
- public AnyToolArgs set(Map<String, String> extraEnv) {
- currentParams.add(AcceptedParams.EXTRA_ENV);
- this.extraEnv = extraEnv;
- return this;
- }
- }
-
- /**
- * Custom exception for bad command execution.
- */
- public static class CommandExecutionException extends Exception {
- CommandExecutionException(List<String> command, Expect whatToExpt) {
- super(createMessage(command, whatToExpt));
- }
-
- CommandExecutionException(Expect whatToExpt, String... command) {
- this(Arrays.asList(command), whatToExpt);
- }
-
- private static String createMessage(List<String> command, Expect whatToExpt) {
- StringBuilder sb = new StringBuilder().append("Command : ");
- sb.append(command.toString()).append(lineSeparator);
- switch (whatToExpt) {
- case SUCCESS:
- sb.append(" has unexpectedly failed");
- break;
- case FAIL:
- sb.append(" has been unexpectedly successful");
- break;
- }
- return sb.toString();
- }
- }
-
- /**
- * Custom exception for not equal resources.
- */
- public static class ResourcesNotEqualException extends Exception {
- public ResourcesNotEqualException(List<String> res1, List<String> res2) {
- super(createMessage(res1, res2));
- }
-
- public ResourcesNotEqualException(String line1, String line2) {
- super(createMessage(line1, line2));
- }
-
- public ResourcesNotEqualException(Path path1, Path path2) {
- super(createMessage(path1, path2));
- }
-
- private static String createMessage(Path path1, Path path2) {
- return new StringBuilder()
- .append("The resources provided for comparison in paths \n")
- .append(path1.toString()).append(" and \n")
- .append(path2.toString()).append("are different").toString();
- }
-
- private static String createMessage(String line1, String line2) {
- return new StringBuilder()
- .append("The resources provided for comparison are different at lines: \n")
- .append(line1).append(" and \n")
- .append(line2).toString();
- }
-
- private static String createMessage(List<String> res1, List<String> res2) {
- return new StringBuilder()
- .append("The resources provided for comparison are different: \n")
- .append("Resource 1 is: ").append(res1).append("\n and \n")
- .append("Resource 2 is: ").append(res2).append("\n").toString();
- }
- }
-
- /**
- * A javac compiler caller method.
- */
- public static int javac(JavaToolArgs params)
- throws CommandExecutionException, IOException {
- if (params.hasMinParams()) {
- if (params.argsArr != null) {
- return genericJavaCMD(JavaCMD.JAVAC, params);
- } else {
- return genericJavaCMD(JavaCMD.JAVAC_API, params);
- }
- }
- throw new AssertionError("javac command has been invoked with less parameters than needed");
- }
-
- /**
- * Run javac and return the resulting classfiles.
- */
- public static Map<String, byte[]> compile(JavaToolArgs params)
- throws CommandExecutionException, IOException {
- if (params.hasMinParams()) {
- if (params.argsArr != null) {
- throw new AssertionError("setAllArgs is not supported for compile");
- }
-
- StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
- MemoryFileManager mfm = new MemoryFileManager(fm);
- StringWriter sw = null;
- boolean rc;
-
- try (PrintWriter pw = (params.errOutput == null) ?
- null : new PrintWriter(sw = new StringWriter())) {
- JavacTask ct = (JavacTask)comp.getTask(pw, mfm, null,
- params.args, null, params.sources);
- rc = ct.call();
- }
-
- String out = (sw == null) ? null : sw.toString();
-
- if (params.errOutput != null && (out != null) && !out.isEmpty()) {
- params.errOutput.addAll(splitLines(out, lineSeparator));
- }
-
- if ( ( rc && params.whatToExpect == Expect.SUCCESS) ||
- (!rc && params.whatToExpect == Expect.FAIL) ) {
- return mfm.classes;
- }
-
- throw new CommandExecutionException(JavaCMD.JAVAC_API.getExceptionMsgContent(params),
- params.whatToExpect);
- }
- throw new AssertionError("compile command has been invoked with less parameters than needed");
- }
-
- /**
- * A javap calling method.
- */
- public static String javap(JavaToolArgs params)
- throws CommandExecutionException, IOException {
- if (params.hasMinParams()) {
- List<String> list = new ArrayList<>();
- params.setErrOutput(list);
- genericJavaCMD(JavaCMD.JAVAP, params);
- return listToString(list);
- }
- throw new AssertionError("javap command has been invoked with less parameters than needed");
- }
-
- /**
- * A javah calling method.
- */
- public static int javah(JavaToolArgs params)
- throws CommandExecutionException, IOException {
- if (params.hasMinParams()) {
- return genericJavaCMD(JavaCMD.JAVAH, params);
- }
- throw new AssertionError("javah command has been invoked with less parameters than needed");
- }
-
- /**
- * A enum class for langtools commands.
- */
- enum JavaCMD {
- JAVAC {
- @Override
- int run(JavaToolArgs params, PrintWriter pw) {
- return com.sun.tools.javac.Main.compile(params.argsArr, pw);
- }
- },
- JAVAC_API {
- @Override
- int run(JavaToolArgs params, PrintWriter pw) {
- JavacTask ct = (JavacTask)comp.getTask(pw, null, null,
- params.args, null, params.sources);
- return ((JavacTaskImpl)ct).doCall().exitCode;
- }
-
- @Override
- String getName() {
- return "javac";
- }
-
- @Override
- List<String> getExceptionMsgContent(JavaToolArgs params) {
- List<String> result = super.getExceptionMsgContent(params);
- for (JavaFileObject source : params.sources) {
- if (source instanceof JavaSource) {
- result.add(((JavaSource)source).name);
- }
- }
- return result;
- }
- },
- JAVAH {
- @Override
- int run(JavaToolArgs params, PrintWriter pw) {
- return com.sun.tools.javah.Main.run(params.argsArr, pw);
- }
- },
- JAVAP {
- @Override
- int run(JavaToolArgs params, PrintWriter pw) {
- return com.sun.tools.javap.Main.run(params.argsArr, pw);
- }
- };
-
- abstract int run(JavaToolArgs params, PrintWriter pw);
-
- String getName() {
- return this.name().toLowerCase();
- }
-
- List<String> getExceptionMsgContent(JavaToolArgs params) {
- List<String> result = new ArrayList<>();
- result.add(getName());
- result.addAll(params.argsArr != null ?
- Arrays.asList(params.argsArr) :
- params.args);
- return result;
- }
- }
-
- /**
- * A helper method for executing langtools commands.
- */
- private static int genericJavaCMD(
- JavaCMD cmd,
- JavaToolArgs params)
- throws CommandExecutionException, IOException {
- int rc = 0;
- StringWriter sw = null;
- try (PrintWriter pw = (params.errOutput == null) ?
- null : new PrintWriter(sw = new StringWriter())) {
- rc = cmd.run(params, pw);
- }
- String out = (sw == null) ? null : sw.toString();
-
- if (params.errOutput != null && (out != null) && !out.isEmpty()) {
- params.errOutput.addAll(splitLines(out, lineSeparator));
- }
-
- if ( (rc == 0 && params.whatToExpect == Expect.SUCCESS) ||
- (rc != 0 && params.whatToExpect == Expect.FAIL) ) {
- return rc;
- }
-
- throw new CommandExecutionException(cmd.getExceptionMsgContent(params),
- params.whatToExpect);
- }
-
- /**
- * A jar calling method.
- */
- public static boolean jar(String... params) throws CommandExecutionException {
- Main jarGenerator = new Main(System.out, System.err, "jar");
- boolean result = jarGenerator.run(params);
- if (!result) {
- List<String> command = new ArrayList<>();
- command.add("jar");
- command.addAll(Arrays.asList(params));
- throw new CommandExecutionException(command, Expect.SUCCESS);
- }
- return result;
- }
-
- /**
- * A general command calling method.
- */
- public static int executeCommand(AnyToolArgs params)
- throws CommandExecutionException, IOException, InterruptedException {
- if (params.hasMinParams()) {
- List<String> cmd = (params.args != null) ?
- params.args :
- Arrays.asList(params.argsArr);
- return executeCommand(cmd, params.extraEnv, params.stdOutput,
- params.errOutput, params.whatToExpect);
- }
- throw new AssertionError("command has been invoked with less parameters than needed");
- }
-
- /**
- * A helper method for calling a general command.
- */
- private static int executeCommand(
- List<String> command,
- Map<String, String> extraEnv,
- WriterHelper stdOutput,
- WriterHelper errOutput,
- Expect whatToExpt)
- throws IOException, InterruptedException, CommandExecutionException {
- ProcessBuilder pb = new ProcessBuilder(command);
-
- if (stdOutput != null) stdOutput.pipeOutput(pb);
- if (errOutput != null) errOutput.pipeOutput(pb);
-
- if (extraEnv != null) {
- pb.environment().putAll(extraEnv);
- }
-
- Process p = pb.start();
-
- if (stdOutput != null) stdOutput.readFromStream(p);
- if (errOutput != null) errOutput.readFromStream(p);
-
- int result = p.waitFor();
- if ( (result == 0 && whatToExpt == Expect.SUCCESS) ||
- (result != 0 && whatToExpt == Expect.FAIL) ) {
- return result;
- }
-
- throw new CommandExecutionException(command, whatToExpt);
- }
-
- /**
- * This set of methods can be used instead of diff when the only needed
- * result is the equality or inequality of the two given resources.
- *
- * A resource can be a file or a String list.
- */
- public static void compareLines(Path aPath, Path otherPath, String encoding)
- throws FileNotFoundException, IOException, ResourcesNotEqualException {
- compareLines(aPath, otherPath, encoding, false);
- }
-
- public static void compareLines(
- Path aPath, Path otherPath, String encoding, boolean trim)
- throws FileNotFoundException, IOException, ResourcesNotEqualException {
- Charset charset = encoding != null ?
- Charset.forName(encoding) :
- defaultCharset;
- List<String> list1 = Files.readAllLines(aPath, charset);
- List<String> list2 = Files.readAllLines(otherPath, charset);
- compareLines(list1, list2, trim);
- }
-
- public static void compareLines(Path path, List<String> strings, String encoding)
- throws FileNotFoundException, IOException, ResourcesNotEqualException {
- compareLines(path, strings, encoding, false);
- }
-
- public static void compareLines(Path path, List<String> strings,
- String encoding, boolean trim)
- throws FileNotFoundException, IOException, ResourcesNotEqualException {
- Charset charset = encoding != null ?
- Charset.forName(encoding) :
- defaultCharset;
- List<String> list = Files.readAllLines(path, charset);
- compareLines(list, strings, trim);
- }
-
- public static void compareLines(List<String> list1, List<String> list2)
- throws ResourcesNotEqualException {
- compareLines(list1, list2, false);
- }
-
- public static void compareLines(List<String> list1,
- List<String> list2, boolean trim) throws ResourcesNotEqualException {
- if ((list1 == list2) || (list1 == null && list2 == null)) return;
- if (list1.size() != list2.size())
- throw new ResourcesNotEqualException(list1, list2);
- int i = 0;
- int j = 0;
- while (i < list1.size() &&
- j < list2.size() &&
- equals(list1.get(i), list2.get(j), trim)) {
- i++; j++;
- }
- if (!(i == list1.size() && j == list2.size()))
- throw new ResourcesNotEqualException(list1, list2);
- }
-
- private static boolean equals(String s1, String s2, boolean trim) {
- return (trim ? s1.trim().equals(s2.trim()) : s1.equals(s2));
- }
-
- /**
- * A set of simple grep-like methods, looks for regExpr in text.
- * The content of text is split using the new line character as a pattern
- * and later the regExpr is seek in every split line. If a match is found,
- * the whole line is added to the result.
- */
- public static List<String> grep(String regExpr, String text, String sep) {
- return grep(regExpr, splitLines(text, sep));
- }
-
- public static List<String> grep(String regExpr, List<String> text) {
- List<String> result = new ArrayList<>();
- Pattern pattern = Pattern.compile(regExpr);
- for (String s : text) {
- if (pattern.matcher(s).find()) {
- result.add(s);
- }
- }
- return result;
- }
-
- public static List<String> grep(String regExpr, File f)
- throws IOException {
- List<String> lines = Files.readAllLines(f.toPath(), defaultCharset);
- return grep(regExpr, lines);
- }
-
- /**
- * A touch-like method.
- */
- public static boolean touch(String fileName) {
- File file = new File(fileName);
- return touch(file);
- }
-
- public static boolean touch(File file) {
- if (file.exists()) {
- file.setLastModified(System.currentTimeMillis());
- return true;
- }
- return false;
- }
-
- public static void createJavaFile(File outFile) throws IOException {
- createJavaFile(outFile, null);
- }
-
- /**
- * A method for creating a valid but very simple java file.
- */
- public static void createJavaFile(File outFile, File superClass)
- throws IOException {
- String srcStr = "public class " + getSimpleName(outFile) + " ";
- if (superClass != null) {
- srcStr = srcStr.concat("extends " + getSimpleName(superClass) + " ");
- }
- srcStr = srcStr.concat("{}");
- try (PrintWriter ps = new PrintWriter(new FileWriter(outFile))) {
- ps.println(srcStr);
- }
- }
-
- /**
- * Creates a java file name given its source.
- * The file is created in the working directory, creating a directory
- * tree if there is a package declaration.
- */
- public static void createJavaFileFromSource(String source) throws IOException {
- createJavaFileFromSource(null, source);
- }
-
- /**
- * Creates a java file name given its source.
- * The file is created in the working directory, creating a directory
- * tree if there is a package declaration or the argument initialPath
- * has a valid path.
- *
- * e.i. if initialPath is foo/ and the source is:
- * package bar;
- *
- * public class bazz {}
- *
- * this method will create the file foo/bar/bazz.java in the working
- * directory.
- */
- public static void createJavaFileFromSource(Path initialPath,
- String source) throws IOException {
- String fileName = getJavaFileNameFromSource(source);
- String dirTree = getDirTreeFromSource(source);
- Path path = (dirTree != null) ?
- Paths.get(dirTree, fileName) :
- Paths.get(fileName);
- path = (initialPath != null) ?
- initialPath.resolve(path):
- path;
- writeFile(path, source);
- }
-
- static Pattern publicClassPattern =
- Pattern.compile("public\\s+(?:class|enum|interface){1}\\s+(\\w+)");
- static Pattern packageClassPattern =
- Pattern.compile("(?:class|enum|interface){1}\\s+(\\w+)");
-
- /**
- * Extracts the java file name from the class declaration.
- * This method is intended for simple files and uses regular expressions,
- * so comments matching the pattern can make the method fail.
- */
- static String getJavaFileNameFromSource(String source) {
- String className = null;
- Matcher matcher = publicClassPattern.matcher(source);
- if (matcher.find()) {
- className = matcher.group(1) + ".java";
- } else {
- matcher = packageClassPattern.matcher(source);
- if (matcher.find()) {
- className = matcher.group(1) + ".java";
- } else {
- throw new AssertionError("Could not extract the java class " +
- "name from the provided source");
- }
- }
- return className;
- }
-
- static Pattern packagePattern =
- Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))");
-
- /**
- * Extracts the path from the package declaration if present.
- * This method is intended for simple files and uses regular expressions,
- * so comments matching the pattern can make the method fail.
- */
- private static String getDirTreeFromSource(String source) {
- Matcher matcher = packagePattern.matcher(source);
- return matcher.find() ?
- matcher.group(1).replace(".", File.separator) :
- null;
- }
-
- /**
- * A method for creating a jar's manifest file with supplied data.
- */
- public static void mkManifestWithClassPath(String mainClass,
- String... classes) throws IOException {
- List <String> lines = new ArrayList<>();
-
- StringBuilder sb = new StringBuilder("Class-Path: ".length() +
- classes[0].length()).append("Class-Path: ").append(classes[0]);
- for (int i = 1; i < classes.length; i++) {
- sb.append(" ").append(classes[i]);
- }
- lines.add(sb.toString());
- if (mainClass != null) {
- lines.add(new StringBuilder("Main-Class: ".length() +
- mainClass.length())
- .append("Main-Class: ")
- .append(mainClass).toString());
- }
- Files.write(Paths.get("MANIFEST.MF"), lines,
- StandardOpenOption.CREATE, StandardOpenOption.WRITE,
- StandardOpenOption.TRUNCATE_EXISTING);
- }
-
- /**
- * A utility method to obtain the file name.
- */
- static String getSimpleName(File inFile) {
- return inFile.toPath().getFileName().toString();
- }
-
- /**
- * A method to write to a file, the directory tree is created if needed.
- */
- public static File writeFile(Path path, String body) throws IOException {
- File result;
- if (path.getParent() != null) {
- Files.createDirectories(path.getParent());
- }
- try (FileWriter out = new FileWriter(result = path.toAbsolutePath().toFile())) {
- out.write(body);
- }
- return result;
- }
-
- public static File writeFile(String path, String body) throws IOException {
- return writeFile(Paths.get(path), body);
- }
-
- /**
- * A rm-like method, the file is deleted only if it exists.
- */
- public static void rm(Path path) throws Exception {
- Files.deleteIfExists(path);
- }
-
- public static void rm(String filename) throws Exception {
- rm(Paths.get(filename));
- }
-
- public static void rm(File f) throws Exception {
- rm(f.toPath());
- }
-
- /**
- * Copy source file to destination file.
- */
- public static void copyFile(File destfile, File srcfile)
- throws IOException {
- copyFile(destfile.toPath(), srcfile.toPath());
- }
-
- public static void copyFile(Path destPath, Path srcPath)
- throws IOException {
- Files.createDirectories(destPath);
- Files.copy(srcPath, destPath, REPLACE_EXISTING);
- }
-
- /**
- * Splits a String using the System's line separator character as splitting point.
- */
- public static List<String> splitLines(String lines, String sep) {
- return Arrays.asList(lines.split(sep));
- }
-
- /**
- * Converts a String list into one String by appending the System's line separator
- * character after each component.
- */
- private static String listToString(List<String> lines) {
- StringBuilder sb = new StringBuilder();
- for (String s : lines) {
- sb.append(s).append(lineSeparator);
- }
- return sb.toString();
- }
-
- /**
- * Returns true if the OS is a Windows version.
- */
- public static boolean isWindows() {
- String osName = System.getProperty("os.name");
- return osName.toUpperCase().startsWith("WINDOWS");
- }
-
- /**
- * Class representing an in-memory java source file. It is able to extract
- * the file name from simple source codes using regular expressions.
- */
- public static class JavaSource extends SimpleJavaFileObject {
- String source;
- String name;
-
- public JavaSource(String className, String source) {
- super(URI.create(className),
- JavaFileObject.Kind.SOURCE);
- this.name = className;
- this.source = source;
- }
-
- public JavaSource(String source) {
- super(URI.create(getJavaFileNameFromSource(source)),
- JavaFileObject.Kind.SOURCE);
- this.name = getJavaFileNameFromSource(source);
- this.source = source;
- }
-
- @Override
- public CharSequence getCharContent(boolean ignoreEncodingErrors) {
- return source;
- }
- }
-
- /**
- * A file manager for compiling strings to byte arrays.
- * This file manager delegates to another file manager
- * to lookup classes on boot class path.
- */
- public static final class MemoryFileManager extends ForwardingJavaFileManager {
- /**
- * Maps binary class names to class files stored as byte arrays.
- */
- private final Map<String, byte[]> classes;
-
- /**
- * Construct a memory file manager which delegates to the specified
- * file manager for unknown sources.
- * @param fileManager a file manager used to look up class files on class path, etc.
- */
- public MemoryFileManager(JavaFileManager fileManager) {
- super(fileManager);
- classes = new HashMap<>();
- }
-
- @java.lang.Override
- public JavaFileObject getJavaFileForOutput(Location location,
- String name,
- Kind kind,
- FileObject sibling)
- throws UnsupportedOperationException
- {
- return new JavaClassInArray(name);
- }
-
- /**
- * A file object representing a Java class file stored in a byte array.
- */
- private class JavaClassInArray extends SimpleJavaFileObject {
-
- private final String name;
-
- /**
- * Constructs a JavaClassInArray object.
- * @param name binary name of the class to be stored in this file object
- */
- JavaClassInArray(String name) {
- super(URI.create("mfm:///" + name.replace('.','/') + Kind.CLASS.extension),
- Kind.CLASS);
- this.name = name;
- }
-
- public OutputStream openOutputStream() {
- return new FilterOutputStream(new ByteArrayOutputStream()) {
- public void close() throws IOException {
- out.close();
- ByteArrayOutputStream bos = (ByteArrayOutputStream)out;
- classes.put(name, bos.toByteArray());
- }
- };
- }
- }
-
- }
-
-}
--- a/langtools/test/tools/javac/links/LinksTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/links/LinksTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @bug 4266026
* @summary javac no longer follows symlinks
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main LinksTest
*/
@@ -33,7 +33,7 @@
import java.nio.file.Files;
import java.nio.file.Paths;
-//original test: test/tools/javac/links/links.sh
+// Original test: test/tools/javac/links/links.sh
public class LinksTest {
private static final String BSrc =
@@ -44,20 +44,18 @@
private static final String TSrc =
"class T extends a.B {}";
- public static void main(String args[])
- throws Exception {
-// mkdir tmp
-// cp ${TESTSRC}/b/B.java tmp
- ToolBox.writeFile(Paths.get("tmp", "B.java"), BSrc);
+ public static void main(String... args) throws Exception {
+ ToolBox tb = new ToolBox();
+ tb.writeFile("tmp/B.java", BSrc);
try {
-// ln -s `pwd`/tmp "${TESTCLASSES}/a"
Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp"));
- ////"${TESTJAVA}/bin/javac" ${TESTTOOLVMOPTS} -sourcepath "${TESTCLASSES}" -d "${TESTCLASSES}/classes" "${TESTSRC}/T.java" 2>&1
- ToolBox.JavaToolArgs javacArgs =
- new ToolBox.JavaToolArgs()
- .setOptions("-sourcepath", ".", "-d", ".").setSources(TSrc);
- ToolBox.javac(javacArgs);
+
+ tb.new JavacTask()
+ .sourcepath(".")
+ .outdir(".")
+ .sources(TSrc)
+ .run();
} catch (UnsupportedOperationException e) {
System.err.println("Symbolic links not supported on this system. The test can't finish");
}
--- a/langtools/test/tools/javac/newlines/NewLineTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/newlines/NewLineTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @bug 4110560 4785453
* @summary portability : javac.properties
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main NewLineTest
*/
@@ -39,18 +39,13 @@
public class NewLineTest {
public static void main(String args[]) throws Exception {
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -J-Dline.separator='@' > ${TMP1} 2>&1
+ ToolBox tb = new ToolBox();
File javacErrOutput = new File("output.txt");
- ToolBox.AnyToolArgs cmdArgs =
- new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
- .appendArgs(ToolBox.javacBinary)
- .appendArgs(ToolBox.testToolVMOpts)
- .appendArgs("-J-Dline.separator='@'")
- .setErrOutput(javacErrOutput);
- ToolBox.executeCommand(cmdArgs);
+ tb.new JavacTask(ToolBox.Mode.EXEC)
+ .redirect(ToolBox.OutputKind.STDERR, javacErrOutput.getPath())
+ .options("-J-Dline.separator='@'")
+ .run(ToolBox.Expect.FAIL);
-// result=`cat ${TMP1} | wc -l`
-// if [ "$result" -eq 0 ] passed
List<String> lines = Files.readAllLines(javacErrOutput.toPath(),
Charset.defaultCharset());
if (lines.size() != 1) {
--- a/langtools/test/tools/javac/processing/rounds/CompleteOnClosed.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/processing/rounds/CompleteOnClosed.java Thu Aug 28 14:53:49 2014 -0700
@@ -26,8 +26,8 @@
* @bug 8038455
* @summary Ensure that formatting diagnostics with an already closed JavaCompiler won't crash
* the compiler.
- * @library /tools/javac/lib
- * @build CompleteOnClosed ToolBox JavacTestingAbstractProcessor
+ * @library /tools/lib /tools/javac/lib
+ * @build ToolBox JavacTestingAbstractProcessor
* @run main CompleteOnClosed
*/
--- a/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java Thu Aug 28 14:53:49 2014 -0700
@@ -26,7 +26,7 @@
* @bug 8038455
* @summary Verify that annotation processor can overwrite source and class files it generated
* during previous compilations, and that the Symbols are updated appropriatelly.
- * @library /tools/javac/lib/
+ * @library /tools/lib /tools/javac/lib/
* @clean *
* @build OverwriteBetweenCompilations ToolBox JavacTestingAbstractProcessor
* @compile/ref=OverwriteBetweenCompilations_1.out -processor OverwriteBetweenCompilations -Apass=1 -parameters -XDrawDiagnostics OverwriteBetweenCompilationsSource.java
@@ -49,6 +49,7 @@
@SupportedOptions("pass")
public class OverwriteBetweenCompilations extends JavacTestingAbstractProcessor {
int round = 1;
+ @Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
Log log = Log.instance(((JavacProcessingEnvironment) processingEnv).getContext());
@@ -85,11 +86,17 @@
try (OutputStream out = filer.createClassFile("GeneratedClass").openOutputStream()) {
String code = pass != 2 ? GENERATED_INIT : GENERATED_UPDATE;
code = code.replace("NAME", "GeneratedClass");
- ToolBox.JavaToolArgs args =
- new ToolBox.JavaToolArgs().appendArgs("-parameters").setSources(code);
- Map<String, byte[]> codeMap = ToolBox.compile(args);
- out.write(codeMap.get("GeneratedClass"));
- } catch (IOException | ToolBox.CommandExecutionException e) {
+
+ ToolBox tb = new ToolBox();
+ ToolBox.MemoryFileManager mfm = new ToolBox.MemoryFileManager();
+ tb.new JavacTask()
+ .fileManager(mfm)
+ .options("-parameters")
+ .sources(code)
+ .run();
+
+ out.write(mfm.getFileBytes(StandardLocation.CLASS_OUTPUT, "GeneratedClass"));
+ } catch (IOException e) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.toString());
}
}
--- a/langtools/test/tools/javac/stackmap/StackMapTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/stackmap/StackMapTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @bug 4955930
* @summary The "method0" StackMap attribute should have two entries instead of three
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run compile StackMapTest.java
* @run main StackMapTest
@@ -34,7 +34,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
-//original test: test/tools/javac/stackmap/T4955930.sh
+// Original test: test/tools/javac/stackmap/T4955930.sh
public class StackMapTest {
class Test {
@@ -48,16 +48,15 @@
}
public static void main(String args[]) throws Exception {
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} T4955930.java
+ ToolBox tb = new ToolBox();
+ Path pathToClass = Paths.get(ToolBox.testClasses, "StackMapTest$Test.class");
+ String javapOut = tb.new JavapTask()
+ .options("-v")
+ .classes(pathToClass.toString())
+ .run()
+ .getOutput(ToolBox.OutputKind.DIRECT);
-// "${TESTJAVA}${FS}bin${FS}javap" ${TESTTOOLVMOPTS} -verbose T4955930 > ${TMP1}
- Path pathToClass = Paths.get(System.getProperty("test.classes"),
- "StackMapTest$Test.class");
- ToolBox.JavaToolArgs javapArgs =
- new ToolBox.JavaToolArgs().setAllArgs("-v", pathToClass.toString());
-
-// grep "StackMapTable: number_of_entries = 2" ${TMP1}
- if (!ToolBox.javap(javapArgs).contains("StackMapTable: number_of_entries = 2"))
+ if (!javapOut.contains("StackMapTable: number_of_entries = 2"))
throw new AssertionError("The number of entries of the stack map "
+ "table should be equal to 2");
}
--- a/langtools/test/tools/javah/6257087/T6257087.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javah/6257087/T6257087.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,12 @@
* @test
* @bug 6257087
* @summary javah doesn't produce proper signatures for inner class native methods
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main T6257087
*/
-import java.nio.file.Paths;
+import java.util.List;
public class T6257087 {
@@ -58,13 +58,14 @@
"#endif";
public static void main(String[] args) throws Exception {
- ToolBox.JavaToolArgs javahArgs =
- new ToolBox.JavaToolArgs()
- .setAllArgs("-cp", System.getProperty("test.classes"), "foo");
- ToolBox.javah(javahArgs);
+ ToolBox tb = new ToolBox();
+ tb.new JavahTask()
+ .classpath(ToolBox.testClasses)
+ .classes("foo")
+ .run();
- ToolBox.compareLines(Paths.get("foo_bar.h"),
- ToolBox.splitLines(fooBarGoldenFile, "\n"), null, true);
+ List<String> fooBarFile = tb.readAllLines("foo_bar.h");
+ tb.checkEqual(fooBarFile, tb.split(fooBarGoldenFile, "\n"));
}
}
--- a/langtools/test/tools/javah/T4942232/MissingParamClassTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javah/T4942232/MissingParamClassTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @summary Verifies that javah won't attempt to generate a header file if a
* native method in a supplied class contains a parameter type whose corresponding
* class is missing or not in the classpath
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run compile MissingParamClassTest.java
* @clean MissingParamClassException
@@ -39,32 +39,21 @@
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-//original test: test/tools/javah/MissingParamClassTest.sh
+// Original test: test/tools/javah/MissingParamClassTest.sh
public class MissingParamClassTest {
public static void main(String[] args) throws Exception {
- //first steps done now by jtreg
-//"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . "${TESTSRC}${FS}ParamClassTest.java" "${TESTSRC}${FS}MissingParamClassException.java"
-//rm -f MissingParamClassException.class
+ ToolBox tb = new ToolBox();
-//"${TESTJAVA}${FS}bin${FS}javah" ${TESTTOOLVMOPTS} ParamClassTest 2>${TMP1}
- List<String> errOutput = new ArrayList<>();
- ToolBox.JavaToolArgs javahParams =
- new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
- .setAllArgs("-classpath", System.getProperty("test.classes"), "ParamClassTest")
- .setErrOutput(errOutput);
- ToolBox.javah(javahParams);
+ String out = tb.new JavahTask()
+ .classpath(ToolBox.testClasses)
+ .classes("ParamClassTest")
+ .run(ToolBox.Expect.FAIL)
+ .getOutput(ToolBox.OutputKind.DIRECT);
-//if [ -f $GENERATED_HEADER_FILE ]; then fail
-//if [ ! -s ${TMP1} ]; then fail
- if (Files.exists(Paths.get("ParamClassTest.h")) || errOutput.size() == 0)
+ if (Files.exists(Paths.get("ParamClassTest.h")) || out.isEmpty())
throw new AssertionError("The only output generated by javah must be an error message");
- //jtreg again
-//rm -f MissingParamClassException.class ParamClassTest.class
-//rm -f $GENERATED_HEADER_FILE $TMP1
}
}
--- a/langtools/test/tools/javah/constMacroTest/ConstMacroTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javah/constMacroTest/ConstMacroTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,15 +27,15 @@
* @summary Validates rewritten javah handling of class defined constants and
* ensures that the appropriate macro definitions are placed in the generated
* header file.
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main ConstMacroTest
*/
import java.io.*;
-import java.nio.file.Paths;
+import java.util.List;
-//original test: test/tools/javah/ConstMacroTest.sh
+// Original test: test/tools/javah/ConstMacroTest.sh
public class ConstMacroTest {
private static final String subClassConstsGoldenFileTemplate =
@@ -71,27 +71,21 @@
"#endif\n" +
"#endif";
- private static final String serialVersionUIDSuffix =
- ToolBox.isWindows() ? "i64" : "LL"; ;
+ public static void main(String[] args) throws Exception {
+ ToolBox tb = new ToolBox();
- public static void main(String[] args) throws Exception {
- //first steps are now done by jtreg
-// cp "${TESTSRC}${FS}SuperClassConsts.java" .
-// cp "${TESTSRC}${FS}SubClassConsts.java" .
-
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . "${TESTSRC}${FS}SubClassConsts.java"
+ tb.new JavahTask()
+ .classpath(ToolBox.testClasses)
+ .classes("SubClassConsts")
+ .run();
-// "${TESTJAVA}${FS}bin${FS}javah" ${TESTTOOLVMOPTS} SubClassConsts
- ToolBox.JavaToolArgs successParams =
- new ToolBox.JavaToolArgs()
- .setAllArgs("-cp", System.getProperty("test.classes"), "SubClassConsts");
- ToolBox.javah(successParams);
+ String longSuffix = tb.isWindows() ? "i64" : "LL";
+ List<String> subClassConstsGoldenFile = tb.split(
+ String.format(subClassConstsGoldenFileTemplate, longSuffix), "\n");
-// diff ${DIFFOPTS} "${TESTSRC}${FS}${EXPECTED_JAVAH_OUT_FILE}" "${GENERATED_HEADER_FILE}"
- String subClassConstGoldenFile = String.format(subClassConstsGoldenFileTemplate,
- serialVersionUIDSuffix);
- ToolBox.compareLines(Paths.get("SubClassConsts.h"),
- ToolBox.splitLines(subClassConstGoldenFile, "\n"), null, true);
+ List<String> subClassConstsFile = tb.readAllLines("SubClassConsts.h");
+
+ tb.checkEqual(subClassConstsFile, subClassConstsGoldenFile);
}
}
--- a/langtools/test/tools/javap/4798312/JavapShouldLoadClassesFromRTJarTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javap/4798312/JavapShouldLoadClassesFromRTJarTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,19 +24,23 @@
/*
* @test
* @bug 4798312
- * @summary In Windows, javap doesnt load classes from rt.jar
- * @library /tools/javac/lib
+ * @summary In Windows, javap doesn't load classes from rt.jar
+ * @library /tools/lib
* @build ToolBox
* @run main JavapShouldLoadClassesFromRTJarTest
*/
+
public class JavapShouldLoadClassesFromRTJarTest {
public static void main(String[] args) throws Exception {
-// "${TESTJAVA}${FS}bin${FS}javap" ${TESTTOOLVMOPTS} java.lang.String
- ToolBox.JavaToolArgs params =
- new ToolBox.JavaToolArgs().
- setAllArgs("-v", "java.lang.String");
- if (ToolBox.javap(params).isEmpty())
+ ToolBox tb = new ToolBox();
+ String out = tb.new JavapTask()
+ .options("-v")
+ .classes("java.lang.String")
+ .run()
+ .getOutput(ToolBox.OutputKind.DIRECT);
+
+ if (out.isEmpty())
throw new AssertionError("javap generated no output");
}
--- a/langtools/test/tools/javap/4866831/PublicInterfaceTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javap/4866831/PublicInterfaceTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,9 +1,5 @@
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,23 +25,29 @@
* @test
* @bug 4866831
* @summary Verify that javap marks public interfaces as public
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main PublicInterfaceTest
*/
-//original test: test/tools/javap/PublicInterfaceTest.sh
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+// Original test: test/tools/javap/PublicInterfaceTest.sh
public class PublicInterfaceTest {
public interface Test {}
public static void main(String[] args) throws Exception {
-// "$JAVAP" ${TESTTOOLVMOPTS} -classpath "${TESTCLASSES}" NotPackagePrivateInterface | grep public
- Path pathToClass = Paths.get(System.getProperty("test.classes"),
- "PublicInterfaceTest$Test.class");
- ToolBox.JavaToolArgs javapParams =
- new ToolBox.JavaToolArgs()
- .setAllArgs(pathToClass.toString());
- if (!ToolBox.javap(javapParams).contains("public"))
+ ToolBox tb = new ToolBox();
+
+ Path pathToClass = Paths.get(ToolBox.testClasses, "PublicInterfaceTest$Test.class");
+
+ String out = tb.new JavapTask()
+ .classes(pathToClass.toString())
+ .run()
+ .getOutput(ToolBox.OutputKind.DIRECT);
+
+ if (!out.contains("public"))
throw new AssertionError("The javap output does not contain \"public\"");
}
--- a/langtools/test/tools/javap/stackmap/StackmapTest.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javap/stackmap/StackmapTest.java Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,15 @@
* @test
* @bug 6271292
* @summary Verify that javap prints StackMapTable attribute contents
- * @library /tools/javac/lib
+ * @library /tools/lib
* @build ToolBox
* @run main StackmapTest
*/
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
-//original test: test/tools/javap/stackmap/T6271292.sh
+// Original test: test/tools/javap/stackmap/T6271292.sh
public class StackmapTest {
private static final String TestSrc =
@@ -58,41 +58,42 @@
"}\n";
private static final String goldenOut =
- "frame_type = 255 /* full_frame */\n" +
- "frame_type = 255 /* full_frame */\n" +
- "frame_type = 73 /* same_locals_1_stack_item */\n" +
- "frame_type = 255 /* full_frame */\n" +
- "offset_delta = 19\n" +
- "offset_delta = 0\n" +
- "offset_delta = 2\n" +
- "stack = [ uninitialized 0, uninitialized 0 ]\n" +
- "stack = [ uninitialized 0, uninitialized 0, double ]\n" +
- "stack = [ this ]\n" +
- "stack = [ this, double ]\n" +
- "locals = [ class \"[Ljava/lang/String;\" ]\n" +
- "locals = [ class \"[Ljava/lang/String;\" ]\n" +
- "locals = [ this, int ]\n";
+ " frame_type = 255 /* full_frame */\n" +
+ " frame_type = 255 /* full_frame */\n" +
+ " frame_type = 73 /* same_locals_1_stack_item */\n" +
+ " frame_type = 255 /* full_frame */\n" +
+ " offset_delta = 19\n" +
+ " offset_delta = 0\n" +
+ " offset_delta = 2\n" +
+ " stack = [ uninitialized 0, uninitialized 0 ]\n" +
+ " stack = [ uninitialized 0, uninitialized 0, double ]\n" +
+ " stack = [ this ]\n" +
+ " stack = [ this, double ]\n" +
+ " locals = [ class \"[Ljava/lang/String;\" ]\n" +
+ " locals = [ class \"[Ljava/lang/String;\" ]\n" +
+ " locals = [ this, int ]\n";
public static void main(String[] args) throws Exception {
- // @compile T6271292.java
- ToolBox.JavaToolArgs javacParams =
- new ToolBox.JavaToolArgs().setSources(TestSrc);
- ToolBox.javac(javacParams);
+ ToolBox tb = new ToolBox();
+
+ tb.new JavacTask()
+ .sources(TestSrc)
+ .run();
-// "${TESTJAVA}${FS}bin${FS}javap" ${TESTTOOLVMOPTS} -classpath "${TESTCLASSES}" -verbose T6271292 > "${JAVAPFILE}"
- ToolBox.JavaToolArgs javapParams =
- new ToolBox.JavaToolArgs()
- .setAllArgs("-v", "Test.class");
- String out = ToolBox.javap(javapParams);
- List<String> grepResult = ToolBox.grep("frame_type", out,
- ToolBox.lineSeparator);
- grepResult.addAll(ToolBox.grep("offset_delta", out, ToolBox.lineSeparator));
- grepResult.addAll(ToolBox.grep("stack = ", out, ToolBox.lineSeparator));
- grepResult.addAll(ToolBox.grep("locals = ", out, ToolBox.lineSeparator));
- List<String> goldenList = Arrays.asList(goldenOut.split("\n"));
+ List<String> out = tb.new JavapTask()
+ .options("-v")
+ .classes("Test.class")
+ .run()
+ .getOutputLines(ToolBox.OutputKind.DIRECT);
-// diff -w "${OUTFILE}" "${TESTSRC}${FS}T6271292.out"
- ToolBox.compareLines(goldenList, grepResult, true);
+ List<String> grepResult = new ArrayList<>();
+ grepResult.addAll(tb.grep("frame_type", out));
+ grepResult.addAll(tb.grep("offset_delta", out));
+ grepResult.addAll(tb.grep("stack = ", out));
+ grepResult.addAll(tb.grep("locals = ", out));
+
+ List<String> goldenList = tb.split(goldenOut, "\n");
+ tb.checkEqual(goldenList, grepResult);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/lib/ToolBox.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,1920 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FilterOutputStream;
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.api.JavacTool;
+import java.io.IOError;
+
+/**
+ * Utility methods and classes for writing jtreg tests for
+ * javac, javah, javap, and sjavac. (For javadoc support,
+ * see JavadocTester.)
+ *
+ * <p>There is support for common file operations similar to
+ * shell commands like cat, cp, diff, mv, rm, grep.
+ *
+ * <p>There is also support for invoking various tools, like
+ * javac, javah, javap, jar, java and other JDK tools.
+ *
+ * <p><em>File separators</em>: for convenience, many operations accept strings
+ * to represent filenames. On all platforms on which JDK is supported,
+ * "/" is a legal filename component separator. In particular, even
+ * on Windows, where the official file separator is "\", "/" is a legal
+ * alternative. It is therefore recommended that any client code using
+ * strings to specify filenames should use "/".
+ *
+ * @author Vicente Romero (original)
+ * @author Jonathan Gibbons (revised)
+ */
+public class ToolBox {
+ /** The platform line separator. */
+ public static final String lineSeparator = System.getProperty("line.separator");
+ /** The platform OS name. */
+ public static final String osName = System.getProperty("os.name");
+
+ /** The location of the class files for this test, or null if not set. */
+ public static final String testClasses = System.getProperty("test.classes");
+ /** The location of the source files for this test, or null if not set. */
+ public static final String testSrc = System.getProperty("test.src");
+ /** The location of the test JDK for this test, or null if not set. */
+ public static final String testJDK = System.getProperty("test.jdk");
+
+ /** The current directory. */
+ public static final Path currDir = Paths.get(".");
+
+ /** The stream used for logging output. */
+ public PrintStream out = System.err;
+
+ JavaCompiler compiler;
+ StandardJavaFileManager standardJavaFileManager;
+
+ /**
+ * Checks if the host OS is some version of Windows.
+ * @return true if the host OS is some version of Windows
+ */
+ public boolean isWindows() {
+ return osName.toLowerCase(Locale.ENGLISH).startsWith("windows");
+ }
+
+ /**
+ * Splits a string around matches of the given regular expression.
+ * If the string is empty, an empty list will be returned.
+ * @param text the string to be split
+ * @param sep the delimiting regular expression
+ * @return the strings between the separators
+ */
+ public List<String> split(String text, String sep) {
+ if (text.isEmpty())
+ return Collections.emptyList();
+ return Arrays.asList(text.split(sep));
+ }
+
+ /**
+ * Checks if two lists of strings are equal.
+ * @param l1 the first list of strings to be compared
+ * @param l2 the second list of strings to be compared
+ * @throws Error if the lists are not equal
+ */
+ public void checkEqual(List<String> l1, List<String> l2) throws Error {
+ if (!Objects.equals(l1, l2)) {
+ // l1 and l2 cannot both be null
+ if (l1 == null)
+ throw new Error("comparison failed: l1 is null");
+ if (l2 == null)
+ throw new Error("comparison failed: l2 is null");
+ // report first difference
+ for (int i = 0; i < Math.min(l1.size(), l2.size()); i++) {
+ String s1 = l1.get(i);
+ String s2 = l1.get(i);
+ if (!Objects.equals(s1, s2)) {
+ throw new Error("comparison failed, index " + i +
+ ", (" + s1 + ":" + s2 + ")");
+ }
+ }
+ throw new Error("comparison failed: l1.size=" + l1.size() + ", l2.size=" + l2.size());
+ }
+ }
+
+ /**
+ * Filters a list of strings according to the given regular expression.
+ * @param regex the regular expression
+ * @param lines the strings to be filtered
+ * @return the strings matching the regular expression
+ */
+ public List<String> grep(String regex, List<String> lines) {
+ return grep(Pattern.compile(regex), lines);
+ }
+
+ /**
+ * Filters a list of strings according to the given regular expression.
+ * @param pattern the regular expression
+ * @param lines the strings to be filtered
+ * @return the strings matching the regular expression
+ */
+ public List<String> grep(Pattern pattern, List<String> lines) {
+ return lines.stream()
+ .filter(s -> pattern.matcher(s).find())
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Copies a file.
+ * If the given destination exists and is a directory, the copy is created
+ * in that directory. Otherwise, the copy will be placed at the destination,
+ * possibly overwriting any existing file.
+ * <p>Similar to the shell "cp" command: {@code cp from to}.
+ * @param from the file to be copied
+ * @param to where to copy the file
+ * @throws IOException if any error occurred while copying the file
+ */
+ public void copyFile(String from, String to) throws IOException {
+ copyFile(Paths.get(from), Paths.get(to));
+ }
+
+ /**
+ * Copies a file.
+ * If the given destination exists and is a directory, the copy is created
+ * in that directory. Otherwise, the copy will be placed at the destination,
+ * possibly overwriting any existing file.
+ * <p>Similar to the shell "cp" command: {@code cp from to}.
+ * @param from the file to be copied
+ * @param to where to copy the file
+ * @throws IOException if an error occurred while copying the file
+ */
+ public void copyFile(Path from, Path to) throws IOException {
+ if (Files.isDirectory(to)) {
+ to = to.resolve(from.getFileName());
+ } else {
+ Files.createDirectories(to.getParent());
+ }
+ Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ /**
+ * Creates one of more directories.
+ * For each of the series of paths, a directory will be created,
+ * including any necessary parent directories.
+ * <p>Similar to the shell command: {@code mkdir -p paths}.
+ * @param paths the directories to be created
+ * @throws IOException if an error occurred while creating the directories
+ */
+ public void createDirectories(String... paths) throws IOException {
+ if (paths.length == 0)
+ throw new IllegalArgumentException("no directories specified");
+ for (String p: paths)
+ Files.createDirectories(Paths.get(p));
+ }
+
+ /**
+ * Creates one or more directories.
+ * For each of the series of paths, a directory will be created,
+ * including any necessary parent directories.
+ * <p>Similar to the shell command: {@code mkdir -p paths}.
+ * @param paths the directories to be created
+ * @throws IOException if an error occurred while creating the directories
+ */
+ public void createDirectories(Path... paths) throws IOException {
+ if (paths.length == 0)
+ throw new IllegalArgumentException("no directories specified");
+ for (Path p: paths)
+ Files.createDirectories(p);
+ }
+
+ /**
+ * Deletes one or more files.
+ * Any directories to be deleted must be empty.
+ * <p>Similar to the shell command: {@code rm files}.
+ * @param files the files to be deleted
+ * @throws IOException if an error occurred while deleting the files
+ */
+ public void deleteFiles(String... files) throws IOException {
+ if (files.length == 0)
+ throw new IllegalArgumentException("no files specified");
+ for (String file: files)
+ Files.delete(Paths.get(file));
+ }
+
+ /**
+ * Moves a file.
+ * If the given destination exists and is a directory, the file will be moved
+ * to that directory. Otherwise, the file will be moved to the destination,
+ * possibly overwriting any existing file.
+ * <p>Similar to the shell "mv" command: {@code mv from to}.
+ * @param from the file to be moved
+ * @param to where to move the file
+ * @throws IOException if an error occurred while moving the file
+ */
+ public void moveFile(String from, String to) throws IOException {
+ moveFile(Paths.get(from), Paths.get(to));
+ }
+
+ /**
+ * Moves a file.
+ * If the given destination exists and is a directory, the file will be moved
+ * to that directory. Otherwise, the file will be moved to the destination,
+ * possibly overwriting any existing file.
+ * <p>Similar to the shell "mv" command: {@code mv from to}.
+ * @param from the file to be moved
+ * @param to where to move the file
+ * @throws IOException if an error occurred while moving the file
+ */
+ public void moveFile(Path from, Path to) throws IOException {
+ if (Files.isDirectory(to)) {
+ to = to.resolve(from.getFileName());
+ } else {
+ Files.createDirectories(to.getParent());
+ }
+ Files.move(from, to, StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ /**
+ * Reads the lines of a file.
+ * The file is read using the default character encoding.
+ * @param path the file to be read
+ * @return the lines of the file.
+ * @throws IOException if an error occurred while reading the file
+ */
+ public List<String> readAllLines(String path) throws IOException {
+ return readAllLines(path, null);
+ }
+
+ /**
+ * Reads the lines of a file.
+ * The file is read using the default character encoding.
+ * @param path the file to be read
+ * @return the lines of the file.
+ * @throws IOException if an error occurred while reading the file
+ */
+ public List<String> readAllLines(Path path) throws IOException {
+ return readAllLines(path, null);
+ }
+
+ /**
+ * Reads the lines of a file using the given encoding.
+ * @param path the file to be read
+ * @param encoding the encoding to be used to read the file
+ * @return the lines of the file.
+ * @throws IOException if an error occurred while reading the file
+ */
+ public List<String> readAllLines(String path, String encoding) throws IOException {
+ return readAllLines(Paths.get(path), encoding);
+ }
+
+ /**
+ * Reads the lines of a file using the given encoding.
+ * @param path the file to be read
+ * @param encoding the encoding to be used to read the file
+ * @return the lines of the file.
+ * @throws IOException if an error occurred while reading the file
+ */
+ public List<String> readAllLines(Path path, String encoding) throws IOException {
+ return Files.readAllLines(path, getCharset(encoding));
+ }
+
+ private Charset getCharset(String encoding) {
+ return (encoding == null) ? Charset.defaultCharset() : Charset.forName(encoding);
+ }
+
+ /**
+ * Writes a file containing the given content.
+ * Any necessary directories for the file will be created.
+ * @param path where to write the file
+ * @param content the content for the file
+ * @throws IOException if an error occurred while writing the file
+ */
+ public void writeFile(String path, String content) throws IOException {
+ writeFile(Paths.get(path), content);
+ }
+
+ /**
+ * Writes a file containing the given content.
+ * Any necessary directories for the file will be created.
+ * @param path where to write the file
+ * @param content the content for the file
+ * @throws IOException if an error occurred while writing the file
+ */
+ public void writeFile(Path path, String content) throws IOException {
+ Path dir = path.getParent();
+ if (dir != null)
+ Files.createDirectories(dir);
+ try (BufferedWriter w = Files.newBufferedWriter(path)) {
+ w.write(content);
+ }
+ }
+
+ /**
+ * Writes one or more files containing Java source code.
+ * For each file to be written, the filename will be inferred from the
+ * given base directory, the package declaration (if present) and from the
+ * the name of the first class, interface or enum declared in the file.
+ * <p>For example, if the base directory is /my/dir/ and the content
+ * contains "package p; class C { }", the file will be written to
+ * /my/dir/p/C.java.
+ * <p>Note: the content is analyzed using regular expressions;
+ * errors can occur if any contents have initial comments that might trip
+ * up the analysis.
+ * @param dir the base directory
+ * @param contents the contents of the files to be written
+ * @throws IOException if an error occurred while writing any of the files.
+ */
+ public void writeJavaFiles(Path dir, String... contents) throws IOException {
+ if (contents.length == 0)
+ throw new IllegalArgumentException("no content specified for any files");
+ for (String c: contents) {
+ new JavaSource(c).write(dir);
+ }
+ }
+
+ /**
+ * Returns the path for the binary of a JDK tool within {@link testJDK}.
+ * @param tool the name of the tool
+ * @return the path of the tool
+ */
+ public Path getJDKTool(String tool) {
+ return Paths.get(testJDK, "bin", tool);
+ }
+
+ /**
+ * Returns a string representing the contents of an {@code Iterable} as a list.
+ * @param <T> the type parameter of the {@code Iterable}
+ * @param items the iterable
+ * @return the string
+ */
+ <T> String toString(Iterable<T> items) {
+ return StreamSupport.stream(items.spliterator(), false)
+ .map(Objects::toString)
+ .collect(Collectors.joining(",", "[", "]"));
+ }
+
+ /**
+ * The supertype for tasks.
+ * Complex operations are modelled by building and running a "Task" object.
+ * Tasks are typically configured in a fluent series of calls.
+ */
+ public interface Task {
+ /**
+ * Returns the name of the task.
+ * @return the name of the task
+ */
+ String name();
+
+ /**
+ * Executes the task as currently configured.
+ * @return a Result object containing the results of running the task
+ * @throws TaskError if the outcome of the task was not as expected
+ */
+ Result run() throws TaskError;
+ }
+
+ /**
+ * Exception thrown by {@code Task.run} when the outcome is not as
+ * expected.
+ */
+ public static class TaskError extends Error {
+ /**
+ * Creates a TaskError object with the given message.
+ * @param message the message
+ */
+ public TaskError(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * An enum to indicate the mode a task should use it is when executed.
+ */
+ public enum Mode {
+ /**
+ * The task should use the interface used by the command
+ * line launcher for the task.
+ * For example, for javac: com.sun.tools.javac.Main.compile
+ */
+ CMDLINE,
+ /**
+ * The task should use a publicly defined API for the task.
+ * For example, for javac: javax.tools.JavaCompiler
+ */
+ API,
+ /**
+ * The task should use the standard launcher for the task.
+ * For example, $JAVA_HOME/bin/javac
+ */
+ EXEC
+ }
+
+ /**
+ * An enum to indicate the expected success or failure of executing a task.
+ */
+ public enum Expect {
+ /** It is expected that the task will complete successfully. */
+ SUCCESS,
+ /** It is expected that the task will not complete successfully. */
+ FAIL
+ }
+
+ /**
+ * An enum to identify the streams that may be written by a {@code Task}.
+ */
+ public enum OutputKind {
+ /** Identifies output written to {@code System.out} or {@code stdout}. */
+ STDOUT,
+ /** Identifies output written to {@code System.err} or {@code stderr}. */
+ STDERR,
+ /** Identifies output written to a stream provided directly to the task. */
+ DIRECT
+ };
+
+ /**
+ * The results from running a {@link Task}.
+ * The results contain the exit code returned when the tool was invoked,
+ * and a map containing the output written to any streams during the
+ * execution of the tool.
+ * All tools support "stdout" and "stderr".
+ * Tools that take an explicit PrintWriter save output written to that
+ * stream as "main".
+ */
+ public class Result {
+
+ final Task task;
+ final int exitCode;
+ final Map<OutputKind, String> outputMap;
+
+ Result(Task task, int exitCode, Map<OutputKind, String> outputMap) {
+ this.task = task;
+ this.exitCode = exitCode;
+ this.outputMap = outputMap;
+ }
+
+ /**
+ * Returns the content of a specified stream.
+ * @param outputKind the kind of the selected stream
+ * @return the content that was written to that stream when the tool
+ * was executed.
+ */
+ public String getOutput(OutputKind outputKind) {
+ return outputMap.get(outputKind);
+ }
+
+ /**
+ * Returns the content of a named stream as a list of lines.
+ * @param outputKind the kind of the selected stream
+ * @return the content that was written to that stream when the tool
+ * was executed.
+ */
+ public List<String> getOutputLines(OutputKind outputKind) {
+ return Arrays.asList(outputMap.get(outputKind).split(lineSeparator));
+ }
+
+ /**
+ * Writes the content of the specified stream to the log.
+ * @param kind the kind of the selected stream
+ * @return this Result object
+ */
+ public Result write(OutputKind kind) {
+ String text = getOutput(kind);
+ if (text == null || text.isEmpty())
+ out.println("[" + task.name() + ":" + kind + "]: empty");
+ else {
+ out.println("[" + task.name() + ":" + kind + "]:");
+ out.print(text);
+ }
+ return this;
+ }
+
+ /**
+ * Writes the content of all streams with any content to the log.
+ * @return this Result object
+ */
+ public Result writeAll() {
+ outputMap.forEach((name, text) -> {
+ if (!text.isEmpty()) {
+ out.println("[" + name + "]:");
+ out.print(text);
+ }
+ });
+ return this;
+ }
+ }
+
+ /**
+ * A utility base class to simplify the implementation of tasks.
+ * Provides support for running the task in a process and for
+ * capturing output written by the task to stdout, stderr and
+ * other writers where applicable.
+ * @param <T> the implementing subclass
+ */
+ protected static abstract class AbstractTask<T extends AbstractTask<T>> implements Task {
+ protected final Mode mode;
+ private final Map<OutputKind, String> redirects = new EnumMap<>(OutputKind.class);
+ private final Map<String, String> envVars = new HashMap<>();
+ private Expect expect = Expect.SUCCESS;
+ int expectedExitCode = 0;
+
+ /**
+ * Create a task that will execute in the specified mode.
+ * @param mode the mode
+ */
+ protected AbstractTask(Mode mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Sets the expected outcome of the task and calls {@code run()}.
+ * @param expect the expected outcome
+ * @return the result of calling {@code run()}
+ */
+ public Result run(Expect expect) {
+ expect(expect, Integer.MIN_VALUE);
+ return run();
+ }
+
+ /**
+ * Sets the expected outcome of the task and calls {@code run()}.
+ * @param expect the expected outcome
+ * @param exitCode the expected exit code if the expected outcome
+ * is {@code FAIL}
+ * @return the result of calling {@code run()}
+ */
+ public Result run(Expect expect, int exitCode) {
+ expect(expect, exitCode);
+ return run();
+ }
+
+ /**
+ * Sets the expected outcome and expected exit code of the task.
+ * The exit code will not be checked if the outcome is
+ * {@code Expect.SUCCESS} or if the exit code is set to
+ * {@code Integer.MIN_VALUE}.
+ * @param expect the expected outcome
+ * @param exitCode the expected exit code
+ */
+ protected void expect(Expect expect, int exitCode) {
+ this.expect = expect;
+ this.expectedExitCode = exitCode;
+ }
+
+ /**
+ * Checks the exit code contained in a {@code Result} against the
+ * expected outcome and exit value
+ * @param result the result object
+ * @return the result object
+ * @throws TaskError if the exit code stored in the result object
+ * does not match the expected outcome and exit code.
+ */
+ protected Result checkExit(Result result) throws TaskError {
+ switch (expect) {
+ case SUCCESS:
+ if (result.exitCode != 0) {
+ result.writeAll();
+ throw new TaskError("Task " + name() + " failed: rc=" + result.exitCode);
+ }
+ break;
+
+ case FAIL:
+ if (result.exitCode == 0) {
+ result.writeAll();
+ throw new TaskError("Task " + name() + " succeeded unexpectedly");
+ }
+
+ if (expectedExitCode != Integer.MIN_VALUE
+ && result.exitCode != expectedExitCode) {
+ result.writeAll();
+ throw new TaskError("Task " + name() + "failed with unexpected exit code "
+ + result.exitCode + ", expected " + expectedExitCode);
+ }
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * Sets an environment variable to be used by this task.
+ * @param name the name of the environment variable
+ * @param value the value for the environment variable
+ * @return this task object
+ * @throws IllegalStateException if the task mode is not {@code EXEC}
+ */
+ protected T envVar(String name, String value) {
+ if (mode != Mode.EXEC)
+ throw new IllegalStateException();
+ envVars.put(name, value);
+ return (T) this;
+ }
+
+ /**
+ * Redirects output from an output stream to a file.
+ * @param outputKind the name of the stream to be redirected.
+ * @param path the file
+ * @return this task object
+ * @throws IllegalStateException if the task mode is not {@code EXEC}
+ */
+ protected T redirect(OutputKind outputKind, String path) {
+ if (mode != Mode.EXEC)
+ throw new IllegalStateException();
+ redirects.put(outputKind, path);
+ return (T) this;
+ }
+
+ /**
+ * Returns a {@code ProcessBuilder} initialized with any
+ * redirects and environment variables that have been set.
+ * @return a {@code ProcessBuilder}
+ */
+ protected ProcessBuilder getProcessBuilder() {
+ if (mode != Mode.EXEC)
+ throw new IllegalStateException();
+ ProcessBuilder pb = new ProcessBuilder();
+ if (redirects.get(OutputKind.STDOUT) != null)
+ pb.redirectOutput(new File(redirects.get(OutputKind.STDOUT)));
+ if (redirects.get(OutputKind.STDERR) != null)
+ pb.redirectError(new File(redirects.get(OutputKind.STDERR)));
+ pb.environment().putAll(envVars);
+ return pb;
+ }
+
+ /**
+ * Collects the output from a process and saves it in a {@code Result}.
+ * @param tb the {@code ToolBox} containing the task {@code t}
+ * @param t the task initiating the process
+ * @param p the process
+ * @return a Result object containing the output from the process and its
+ * exit value.
+ * @throws InterruptedException if the thread is interrupted
+ */
+ protected Result runProcess(ToolBox tb, Task t, Process p) throws InterruptedException {
+ if (mode != Mode.EXEC)
+ throw new IllegalStateException();
+ ProcessOutput sysOut = new ProcessOutput(p.getInputStream()).start();
+ ProcessOutput sysErr = new ProcessOutput(p.getErrorStream()).start();
+ sysOut.waitUntilDone();
+ sysErr.waitUntilDone();
+ int rc = p.waitFor();
+ Map<OutputKind, String> outputMap = new EnumMap<>(OutputKind.class);
+ outputMap.put(OutputKind.STDOUT, sysOut.getOutput());
+ outputMap.put(OutputKind.STDERR, sysErr.getOutput());
+ return checkExit(tb.new Result(t, rc, outputMap));
+ }
+
+ /**
+ * Thread-friendly class to read the output from a process until the stream
+ * is exhausted.
+ */
+ static class ProcessOutput implements Runnable {
+ ProcessOutput(InputStream from) {
+ in = new BufferedReader(new InputStreamReader(from));
+ out = new StringBuilder();
+ }
+
+ ProcessOutput start() {
+ new Thread(this).start();
+ return this;
+ }
+
+ @Override
+ public void run() {
+ try {
+ String line;
+ while ((line = in.readLine()) != null) {
+ out.append(line).append("\n");
+ }
+ } catch (IOException e) {
+ }
+ synchronized (this) {
+ done = true;
+ notifyAll();
+ }
+ }
+
+ synchronized void waitUntilDone() throws InterruptedException {
+ boolean interrupted = false;
+
+ // poll interrupted flag, while waiting for copy to complete
+ while (!(interrupted = Thread.interrupted()) && !done)
+ wait(1000);
+
+ if (interrupted)
+ throw new InterruptedException();
+ }
+
+ String getOutput() {
+ return out.toString();
+ }
+
+ private BufferedReader in;
+ private final StringBuilder out;
+ private boolean done;
+ }
+
+ /**
+ * Utility class to simplify the handling of temporarily setting a
+ * new stream for System.out or System.err.
+ */
+ static class StreamOutput {
+ // Functional interface to set a stream.
+ // Expected use: System::setOut, System::setErr
+ private interface Initializer {
+ void set(PrintStream s);
+ }
+
+ private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private final PrintStream ps = new PrintStream(baos);
+ private final PrintStream prev;
+ private final Initializer init;
+
+ StreamOutput(PrintStream s, Initializer init) {
+ prev = s;
+ init.set(ps);
+ this.init = init;
+ }
+
+ /**
+ * Closes the stream and returns the contents that were written to it.
+ * @return the contents that were written to it.
+ */
+ String close() {
+ init.set(prev);
+ ps.close();
+ return baos.toString();
+ }
+ }
+
+ /**
+ * Utility class to simplify the handling of creating an in-memory PrintWriter.
+ */
+ static class WriterOutput {
+ private final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+
+ /**
+ * Closes the stream and returns the contents that were written to it.
+ * @return the contents that were written to it.
+ */
+ String close() {
+ pw.close();
+ return sw.toString();
+ }
+ }
+ }
+
+ /**
+ * A task to configure and run the Java compiler, javac.
+ */
+ public class JavacTask extends AbstractTask<JavacTask> {
+ private boolean includeStandardOptions;
+ private String classpath;
+ private String sourcepath;
+ private String outdir;
+ private List<String> options;
+ private List<String> classes;
+ private List<String> files;
+ private List<JavaFileObject> fileObjects;
+ private JavaFileManager fileManager;
+
+ /**
+ * Creates a task to execute {@code javac} using API mode.
+ */
+ public JavacTask() {
+ super(Mode.API);
+ }
+
+ /**
+ * Creates a task to execute {@code javac} in a specified mode.
+ * @param mode the mode to be used
+ */
+ public JavacTask(Mode mode) {
+ super(mode);
+ }
+
+ /**
+ * Sets the classpath.
+ * @param classpath the classpath
+ * @return this task object
+ */
+ public JavacTask classpath(String classpath) {
+ this.classpath = classpath;
+ return this;
+ }
+
+ /**
+ * Sets the sourcepath.
+ * @param sourcepath the sourcepath
+ * @return this task object
+ */
+ public JavacTask sourcepath(String sourcepath) {
+ this.sourcepath = sourcepath;
+ return this;
+ }
+
+ /**
+ * Sets the output directory.
+ * @param outdir the output directory
+ * @return this task object
+ */
+ public JavacTask outdir(String outdir) {
+ this.outdir = outdir;
+ return this;
+ }
+
+ /**
+ * Sets the options.
+ * @param options the options
+ * @return this task object
+ */
+ public JavacTask options(String... options) {
+ this.options = Arrays.asList(options);
+ return this;
+ }
+
+ /**
+ * Sets the classes to be analyzed.
+ * @param classes the classes
+ * @return this task object
+ */
+ public JavacTask classes(String... classes) {
+ this.classes = Arrays.asList(classes);
+ return this;
+ }
+
+ /**
+ * Sets the files to be compiled or analyzed.
+ * @param files the files
+ * @return this task object
+ */
+ public JavacTask files(String... files) {
+ this.files = Arrays.asList(files);
+ return this;
+ }
+
+ /**
+ * Sets the files to be compiled or analyzed.
+ * @param files the files
+ * @return this task object
+ */
+ public JavacTask files(Path... files) {
+ this.files = Stream.of(files)
+ .map(Path::toString)
+ .collect(Collectors.toList());
+ return this;
+ }
+
+ /**
+ * Sets the sources to be compiled or analyzed.
+ * Each source string is converted into an in-memory object that
+ * can be passed directly to the compiler.
+ * @param sources the sources
+ * @return this task object
+ */
+ public JavacTask sources(String... sources) {
+ fileObjects = Stream.of(sources)
+ .map(s -> new JavaSource(s))
+ .collect(Collectors.toList());
+ return this;
+ }
+
+ /**
+ * Sets the file manager to be used by this task.
+ * @param fileManager the file manager
+ * @return this task object
+ */
+ public JavacTask fileManager(JavaFileManager fileManager) {
+ this.fileManager = fileManager;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return the name "javac"
+ */
+ @Override
+ public String name() {
+ return "javac";
+ }
+
+ /**
+ * Calls the compiler with the arguments as currently configured.
+ * @return a Result object indicating the outcome of the compilation
+ * and the content of any output written to stdout, stderr, or the
+ * main stream by the compiler.
+ * @throws TaskError if the outcome of the task is not as expected.
+ */
+ @Override
+ public Result run() {
+ if (mode == Mode.EXEC)
+ return runExec();
+
+ WriterOutput direct = new WriterOutput();
+ // The following are to catch output to System.out and System.err,
+ // in case these are used instead of the primary (main) stream
+ StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+ StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+ int rc;
+ Map<OutputKind, String> outputMap = new HashMap<>();
+ try {
+ switch (mode == null ? Mode.API : mode) {
+ case API:
+ rc = runAPI(direct.pw);
+ break;
+ case CMDLINE:
+ rc = runCommand(direct.pw);
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ } catch (IOException e) {
+ out.println("Exception occurred: " + e);
+ rc = 99;
+ } finally {
+ outputMap.put(OutputKind.STDOUT, sysOut.close());
+ outputMap.put(OutputKind.STDERR, sysErr.close());
+ outputMap.put(OutputKind.DIRECT, direct.close());
+ }
+ return checkExit(new Result(this, rc, outputMap));
+ }
+
+ private int runAPI(PrintWriter pw) throws IOException {
+// if (compiler == null) {
+ // TODO: allow this to be set externally
+// compiler = ToolProvider.getSystemJavaCompiler();
+ compiler = JavacTool.create();
+// }
+
+ if (fileManager == null)
+ fileManager = compiler.getStandardFileManager(null, null, null);
+ if (outdir != null)
+ setLocation(StandardLocation.CLASS_OUTPUT, toFiles(outdir));
+ if (classpath != null)
+ setLocation(StandardLocation.CLASS_PATH, toFiles(classpath));
+ if (sourcepath != null)
+ setLocation(StandardLocation.SOURCE_PATH, toFiles(sourcepath));
+ List<String> allOpts = new ArrayList<>();
+ if (options != null)
+ allOpts.addAll(options);
+
+ Iterable<? extends JavaFileObject> allFiles = joinFiles(files, fileObjects);
+ JavaCompiler.CompilationTask task = compiler.getTask(pw,
+ fileManager,
+ null, // diagnostic listener; should optionally collect diags
+ allOpts,
+ classes,
+ allFiles);
+ return ((JavacTaskImpl) task).doCall().exitCode;
+ }
+
+ private void setLocation(StandardLocation location, List<File> files) throws IOException {
+ if (!(fileManager instanceof StandardJavaFileManager))
+ throw new IllegalStateException("not a StandardJavaFileManager");
+ ((StandardJavaFileManager) fileManager).setLocation(location, files);
+ }
+
+ private int runCommand(PrintWriter pw) {
+ List<String> args = getAllArgs();
+ String[] argsArray = args.toArray(new String[args.size()]);
+ return com.sun.tools.javac.Main.compile(argsArray, pw);
+ }
+
+ private Result runExec() {
+ List<String> args = new ArrayList<>();
+ Path javac = getJDKTool("javac");
+ args.add(javac.toString());
+ if (includeStandardOptions) {
+ args.addAll(split(System.getProperty("test.tool.vm.opts"), " +"));
+ args.addAll(split(System.getProperty("test.compiler.opts"), " +"));
+ }
+ args.addAll(getAllArgs());
+
+ String[] argsArray = args.toArray(new String[args.size()]);
+ ProcessBuilder pb = getProcessBuilder();
+ pb.command(argsArray);
+ try {
+ return runProcess(ToolBox.this, this, pb.start());
+ } catch (IOException | InterruptedException e) {
+ throw new Error(e);
+ }
+ }
+
+ private List<String> getAllArgs() {
+ List<String> args = new ArrayList<>();
+ if (options != null)
+ args.addAll(options);
+ if (outdir != null) {
+ args.add("-d");
+ args.add(outdir);
+ }
+ if (classpath != null) {
+ args.add("-classpath");
+ args.add(classpath);
+ }
+ if (sourcepath != null) {
+ args.add("-sourcepath");
+ args.add(sourcepath);
+ }
+ if (classes != null)
+ args.addAll(classes);
+ if (files != null)
+ args.addAll(files);
+
+ return args;
+ }
+
+ private List<File> toFiles(String path) {
+ List<File> result = new ArrayList<>();
+ for (String s: path.split(File.pathSeparator)) {
+ if (!s.isEmpty())
+ result.add(new File(s));
+ }
+ return result;
+ }
+
+ private Iterable<? extends JavaFileObject> joinFiles(
+ List<String> files, List<JavaFileObject> fileObjects) {
+ if (files == null)
+ return fileObjects;
+ if (standardJavaFileManager == null)
+ standardJavaFileManager = compiler.getStandardFileManager(null, null, null);
+ Iterable<? extends JavaFileObject> filesAsFileObjects =
+ standardJavaFileManager.getJavaFileObjectsFromStrings(files);
+ if (fileObjects == null)
+ return filesAsFileObjects;
+ List<JavaFileObject> combinedList = new ArrayList<>();
+ for (JavaFileObject o: filesAsFileObjects)
+ combinedList.add(o);
+ combinedList.addAll(fileObjects);
+ return combinedList;
+ }
+ }
+
+ /**
+ * A task to configure and run the native header tool, javah.
+ */
+ public class JavahTask extends AbstractTask<JavahTask> {
+ private String classpath;
+ private List<String> options;
+ private List<String> classes;
+
+ /**
+ * Create a task to execute {@code javah} using {@code CMDLINE} mode.
+ */
+ public JavahTask() {
+ super(Mode.CMDLINE);
+ }
+
+ /**
+ * Sets the classpath.
+ * @param classpath the classpath
+ * @return this task object
+ */
+ public JavahTask classpath(String classpath) {
+ this.classpath = classpath;
+ return this;
+ }
+
+ /**
+ * Sets the options.
+ * @param options the options
+ * @return this task object
+ */
+ public JavahTask options(String... options) {
+ this.options = Arrays.asList(options);
+ return this;
+ }
+
+ /**
+ * Sets the classes to be analyzed.
+ * @param classes the classes
+ * @return this task object
+ */
+ public JavahTask classes(String... classes) {
+ this.classes = Arrays.asList(classes);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return the name "javah"
+ */
+ @Override
+ public String name() {
+ return "javah";
+ }
+
+ /**
+ * Calls the javah tool with the arguments as currently configured.
+ * @return a Result object indicating the outcome of the task
+ * and the content of any output written to stdout, stderr, or the
+ * main stream provided to the task.
+ * @throws TaskError if the outcome of the task is not as expected.
+ */
+ @Override
+ public Result run() {
+ List<String> args = new ArrayList<>();
+ if (options != null)
+ args.addAll(options);
+ if (classpath != null) {
+ args.add("-classpath");
+ args.add(classpath);
+ }
+ if (classes != null)
+ args.addAll(classes);
+
+ WriterOutput direct = new WriterOutput();
+ // These are to catch output to System.out and System.err,
+ // in case these are used instead of the primary streams
+ StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+ StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+ int rc;
+ Map<OutputKind, String> outputMap = new HashMap<>();
+ try {
+ rc = com.sun.tools.javah.Main.run(args.toArray(new String[args.size()]), direct.pw);
+ } finally {
+ outputMap.put(OutputKind.STDOUT, sysOut.close());
+ outputMap.put(OutputKind.STDERR, sysErr.close());
+ outputMap.put(OutputKind.DIRECT, direct.close());
+ }
+ return checkExit(new Result(this, rc, outputMap));
+ }
+ }
+
+ /**
+ * A task to configure and run the disassembler tool, javap.
+ */
+ public class JavapTask extends AbstractTask<JavapTask> {
+ private String classpath;
+ private List<String> options;
+ private List<String> classes;
+
+ /**
+ * Create a task to execute {@code javap} using {@code CMDLINE} mode.
+ */
+ public JavapTask() {
+ super(Mode.CMDLINE);
+ }
+
+ /**
+ * Sets the classpath.
+ * @param classpath the classpath
+ * @return this task object
+ */
+ public JavapTask classpath(String classpath) {
+ this.classpath = classpath;
+ return this;
+ }
+
+ /**
+ * Sets the options.
+ * @param options the options
+ * @return this task object
+ */
+ public JavapTask options(String... options) {
+ this.options = Arrays.asList(options);
+ return this;
+ }
+
+ /**
+ * Sets the classes to be analyzed.
+ * @param classes the classes
+ * @return this task object
+ */
+ public JavapTask classes(String... classes) {
+ this.classes = Arrays.asList(classes);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return the name "javap"
+ */
+ @Override
+ public String name() {
+ return "javap";
+ }
+
+ /**
+ * Calls the javap tool with the arguments as currently configured.
+ * @return a Result object indicating the outcome of the task
+ * and the content of any output written to stdout, stderr, or the
+ * main stream.
+ * @throws TaskError if the outcome of the task is not as expected.
+ */
+ @Override
+ public Result run() {
+ List<String> args = new ArrayList<>();
+ if (options != null)
+ args.addAll(options);
+ if (classpath != null) {
+ args.add("-classpath");
+ args.add(classpath);
+ }
+ if (classes != null)
+ args.addAll(classes);
+
+ WriterOutput direct = new WriterOutput();
+ // These are to catch output to System.out and System.err,
+ // in case these are used instead of the primary streams
+ StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+ StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+
+ int rc;
+ Map<OutputKind, String> outputMap = new HashMap<>();
+ try {
+ rc = com.sun.tools.javap.Main.run(args.toArray(new String[args.size()]), direct.pw);
+ } finally {
+ outputMap.put(OutputKind.STDOUT, sysOut.close());
+ outputMap.put(OutputKind.STDERR, sysErr.close());
+ outputMap.put(OutputKind.DIRECT, direct.close());
+ }
+ return checkExit(new Result(this, rc, outputMap));
+ }
+ }
+
+ /**
+ * A task to configure and run the jar file utility.
+ */
+ public class JarTask extends AbstractTask<JarTask> {
+ private Path jar;
+ private Manifest manifest;
+ private String classpath;
+ private String mainClass;
+ private Path baseDir;
+ private List<Path> paths;
+
+ /**
+ * Creates a task to write jar files, using API mode.
+ */
+ public JarTask() {
+ super(Mode.API);
+ paths = Collections.emptyList();
+ }
+
+ /**
+ * Creates a JarTask for use with a given jar file.
+ * @param path the file
+ */
+ public JarTask(String path) {
+ this();
+ jar = Paths.get(path);
+ }
+
+ /**
+ * Sets a manifest for the jar file.
+ * @param manifest the manifest
+ * @return this task object
+ */
+ public JarTask manifest(Manifest manifest) {
+ this.manifest = manifest;
+ return this;
+ }
+
+ /**
+ * Sets a manifest for the jar file.
+ * @param manifest a string containing the contents of the manifest
+ * @return this task object
+ * @throws IOException if there is a problem creating the manifest
+ */
+ public JarTask manifest(String manifest) throws IOException {
+ this.manifest = new Manifest(new ByteArrayInputStream(manifest.getBytes()));
+ return this;
+ }
+
+ /**
+ * Sets the classpath to be written to the {@code Class-Path}
+ * entry in the manifest.
+ * @param classpath the classpath
+ * @return this task object
+ */
+ public JarTask classpath(String classpath) {
+ this.classpath = classpath;
+ return this;
+ }
+
+ /**
+ * Sets the class to be written to the {@code Main-Class}
+ * entry in the manifest..
+ * @param mainClass the name of the main class
+ * @return this task object
+ */
+ public JarTask mainClass(String mainClass) {
+ this.mainClass = mainClass;
+ return this;
+ }
+
+ /**
+ * Sets the base directory for files to be written into the jar file.
+ * @param baseDir the base directory
+ * @return this task object
+ */
+ public JarTask baseDir(String baseDir) {
+ this.baseDir = Paths.get(baseDir);
+ return this;
+ }
+
+ /**
+ * Sets the files to be written into the jar file.
+ * @param files the files
+ * @return this task object
+ */
+ public JarTask files(String... files) {
+ this.paths = Stream.of(files)
+ .map(file -> Paths.get(file))
+ .collect(Collectors.toList());
+ return this;
+ }
+
+ /**
+ * Provides limited jar command-like functionality.
+ * The supported commands are:
+ * <ul>
+ * <li> jar cf jarfile -C dir files...
+ * <li> jar cfm jarfile manifestfile -C dir files...
+ * </ul>
+ * Any values specified by other configuration methods will be ignored.
+ * @param args arguments in the style of those for the jar command
+ * @return a Result object containing the results of running the task
+ */
+ public Result run(String... args) {
+ if (args.length < 2)
+ throw new IllegalArgumentException();
+
+ ListIterator<String> iter = Arrays.asList(args).listIterator();
+ String first = iter.next();
+ switch (first) {
+ case "cf":
+ jar = Paths.get(iter.next());
+ break;
+ case "cfm":
+ jar = Paths.get(iter.next());
+ try (InputStream in = Files.newInputStream(Paths.get(iter.next()))) {
+ manifest = new Manifest(in);
+ } catch (IOException e) {
+ throw new IOError(e);
+ }
+ break;
+ }
+
+ if (iter.hasNext()) {
+ if (iter.next().equals("-C"))
+ baseDir = Paths.get(iter.next());
+ else
+ iter.previous();
+ }
+
+ paths = new ArrayList<>();
+ while (iter.hasNext())
+ paths.add(Paths.get(iter.next()));
+
+ return run();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return the name "jar"
+ */
+ @Override
+ public String name() {
+ return "jar";
+ }
+
+ /**
+ * Creates a jar file with the arguments as currently configured.
+ * @return a Result object indicating the outcome of the compilation
+ * and the content of any output written to stdout, stderr, or the
+ * main stream by the compiler.
+ * @throws TaskError if the outcome of the task is not as expected.
+ */
+ @Override
+ public Result run() {
+ Manifest m = (manifest == null) ? new Manifest() : manifest;
+ Attributes mainAttrs = m.getMainAttributes();
+ if (mainClass != null)
+ mainAttrs.put(Attributes.Name.MAIN_CLASS, mainClass);
+ if (classpath != null)
+ mainAttrs.put(Attributes.Name.CLASS_PATH, classpath);
+
+ StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+ StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+
+ int rc;
+ Map<OutputKind, String> outputMap = new HashMap<>();
+
+ try (OutputStream os = Files.newOutputStream(jar);
+ JarOutputStream jos = openJar(os, m)) {
+ Path base = (baseDir == null) ? currDir : baseDir;
+ for (Path path: paths) {
+ Files.walkFileTree(base.resolve(path), new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ try {
+ JarEntry e = new JarEntry(base.relativize(file).toString());
+ jos.putNextEntry(e);
+ jos.write(Files.readAllBytes(file));
+ jos.closeEntry();
+ return FileVisitResult.CONTINUE;
+ } catch (IOException e) {
+ System.err.println("Error adding " + file + " to jar file: " + e);
+ return FileVisitResult.TERMINATE;
+ }
+ }
+ });
+ }
+ rc = 0;
+ } catch (IOException e) {
+ System.err.println("Error opening " + jar + ": " + e);
+ rc = 1;
+ } finally {
+ outputMap.put(OutputKind.STDOUT, sysOut.close());
+ outputMap.put(OutputKind.STDERR, sysErr.close());
+ }
+ return checkExit(new Result(this, rc, outputMap));
+ }
+
+ private JarOutputStream openJar(OutputStream os, Manifest m) throws IOException {
+ if (m == null || m.getMainAttributes().isEmpty() && m.getEntries().isEmpty()) {
+ return new JarOutputStream(os);
+ } else {
+ if (m.getMainAttributes().get(Attributes.Name.MANIFEST_VERSION) == null)
+ m.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ return new JarOutputStream(os, m);
+ }
+ }
+
+ }
+
+ /**
+ * A task to configure and run the Java launcher.
+ */
+ public class JavaTask extends AbstractTask<JavaTask> {
+ boolean includeStandardOptions = true;
+ private String classpath;
+ private List<String> vmOptions;
+ private String className;
+ private List<String> classArgs;
+
+ /**
+ * Create a task to run the Java launcher, using {@code EXEC} mode.
+ */
+ public JavaTask() {
+ super(Mode.EXEC);
+ }
+
+ /**
+ * Sets the classpath.
+ * @param classpath the classpath
+ * @return this task object
+ */
+ public JavaTask classpath(String classpath) {
+ this.classpath = classpath;
+ return this;
+ }
+
+ /**
+ * Sets the VM options.
+ * @param vmOptions the options
+ * @return this task object
+ */
+ public JavaTask vmOptions(String... vmOptions) {
+ this.vmOptions = Arrays.asList(vmOptions);
+ return this;
+ }
+
+ /**
+ * Sets the name of the class to be executed.
+ * @param className the name of the class
+ * @return this task object
+ */
+ public JavaTask className(String className) {
+ this.className = className;
+ return this;
+ }
+
+ /**
+ * Sets the arguments for the class to be executed.
+ * @param classArgs the arguments
+ * @return this task object
+ */
+ public JavaTask classArgs(String... classArgs) {
+ this.classArgs = Arrays.asList(classArgs);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return the name "java"
+ */
+ @Override
+ public String name() {
+ return "java";
+ }
+
+ /**
+ * Calls the Java launcher with the arguments as currently configured.
+ * @return a Result object indicating the outcome of the task
+ * and the content of any output written to stdout or stderr.
+ * @throws TaskError if the outcome of the task is not as expected.
+ */
+ @Override
+ public Result run() {
+ List<String> args = new ArrayList<>();
+ args.add(getJDKTool("java").toString());
+ if (includeStandardOptions) {
+ args.addAll(split(System.getProperty("test.vm.opts"), " +"));
+ args.addAll(split(System.getProperty("test.java.opts"), " +"));
+ }
+ if (classpath != null) {
+ args.add("-classpath");
+ args.add(classpath);
+ }
+ if (vmOptions != null)
+ args.addAll(vmOptions);
+ if (className != null)
+ args.add(className);
+ if (classArgs != null)
+ args.addAll(classArgs);
+ ProcessBuilder pb = getProcessBuilder();
+ pb.command(args);
+ try {
+ return runProcess(ToolBox.this, this, pb.start());
+ } catch (IOException | InterruptedException e) {
+ throw new Error(e);
+ }
+ }
+ }
+
+ /**
+ * A task to configure and run a general command.
+ */
+ public class ExecTask extends AbstractTask<ExecTask> {
+ private final String command;
+ private List<String> args;
+
+ /**
+ * Create a task to execute a given command, to be run using {@code EXEC} mode.
+ * @param command the command to be executed
+ */
+ public ExecTask(String command) {
+ super(Mode.EXEC);
+ this.command = command;
+ }
+
+ /**
+ * Create a task to execute a given command, to be run using {@code EXEC} mode.
+ * @param command the command to be executed
+ */
+ public ExecTask(Path command) {
+ super(Mode.EXEC);
+ this.command = command.toString();
+ }
+
+ /**
+ * Sets the arguments for the command to be executed
+ * @param args the arguments
+ * @return this task object
+ */
+ public ExecTask args(String... args) {
+ this.args = Arrays.asList(args);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return the name "exec"
+ */
+ @Override
+ public String name() {
+ return "exec";
+ }
+
+ /**
+ * Calls the command with the arguments as currently configured.
+ * @return a Result object indicating the outcome of the task
+ * and the content of any output written to stdout or stderr.
+ * @throws TaskError if the outcome of the task is not as expected.
+ */
+ @Override
+ public Result run() {
+ List<String> cmdArgs = new ArrayList<>();
+ cmdArgs.add(command);
+ if (args != null)
+ cmdArgs.addAll(args);
+ ProcessBuilder pb = getProcessBuilder();
+ pb.command(cmdArgs);
+ try {
+ return runProcess(ToolBox.this, this, pb.start());
+ } catch (IOException | InterruptedException e) {
+ throw new Error(e);
+ }
+ }
+ }
+
+ /**
+ * An in-memory Java source file.
+ * It is able to extract the file name from simple source text using
+ * regular expressions.
+ */
+ public static class JavaSource extends SimpleJavaFileObject {
+ private final String source;
+
+ /**
+ * Creates a in-memory file object for Java source code.
+ * @param className the name of the class
+ * @param source the source text
+ */
+ public JavaSource(String className, String source) {
+ super(URI.create(className), JavaFileObject.Kind.SOURCE);
+ this.source = source;
+ }
+
+ /**
+ * Creates a in-memory file object for Java source code.
+ * The name of the class will be inferred from the source code.
+ * @param source the source text
+ */
+ public JavaSource(String source) {
+ super(URI.create(getJavaFileNameFromSource(source)),
+ JavaFileObject.Kind.SOURCE);
+ this.source = source;
+ }
+
+ /**
+ * Writes the source code to a file in the current directory.
+ * @throws IOException if there is a problem writing the file
+ */
+ public void write() throws IOException {
+ write(currDir);
+ }
+
+ /**
+ * Writes the source code to a file in a specified directory.
+ * @param dir the directory
+ * @throws IOException if there is a problem writing the file
+ */
+ public void write(Path dir) throws IOException {
+ Path file = dir.resolve(getJavaFileNameFromSource(source));
+ Files.createDirectories(file.getParent());
+ try (BufferedWriter out = Files.newBufferedWriter(file)) {
+ out.write(source.replace("\n", lineSeparator));
+ }
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+
+ private static Pattern packagePattern =
+ Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))");
+ private static Pattern classPattern =
+ Pattern.compile("(?:public\\s+)?(?:class|enum|interface)\\s+(\\w+)");
+
+ /**
+ * Extracts the Java file name from the class declaration.
+ * This method is intended for simple files and uses regular expressions,
+ * so comments matching the pattern can make the method fail.
+ */
+ static String getJavaFileNameFromSource(String source) {
+ String packageName = null;
+
+ Matcher matcher = packagePattern.matcher(source);
+ if (matcher.find())
+ packageName = matcher.group(1).replace(".", "/");
+
+ matcher = classPattern.matcher(source);
+ if (matcher.find()) {
+ String className = matcher.group(1) + ".java";
+ return (packageName == null) ? className : packageName + "/" + className;
+ } else {
+ throw new Error("Could not extract the java class " +
+ "name from the provided source");
+ }
+ }
+ }
+
+ /**
+ * Extracts the Java file name from the class declaration.
+ * This method is intended for simple files and uses regular expressions,
+ * so comments matching the pattern can make the method fail.
+ * @deprecated This is a legacy method for compatibility with ToolBox v1.
+ * Use {@link JavaSource#getName JavaSource.getName} instead.
+ * @param source the source text
+ * @return the Java file name inferred from the source
+ */
+ @Deprecated
+ public static String getJavaFileNameFromSource(String source) {
+ return JavaSource.getJavaFileNameFromSource(source);
+ }
+
+ /**
+ * A memory file manager, for saving generated files in memory.
+ * The file manager delegates to a separate file manager for listing and
+ * reading input files.
+ */
+ public static class MemoryFileManager extends ForwardingJavaFileManager {
+ private interface Content {
+ byte[] getBytes();
+ String getString();
+ }
+
+ /**
+ * Maps binary class names to generated content.
+ */
+ final Map<Location, Map<String, Content>> files;
+
+ /**
+ * Construct a memory file manager which stores output files in memory,
+ * and delegates to a default file manager for input files.
+ */
+ public MemoryFileManager() {
+ this(JavacTool.create().getStandardFileManager(null, null, null));
+ }
+
+ /**
+ * Construct a memory file manager which stores output files in memory,
+ * and delegates to a specified file manager for input files.
+ * @param fileManager the file manager to be used for input files
+ */
+ public MemoryFileManager(JavaFileManager fileManager) {
+ super(fileManager);
+ files = new HashMap<>();
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForOutput(Location location,
+ String name,
+ JavaFileObject.Kind kind,
+ FileObject sibling)
+ {
+ return new MemoryFileObject(location, name, kind);
+ }
+
+ /**
+ * Returns the content written to a file in a given location,
+ * or null if no such file has been written.
+ * @param location the location
+ * @param name the name of the file
+ * @return the content as an array of bytes
+ */
+ public byte[] getFileBytes(Location location, String name) {
+ Content content = getFile(location, name);
+ return (content == null) ? null : content.getBytes();
+ }
+
+ /**
+ * Returns the content written to a file in a given location,
+ * or null if no such file has been written.
+ * @param location the location
+ * @param name the name of the file
+ * @return the content as a string
+ */
+ public String getFileString(Location location, String name) {
+ Content content = getFile(location, name);
+ return (content == null) ? null : content.getString();
+ }
+
+ private Content getFile(Location location, String name) {
+ Map<String, Content> filesForLocation = files.get(location);
+ return (filesForLocation == null) ? null : filesForLocation.get(name);
+ }
+
+ private void save(Location location, String name, Content content) {
+ Map<String, Content> filesForLocation = files.get(location);
+ if (filesForLocation == null)
+ files.put(location, filesForLocation = new HashMap<>());
+ filesForLocation.put(name, content);
+ }
+
+ /**
+ * A writable file object stored in memory.
+ */
+ private class MemoryFileObject extends SimpleJavaFileObject {
+ private final Location location;
+ private final String name;
+
+ /**
+ * Constructs a memory file object.
+ * @param name binary name of the class to be stored in this file object
+ */
+ MemoryFileObject(Location location, String name, JavaFileObject.Kind kind) {
+ super(URI.create("mfm:///" + name.replace('.','/') + kind.extension),
+ Kind.CLASS);
+ this.location = location;
+ this.name = name;
+ }
+
+ @Override
+ public OutputStream openOutputStream() {
+ return new FilterOutputStream(new ByteArrayOutputStream()) {
+ @Override
+ public void close() throws IOException {
+ out.close();
+ byte[] bytes = ((ByteArrayOutputStream) out).toByteArray();
+ save(location, name, new Content() {
+ @Override
+ public byte[] getBytes() {
+ return bytes;
+ }
+ @Override
+ public String getString() {
+ return new String(bytes);
+ }
+
+ });
+ }
+ };
+ }
+
+ @Override
+ public Writer openWriter() {
+ return new FilterWriter(new StringWriter()) {
+ @Override
+ public void close() throws IOException {
+ out.close();
+ String text = ((StringWriter) out).toString();
+ save(location, name, new Content() {
+ @Override
+ public byte[] getBytes() {
+ return text.getBytes();
+ }
+ @Override
+ public String getString() {
+ return text;
+ }
+
+ });
+ }
+ };
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/IdleShutdown.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8044131
+ * @summary Tests the hooks used for detecting idleness of the sjavac server.
+ * @build Wrapper
+ * @run main Wrapper IdleShutdown
+ */
+import java.io.File;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.IdleResetSjavac;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SysInfo;
+import com.sun.tools.sjavac.server.Terminable;
+
+
+public class IdleShutdown {
+
+ final static long TEST_START = System.currentTimeMillis();
+ final static long TIMEOUT_MS = 3000;
+
+ public static void main(String[] args) throws InterruptedException {
+
+ final AtomicLong timeoutTimestamp = new AtomicLong(-1);
+
+ log("Starting IdleCallbackJavacService with timeout: " + TIMEOUT_MS);
+ Sjavac service = new IdleResetSjavac(
+ new NoopJavacService(),
+ new Terminable() {
+ public void shutdown(String msg) {
+ // Record the idle timeout time
+ log("Timeout detected");
+ timeoutTimestamp.set(System.currentTimeMillis());
+ }
+ },
+ TIMEOUT_MS);
+
+ // Make sure it didn't timeout immediately
+ if (timeoutTimestamp.get() != -1)
+ throw new AssertionError("Premature timeout detected.");
+
+ // Call various methods and wait less than TIMEOUT_MS in between
+ Thread.sleep(TIMEOUT_MS - 1000);
+ log("Getting sys info");
+ service.getSysInfo();
+
+ Thread.sleep(TIMEOUT_MS - 1000);
+ log("Getting sys info");
+ service.getSysInfo();
+
+ if (timeoutTimestamp.get() != -1)
+ throw new AssertionError("Premature timeout detected.");
+
+ Thread.sleep(TIMEOUT_MS - 1000);
+ log("Compiling");
+ service.compile("",
+ "",
+ new String[0],
+ Collections.<File>emptyList(),
+ Collections.<URI>emptySet(),
+ Collections.<URI>emptySet());
+
+ Thread.sleep(TIMEOUT_MS - 1000);
+ log("Compiling");
+ service.compile("",
+ "",
+ new String[0],
+ Collections.<File>emptyList(),
+ Collections.<URI>emptySet(),
+ Collections.<URI>emptySet());
+
+ if (timeoutTimestamp.get() != -1)
+ throw new AssertionError("Premature timeout detected.");
+
+ long expectedTimeout = System.currentTimeMillis() + TIMEOUT_MS;
+
+ // Wait for actual timeout
+ log("Awaiting idle timeout");
+ Thread.sleep(TIMEOUT_MS + 1000);
+
+ // Check result
+ if (timeoutTimestamp.get() == -1)
+ throw new AssertionError("Timeout never occurred");
+
+ long error = Math.abs(expectedTimeout - timeoutTimestamp.get());
+ log("Timeout error: " + error + " ms");
+ if (error > TIMEOUT_MS * .1)
+ throw new AssertionError("Error too big");
+
+ log("Shutting down");
+ service.shutdown();
+ }
+
+ private static void log(String msg) {
+ long logTime = System.currentTimeMillis() - TEST_START;
+ System.out.printf("After %5d ms: %s%n", logTime, msg);
+ }
+
+ private static class NoopJavacService implements Sjavac {
+ @Override
+ public SysInfo getSysInfo() {
+ // Attempt to trigger idle timeout during a call by sleeping
+ try {
+ Thread.sleep(TIMEOUT_MS + 1000);
+ } catch (InterruptedException e) {
+ }
+ return null;
+ }
+ @Override
+ public void shutdown() {
+ }
+ @Override
+ public CompilationResult compile(String protocolId,
+ String invocationId,
+ String[] args,
+ List<File> explicitSources,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources) {
+ return null;
+ }
+ @Override
+ public String serverSettings() {
+ return "";
+ }
+ }
+}
--- a/langtools/test/tools/sjavac/OptionDecoding.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/sjavac/OptionDecoding.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
/*
* @test
- * @bug 8035063
+ * @bug 8035063 8054465
* @summary Tests decoding of String[] into Options.
*
* @build Wrapper
@@ -192,13 +192,16 @@
assertEquals(17, options.getNumCores());
assertEquals("debug", options.getLogLevel());
assertEquals(false, options.isDefaultPackagePermitted());
- assertEquals(false, options.isUnidentifiedArtifactPermitted());
+ assertEquals(false, options.areUnidentifiedArtifactsPermitted());
+ assertEquals(false, options.isUnidentifiedArtifactPermitted(Paths.get("bar.txt").toFile().getAbsolutePath()));
options = Options.parseArgs("--permit-unidentified-artifacts",
+ "--permit-artifact=bar.txt",
"--permit-sources-without-package");
assertEquals("info", options.getLogLevel());
assertEquals(true, options.isDefaultPackagePermitted());
- assertEquals(true, options.isUnidentifiedArtifactPermitted());
+ assertEquals(true, options.areUnidentifiedArtifactsPermitted());
+ assertEquals(true, options.isUnidentifiedArtifactPermitted(Paths.get("bar.txt").toFile().getAbsolutePath()));
}
// Test server configuration options
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/PooledExecution.java Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8044131
+ * @summary Makes sure sjavac poolsize option is honored.
+ * @build Wrapper
+ * @run main Wrapper PooledExecution
+ */
+import java.io.File;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.sun.tools.sjavac.comp.PooledSjavac;
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SysInfo;
+
+
+public class PooledExecution {
+
+ public static void main(String[] args) throws InterruptedException {
+ new PooledExecutionTest().runTest();
+ }
+
+ static class PooledExecutionTest {
+
+ final int POOL_SIZE = 15;
+ final int NUM_REQUESTS = 100;
+
+ // Number of tasks that has not yet started
+ CountDownLatch leftToStart = new CountDownLatch(NUM_REQUESTS);
+
+ // Highest number of concurrently active request seen
+ int highWaterMark = 0;
+
+ public void runTest() throws InterruptedException {
+ ConcurrencyLoggingService loggingService = new ConcurrencyLoggingService();
+ final Sjavac service = new PooledSjavac(loggingService, POOL_SIZE);
+
+ // Keep track of the number of finished tasks so we can make sure all
+ // tasks finishes gracefully upon shutdown.
+ Thread[] tasks = new Thread[NUM_REQUESTS];
+ final AtomicInteger tasksFinished = new AtomicInteger(0);
+
+ for (int i = 0; i < NUM_REQUESTS; i++) {
+ tasks[i] = new Thread() {
+ public void run() {
+ service.compile("",
+ "",
+ new String[0],
+ Collections.<File>emptyList(),
+ Collections.<URI>emptySet(),
+ Collections.<URI>emptySet());
+ tasksFinished.incrementAndGet();
+ }
+ };
+ tasks[i].start();
+ }
+
+ // Wait for all tasks to start (but not necessarily run to completion)
+ leftToStart.await();
+
+ // Shutdown before all tasks are completed
+ System.out.println("Shutting down!");
+ service.shutdown();
+
+ // Wait for all tasks to complete
+ for (Thread t : tasks)
+ t.join();
+
+ if (tasksFinished.get() != NUM_REQUESTS) {
+ throw new AssertionError(tasksFinished.get() + " out of " +
+ NUM_REQUESTS + " finished. Broken shutdown?");
+ }
+
+ if (highWaterMark > POOL_SIZE) {
+ throw new AssertionError("Pool size overused: " + highWaterMark +
+ " used out of " + POOL_SIZE + " allowed.");
+ }
+
+ // Assuming more than POOL_SIZE requests can be processed within 1 sek:
+ if (highWaterMark < POOL_SIZE) {
+ throw new AssertionError("Pool size underused: " + highWaterMark +
+ " used out of " + POOL_SIZE + " allowed.");
+ }
+ }
+
+
+ private class ConcurrencyLoggingService implements Sjavac {
+
+ // Keeps track of currently active requests
+ AtomicInteger activeRequests = new AtomicInteger(0);
+
+ @Override
+ public CompilationResult compile(String protocolId,
+ String invocationId,
+ String[] args,
+ List<File> explicitSources,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources) {
+ leftToStart.countDown();
+ int numActiveRequests = activeRequests.incrementAndGet();
+ System.out.printf("Left to start: %2d / Currently active: %2d%n",
+ leftToStart.getCount(),
+ numActiveRequests);
+ highWaterMark = Math.max(highWaterMark, numActiveRequests);
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {
+ throw new RuntimeException("Interrupted", ie);
+ }
+ activeRequests.decrementAndGet();
+ System.out.println("Task completed");
+ return null;
+ }
+
+ @Override
+ public SysInfo getSysInfo() {
+ return null;
+ }
+
+ @Override
+ public void shutdown() {
+ }
+
+ @Override
+ public String serverSettings() {
+ return "";
+ }
+ }
+ }
+}
--- a/langtools/test/tools/sjavac/SJavac.java Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/sjavac/SJavac.java Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
/*
* @test
* @summary Test all aspects of sjavac.
- * @bug 8004658 8042441 8042699
+ * @bug 8004658 8042441 8042699 8054461 8054474 8054465
*
* @build Wrapper
* @run main Wrapper SJavac
@@ -99,6 +99,9 @@
compileCircularSources();
compileExcludingDependency();
incrementalCompileTestFullyQualifiedRef();
+ compileWithAtFile();
+ testStateDir();
+ testPermittedArtifact();
delete(gensrc);
delete(gensrc2);
@@ -463,6 +466,98 @@
"bin/javac_state");
}
+ /**
+ * Tests @atfile
+ * @throws Exception If test fails
+ */
+ void compileWithAtFile() throws Exception {
+ System.out.println("\nTest @atfile with command line content.");
+ System.out.println("---------------------------------------");
+
+ delete(gensrc);
+ delete(gensrc2);
+ delete(bin);
+
+ populate(gensrc,
+ "list.txt",
+ "-if */alfa/omega/A.java\n-if */beta/B.java\ngensrc\n-d bin\n",
+ "alfa/omega/A.java",
+ "package alfa.omega; import beta.B; public class A { B b; }",
+ "beta/B.java",
+ "package beta; public class B { }",
+ "beta/C.java",
+ "broken");
+ previous_bin_state = collectState(bin);
+ compile("@gensrc/list.txt", "--server:portfile=testserver,background=false");
+
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/javac_state",
+ "bin/alfa/omega/A.class",
+ "bin/beta/B.class");
+ }
+
+ /**
+ * Tests storing javac_state into another directory.
+ * @throws Exception If test fails
+ */
+ void testStateDir() throws Exception {
+ System.out.println("\nVerify that --state-dir=bar works.");
+ System.out.println("----------------------------------");
+
+ Path bar = defaultfs.getPath("bar");
+ Files.createDirectory(bar);
+
+ delete(gensrc);
+ delete(bin);
+ delete(bar);
+ previous_bin_state = collectState(bin);
+ Map<String,Long> previous_bar_state = collectState(bar);
+
+ populate(gensrc,
+ "alfa/omega/A.java",
+ "package alfa.omega; public class A { }");
+
+ compile("--state-dir=bar", "-src", "gensrc", "-d", "bin", serverArg);
+
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/alfa/omega/A.class");
+ Map<String,Long> new_bar_state = collectState(bar);
+ verifyThatFilesHaveBeenAdded(previous_bar_state, new_bar_state,
+ "bar/javac_state");
+ }
+
+ /**
+ * Test white listing of external artifacts inside the destination dir.
+ * @throws Exception If test fails
+ */
+ void testPermittedArtifact() throws Exception {
+ System.out.println("\nVerify that --permit-artifact=bar works.");
+ System.out.println("-------------------------------------------");
+
+ delete(gensrc);
+ delete(bin);
+
+ previous_bin_state = collectState(bin);
+
+ populate(gensrc,
+ "alfa/omega/A.java",
+ "package alfa.omega; public class A { }");
+
+ populate(bin,
+ "alfa/omega/AA.class",
+ "Ugh, a messy build system (tobefixed) wrote this class file, sjavac must not delete it.");
+
+ compile("--log=debug", "--permit-artifact=bin/alfa/omega/AA.class", "-src", "gensrc", "-d", "bin", serverArg);
+
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/alfa/omega/A.class",
+ "bin/alfa/omega/AA.class",
+ "bin/javac_state");
+ }
+
void removeFrom(Path dir, String... args) throws IOException {
for (String filename : args) {
Path p = dir.resolve(filename);