This commit is contained in:
Lana Steuck 2014-08-28 14:53:49 -07:00
commit 09bd1b2855
198 changed files with 7262 additions and 4276 deletions

View File

@ -68,7 +68,7 @@ javac.no.jdk.warnings = -XDignore.symbol.file=true
# 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/

View File

@ -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>

View File

@ -2195,16 +2195,6 @@ public class Types {
}
}
@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);

View File

@ -919,14 +919,14 @@ public class Attr extends JCTree.Visitor {
// 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");

View File

@ -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.HashSet;
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 @@ public class BuildState {
*/
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 @@ public class BuildState {
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 @@ public class BuildState {
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 @@ public class BuildState {
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 @@ public class BuildState {
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());
}
}

View File

@ -36,19 +36,18 @@ import java.util.Map;
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 @@ public class CleanProperties implements Transformer
// 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 @@ public class CleanProperties implements Transformer
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 @@ public class CleanProperties implements Transformer
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 {

View File

@ -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 @@ import java.util.Set;
* 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;

View File

@ -30,13 +30,12 @@ import java.io.PrintStream;
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 @@ public class CompileJavaPackages implements Transformer {
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 @@ public class CompileJavaPackages implements Transformer {
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 @@ public class CompileJavaPackages implements Transformer {
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 @@ public class CompileJavaPackages implements Transformer {
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 @@ public class CompileJavaPackages implements Transformer {
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;
}
}

View File

@ -38,20 +38,19 @@ import java.util.HashSet;
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 class CompileProperties implements Transformer
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,

View File

@ -32,16 +32,16 @@ import java.util.HashSet;
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 class CopyFile implements Transformer {
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,

View File

@ -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.net.URI;
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 @@ public class JavacState
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 @@ public class JavacState
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 @@ public class JavacState
// 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 @@ public class JavacState
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 @@ public class JavacState
// 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 class JavacState
*/
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 @@ public class JavacState
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 @@ public class JavacState
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 @@ public class JavacState
/**
* 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 @@ public class JavacState
/**
* 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 @@ public class JavacState
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 @@ public class JavacState
* 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 @@ public class JavacState
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 @@ public class JavacState
* 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.

View File

@ -31,10 +31,10 @@ import java.io.PrintStream;
* 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;

View File

@ -31,19 +31,21 @@ import java.util.*;
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 @@ public class Main {
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 @@ public class Main {
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 @@ public class Main {
// 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 @@ public class Main {
// 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 @@ public class Main {
// 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 @@ public class Main {
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")) {

View File

@ -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 @@ import java.util.Set;
* 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;

View File

@ -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.Iterator;
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 @@ import java.util.Set;
* 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 class Package implements Comparable<Package> {
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 class Package implements Comparable<Package> {
}
public void setArtifacts(Set<URI> as) {
assert(!artifacts.isEmpty());
Assert.check(!artifacts.isEmpty());
artifacts = new HashMap<>();
addArtifacts(as);
}

View File

@ -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 @@ package com.sun.tools.sjavac;
/**
* 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;

View File

@ -37,10 +37,10 @@ import java.util.Map;
* 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.

View File

@ -31,7 +31,7 @@ import java.util.Set;
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 @@ import com.sun.tools.sjavac.server.JavacService;
* 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 @@ public interface Transformer
* 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,

View File

@ -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 @@ import java.util.StringTokenizer;
/**
* 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 class Util {
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);
}

View File

@ -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
}
}

View File

@ -30,10 +30,10 @@ import com.sun.tools.javac.code.Symbol;
/** 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 {

View File

@ -34,6 +34,7 @@ import java.util.Map;
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 @@ import com.sun.tools.javac.util.Name;
/** 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 @@ public class Dependencies {
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);

View File

@ -32,29 +32,29 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol;
/** 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 @@ public class JavaCompilerWithDeps extends JavaCompiler {
// 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());
}

View File

@ -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();
}
}

View File

@ -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 @@ import javax.lang.model.util.ElementScanner9;
/** 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> {

View File

@ -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 @@ import com.sun.tools.javac.code.Symbol;
/** 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 {

View File

@ -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);
}

View File

@ -22,7 +22,6 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.comp;
import java.io.File;
@ -32,6 +31,7 @@ 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;
@ -41,26 +41,21 @@ 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.javac.util.Options;
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.Sjavac;
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);
}
/**
* 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() {
@ -75,6 +70,7 @@ public class JavacServiceImpl implements JavacService {
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);
@ -82,7 +78,12 @@ public class JavacServiceImpl implements JavacService {
Context context = new Context();
ResolveWithDeps.preRegister(context);
AttrWithDeps.preRegister(context);
JavaCompilerWithDeps.preRegister(context, this);
JavaCompilerWithDeps.preRegister(context, new SjavacErrorHandler() {
@Override
public void logError(String msg) {
forcedExit.set(true);
}
});
// Now setup the actual compilation....
CompilationResult compilationResult = new CompilationResult(0);
@ -100,13 +101,6 @@ public class JavacServiceImpl implements JavacService {
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();
@ -120,14 +114,20 @@ public class JavacServiceImpl implements JavacService {
smartFileManager.cleanArtifacts();
smartFileManager.setLog(stdout);
// Do the compilation!
CompilationTask task = compiler.getTask(stderr, smartFileManager, null, Arrays.asList(args), null, compilationUnits, context);
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) {
stderr.println(e.getMessage());
stderrLog.append(e.getMessage());
forcedExit.set(true);
}
@ -139,8 +139,22 @@ public class JavacServiceImpl implements JavacService {
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 "";
}
}

View File

@ -37,7 +37,6 @@ import javax.tools.*;
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 @@ import com.sun.tools.javac.util.ListBuffer;
* 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 class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
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 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
String t = uri.toString();
if (t.startsWith("jar:")
|| t.endsWith(".class")
|| visibleSources.contains(uri))
{
|| visibleSources.contains(uri)) {
filteredFiles.add(f);
}
}
@ -128,9 +124,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
@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 class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
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 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
@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 class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
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) &&

View File

@ -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 @@ import javax.tools.JavaFileObject;
* 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 {

View File

@ -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 @@ import javax.tools.JavaFileObject;
* 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 {

View File

@ -27,6 +27,12 @@ package com.sun.tools.sjavac.options;
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 */

View File

@ -47,6 +47,11 @@ import com.sun.tools.sjavac.Transformer;
* 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 @@ public enum Option {
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 @@ public enum Option {
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;

View File

@ -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 @@ public abstract class OptionHelper {
/** 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 @@ public abstract class OptionHelper {
/** 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 @@ public abstract class OptionHelper {
* @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:

View File

@ -32,16 +32,23 @@ import java.util.Collection;
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 @@ public class Options {
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 @@ public class Options {
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 @@ public class Options {
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 @@ public class Options {
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 @@ public class Options {
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 @@ public class Options {
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 @@ public class Options {
boolean headerProvided = false;
boolean genSrcProvided = false;
boolean stateProvided = false;
@Override
public void reportError(String msg) {
@ -398,9 +416,14 @@ public class Options {
sourceReferenceList = referenceList;
}
@Override
public void permitArtifact(String f) {
permitted_artifacts.add(f);
}
@Override
public void permitUnidentifiedArtifacts() {
permitUnidentifiedArtifact = true;
permitUnidentifiedArtifacts = true;
}
@Override
@ -465,6 +488,16 @@ public class Options {
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) {

View File

@ -37,6 +37,11 @@ import com.sun.tools.sjavac.Source;
/**
* 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 {

View File

@ -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) {

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}

View File

@ -33,6 +33,7 @@ import java.nio.channels.ClosedChannelException;
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 @@ import com.sun.tools.sjavac.Log;
* 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 @@ class PortFile {
* 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 @@ class PortFile {
/**
* Lock the port file.
*/
void lock() throws IOException {
public void lock() throws IOException {
lock = channel.lock();
}
@ -115,7 +115,7 @@ class PortFile {
containsPortInfo = false;
}
}
} catch (Exception e) {
} catch (IOException e) {
containsPortInfo = false;
}
}
@ -131,7 +131,7 @@ class PortFile {
* 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 @@ class PortFile {
* If so, then we can acquire the server cookie.
*/
public long getCookie() {
assert(containsPortInfo);
Assert.check(containsPortInfo);
return serverCookie;
}
@ -147,7 +147,7 @@ class PortFile {
* 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 @@ class PortFile {
* Unlock the port file.
*/
public void unlock() throws IOException {
assert(lock != null);
Assert.check(lock != null);
lock.release();
lock = null;
}

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -22,7 +22,6 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.io.File;
@ -30,7 +29,16 @@ import java.net.URI;
import java.util.List;
import java.util.Set;
public interface JavacService {
/**
* 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();
@ -40,4 +48,7 @@ public interface JavacService {
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources);
void shutdown();
String serverSettings();
}

View File

@ -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();
}
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -38,6 +38,7 @@ import java.lang.ref.SoftReference;
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 @@ public abstract class JavadocTester {
break;
}
}
out.println("args: " + Arrays.toString(args));
// log.setOutDir(outputDir);
outputDirectoryCheck.check(outputDir);

View File

@ -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.Files;
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 @@ public class CheckAptIsRemovedTest {
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();
}
}

View File

@ -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 class CheckEBCDICLocaleTest {
}
public void test() throws Exception {
String native2asciiBinary = Paths.get(
System.getProperty("test.jdk"),"bin", "native2ascii").toString();
ToolBox tb = new ToolBox();
Path native2asciiBinary = tb.getJDKTool("native2ascii");
ToolBox.createJavaFileFromSource(TestSrc);
Files.createDirectory(Paths.get("output"));
tb.writeFile("Test.java", TestSrc);
tb.createDirectories("output");
ToolBox.AnyToolArgs nativeCmdParams =
new ToolBox.AnyToolArgs()
.appendArgs(native2asciiBinary)
.appendArgs(ToolBox.testToolVMOpts)
.appendArgs("-reverse", "-encoding", "IBM1047", "Test.java",
"output/Test.java");
ToolBox.executeCommand(nativeCmdParams);
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);
}
}

View File

@ -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);
}
}

View File

@ -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 @@ public class AnonymousSubclassTest {
"}";
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");
}
}

View File

@ -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 @@ public class ClassPathTest {
"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 @@ public class ClassPathTest {
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 @@ public class ClassPathTest {
// 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);
}
}

View File

@ -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 @@ public class ConstFoldTest {
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 @@ public class ConstFoldTest {
final String regex = "\\sif(?:null|nonnull|eq|ne){1}\\s";
void run() throws Exception {
URL url = ConstFoldTest.class.getResource("ConstFoldTest$CFTest.class");
String result = ToolBox.javap(new ToolBox.JavaToolArgs().setAllArgs("-c", url.getFile()));
System.out.println(result);
ToolBox tb = new ToolBox();
List<String> bad_codes = ToolBox.grep(regex, result, "\n");
URL url = ConstFoldTest.class.getResource("ConstFoldTest$CFTest.class");
List<String> result = tb.new JavapTask()
.options("-c")
.classes(url.getFile())
.run()
.write(ToolBox.OutputKind.DIRECT)
.getOutputLines(ToolBox.OutputKind.DIRECT);
List<String> bad_codes = tb.grep(regex, result);
if (!bad_codes.isEmpty()) {
for (String code : bad_codes)
System.out.println("Bad OpCode Found: " + code);

View File

@ -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 @@ public class ExtDirTest {
"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"});
tb.new JavacTask()
.outdir(".")
.sources(ExtDirTestClass2Src)
.run();
javacParams.setSources(ExtDirTestClass2Src);
ToolBox.javac(javacParams);
tb.new JarTask("pkg2.jar")
.manifest(jar2Manifest)
.files("pkg2/ExtDirTestClass2.class")
.run();
ToolBox.writeFile(Paths.get("pkg2", "MANIFEST.MF"), jar2Manifest);
jarGenerator.run(new String[] {"cfm", "pkg2.jar", "pkg2/MANIFEST.MF",
"pkg2/ExtDirTestClass2.class"});
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");
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"));
Files.delete(Paths.get("pkg1.jar"));
Files.delete(Paths.get("pkg2.jar"));
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 {
tb.new JavacTask()
.outdir(".")
.options("-extdirs", "ext1")
.sources(ExtDirTest_1Src)
.run()
.writeAll();
//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" + File.pathSeparator + "ext2")
.sources(ExtDirTest_2Src)
.run();
//javac -extdirs ext1:ext2 ExtDirTest_2.java
params.setOptions("-d", ".", "-extdirs", "ext1" + File.pathSeparator + "ext2")
.setSources(ExtDirTest_2Src);
ToolBox.javac(params);
//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();
}
}

View File

@ -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 class IncorrectInheritanceTest {
}
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();
}
}

View File

@ -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();
// "${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.writeFile(MissingIncludeFile, MissingIncludeSrc);
tb.new JavacTask(ToolBox.Mode.CMDLINE)
.options("@/nonexistent_file")
.files(MissingIncludeFile)
.run(ToolBox.Expect.FAIL);
}
}

View File

@ -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();
}
}

View File

@ -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 @@ public class ProtectedInnerClassesTest {
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);
tb.new JavacTask()
.outdir(".")
.sources(protectedInnerClass1Src, protectedInnerClass2Src)
.run();
ToolBox.javac(javacParams);
//"${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);
}
}

View File

@ -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 class AssertionFailureTest {
"}";
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();
}
}

View File

@ -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 @@ public class DebugPointerAtBadPositionTest {
}
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 {

View File

@ -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 @@ public class InlinedFinallyConfuseDebuggersTest {
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 @@ public class InlinedFinallyConfuseDebuggersTest {
}
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 {

View File

@ -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 class CheckRejectProfileBCPOptionsIfUsedTogetherTest {
"}";
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");
}

View File

@ -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 @@ public class CompilerCrashWhenMixingBinariesAndSourcesTest {
" 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();
ToolBox.rm("A.class");
ToolBox.rm("A$1.class");
ToolBox.rm("C.class");
ToolBox.rm("D.class");
tb.new JavacTask()
.sources(ASource, BSource, CSource, DSource)
.run();
javacParams = new ToolBox.JavaToolArgs()
.setOptions("-cp", ".")
.setSources(ASource, CSource, DSource);
ToolBox.javac(javacParams);
tb.deleteFiles("A.class", "A$1.class", "C.class", "D.class");
tb.new JavacTask()
.classpath(".")
.sources(ASource, CSource, DSource)
.run();
}
}

View File

@ -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 @@ public class CompileErrorWithIteratorTest {
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();
}
}

View File

@ -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 @@ public class WrongLNTForLambdaTest {
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 @@ public class WrongLNTForLambdaTest {
}
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 {

View File

@ -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 @@ public class IncorrectSignatureDeterminationForInnerClassesTest {
}
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();
}
}

View File

@ -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 @@ public class NoDeadCodeGenerationOnTrySmtTest {
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 @@ public class NoDeadCodeGenerationOnTrySmtTest {
}
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 {

View File

@ -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 class ExceptionInferenceFromClassFileTest {
"}";
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();
}
}

View File

@ -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;

View File

@ -0,0 +1,2 @@
package-info.java:24:1: compiler.err.annotation.type.not.applicable
1 error

View File

@ -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 {

View File

@ -0,0 +1,2 @@
NoAnnotationMethods.java:10:9: compiler.err.intf.annotation.member.clash: annotationType(), java.lang.annotation.Annotation
1 error

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -0,0 +1,2 @@
NoObjectMethods.java:10:9: compiler.err.intf.annotation.member.clash: clone(), java.lang.Object
1 error

View File

@ -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)

View File

@ -0,0 +1,2 @@
ObjectMembers.java:10:16: compiler.err.no.annotation.member: hashCode, ObjectMembers
1 error

View File

@ -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;

View File

@ -0,0 +1,2 @@
OverrideNo.java:16:5: compiler.err.method.does.not.override.superclass
1 error

View File

@ -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

View File

@ -0,0 +1,2 @@
Package.java:10:1: compiler.err.pkg.annotations.sb.in.package-info.java
1 error

View File

@ -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.*;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -0,0 +1,2 @@
Scope.java:12:4: compiler.err.cant.resolve: kindname.variable, red, ,
1 error

View File

@ -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;

View File

@ -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

View File

@ -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 {
}

View File

@ -0,0 +1,2 @@
WrongTarget.java:16:1: compiler.err.annotation.type.not.applicable
1 error

View File

@ -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;

View File

@ -0,0 +1,2 @@
WrongTarget2.java:12:6: compiler.err.annotation.type.not.applicable
1 error

View File

@ -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 {

View File

@ -0,0 +1,2 @@
WrongValue.java:25:5: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TestM3, TestM2)
1 error

View File

@ -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 }

Some files were not shown because too many files have changed in this diff Show More