Merge
This commit is contained in:
commit
09bd1b2855
@ -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/
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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")) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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> {
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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 "";
|
||||
}
|
||||
|
||||
}
|
@ -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) &&
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -0,0 +1,2 @@
|
||||
package-info.java:24:1: compiler.err.annotation.type.not.applicable
|
||||
1 error
|
@ -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 {
|
||||
|
@ -0,0 +1,2 @@
|
||||
NoAnnotationMethods.java:10:9: compiler.err.intf.annotation.member.clash: annotationType(), java.lang.annotation.Annotation
|
||||
1 error
|
@ -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 {
|
||||
|
3
langtools/test/tools/javac/annotations/neg/NoClone.out
Normal file
3
langtools/test/tools/javac/annotations/neg/NoClone.out
Normal 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
|
@ -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 {
|
||||
|
@ -0,0 +1,2 @@
|
||||
NoObjectMethods.java:10:9: compiler.err.intf.annotation.member.clash: clone(), java.lang.Object
|
||||
1 error
|
@ -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)
|
||||
|
@ -0,0 +1,2 @@
|
||||
ObjectMembers.java:10:16: compiler.err.no.annotation.member: hashCode, ObjectMembers
|
||||
1 error
|
@ -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;
|
||||
|
@ -0,0 +1,2 @@
|
||||
OverrideNo.java:16:5: compiler.err.method.does.not.override.superclass
|
||||
1 error
|
@ -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
|
||||
|
2
langtools/test/tools/javac/annotations/neg/Package.out
Normal file
2
langtools/test/tools/javac/annotations/neg/Package.out
Normal file
@ -0,0 +1,2 @@
|
||||
Package.java:10:1: compiler.err.pkg.annotations.sb.in.package-info.java
|
||||
1 error
|
@ -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.*;
|
||||
|
2
langtools/test/tools/javac/annotations/neg/Recovery.out
Normal file
2
langtools/test/tools/javac/annotations/neg/Recovery.out
Normal 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
|
@ -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;
|
||||
|
4
langtools/test/tools/javac/annotations/neg/Recovery1.out
Normal file
4
langtools/test/tools/javac/annotations/neg/Recovery1.out
Normal 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
|
@ -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;
|
||||
|
2
langtools/test/tools/javac/annotations/neg/Scope.out
Normal file
2
langtools/test/tools/javac/annotations/neg/Scope.out
Normal file
@ -0,0 +1,2 @@
|
||||
Scope.java:12:4: compiler.err.cant.resolve: kindname.variable, red, ,
|
||||
1 error
|
@ -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;
|
||||
|
4
langtools/test/tools/javac/annotations/neg/Syntax1.out
Normal file
4
langtools/test/tools/javac/annotations/neg/Syntax1.out
Normal 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
|
@ -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 {
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
WrongTarget.java:16:1: compiler.err.annotation.type.not.applicable
|
||||
1 error
|
@ -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;
|
||||
|
@ -0,0 +1,2 @@
|
||||
WrongTarget2.java:12:6: compiler.err.annotation.type.not.applicable
|
||||
1 error
|
@ -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 {
|
||||
|
@ -0,0 +1,2 @@
|
||||
WrongValue.java:25:5: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TestM3, TestM2)
|
||||
1 error
|
@ -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
Loading…
Reference in New Issue
Block a user