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

View File

@ -68,7 +68,7 @@ javac.no.jdk.warnings = -XDignore.symbol.file=true
# set the following to -version to verify the versions of javac being used # set the following to -version to verify the versions of javac being used
javac.version.opt = javac.version.opt =
# in time, there should be no exceptions to -Xlint:all # 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 # options for the <javadoc> task for javac
#javadoc.jls3.url=http://java.sun.com/docs/books/jls/ #javadoc.jls3.url=http://java.sun.com/docs/books/jls/

View File

@ -6,10 +6,14 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/bootstrap/gensrc" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/bootstrap/gensrc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/genstubs" 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$/src/java.base" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" type="java-test-resource" /> <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> </content>
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
</component> </component>
</module> </module>

View File

@ -2195,16 +2195,6 @@ public class Types {
} }
} }
@Override
public Type visitWildcardType(WildcardType t, Boolean recurse) {
final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
Type erased = erasure(wildUpperBound(t), recurse);
if (!annos.isEmpty()) {
erased = erased.annotatedType(annos);
}
return erased;
}
@Override @Override
public Type visitClassType(ClassType t, Boolean recurse) { public Type visitClassType(ClassType t, Boolean recurse) {
Type erased = t.tsym.erasure(Types.this); Type erased = t.tsym.erasure(Types.this);

View File

@ -919,14 +919,14 @@ public class Attr extends JCTree.Visitor {
// Empty bodies are only allowed for // Empty bodies are only allowed for
// abstract, native, or interface methods, or for methods // abstract, native, or interface methods, or for methods
// in a retrofit signature class. // 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 (tree.defaultValue != null) {
if ((owner.flags() & ANNOTATION) == 0) if ((owner.flags() & ANNOTATION) == 0)
log.error(tree.pos(), log.error(tree.pos(),
"default.allowed.in.intf.annotation.member"); "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) { } else if ((tree.sym.flags() & ABSTRACT) != 0 && !isDefaultMethod) {
if ((owner.flags() & INTERFACE) != 0) { if ((owner.flags() & INTERFACE) != 0) {
log.error(tree.body.pos(), "intf.meth.cant.have.body"); log.error(tree.body.pos(), "intf.meth.cant.have.body");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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.Map;
import java.util.Set; import java.util.Set;
import com.sun.tools.javac.util.Assert;
/** /**
* The build state class captures the source code and generated artifacts * The build state class captures the source code and generated artifacts
* from a build. There are usually two build states, the previous one (prev), * from a build. There are usually two build states, the previous one (prev),
* loaded from the javac_state file, and the current one (now). * loaded from the javac_state file, and the current one (now).
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class BuildState { public class BuildState {
private Map<String,Module> modules = new HashMap<>(); private Map<String,Module> modules = new HashMap<>();
@ -75,7 +77,7 @@ public class BuildState {
*/ */
Module findModuleFromPackageName(String pkg) { Module findModuleFromPackageName(String pkg) {
int cp = pkg.indexOf(':'); int cp = pkg.indexOf(':');
assert(cp != -1); Assert.check(cp != -1);
String mod = pkg.substring(0, cp); String mod = pkg.substring(0, cp);
return lookupModule(mod); return lookupModule(mod);
} }
@ -94,7 +96,7 @@ public class BuildState {
for (Map.Entry<String,Package> j : i.packages().entrySet()) { for (Map.Entry<String,Package> j : i.packages().entrySet()) {
Package p = packages.get(j.getKey()); Package p = packages.get(j.getKey());
// Check that no two different packages are stored under same name. // 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) { if (p == null) {
p = j.getValue(); p = j.getValue();
packages.put(j.getKey(),j.getValue()); packages.put(j.getKey(),j.getValue());
@ -102,7 +104,7 @@ public class BuildState {
for (Map.Entry<String,Source> k : p.sources().entrySet()) { for (Map.Entry<String,Source> k : p.sources().entrySet()) {
Source s = sources.get(k.getKey()); Source s = sources.get(k.getKey());
// Check that no two different sources are stored under same name. // 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) { if (s == null) {
s = k.getValue(); s = k.getValue();
sources.put(k.getKey(), k.getValue()); sources.put(k.getKey(), k.getValue());
@ -111,7 +113,7 @@ public class BuildState {
for (Map.Entry<String,File> g : p.artifacts().entrySet()) { for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
File f = artifacts.get(g.getKey()); File f = artifacts.get(g.getKey());
// Check that no two artifacts are stored under the same file. // 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) { if (f == null) {
f = g.getValue(); f = g.getValue();
artifacts.put(g.getKey(), g.getValue()); artifacts.put(g.getKey(), g.getValue());
@ -134,13 +136,13 @@ public class BuildState {
for (Map.Entry<String,Package> j : i.packages().entrySet()) { for (Map.Entry<String,Package> j : i.packages().entrySet()) {
Package p = packages.get(j.getKey()); Package p = packages.get(j.getKey());
// Check that no two different packages are stored under same name. // 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(); p = j.getValue();
packages.put(j.getKey(),j.getValue()); packages.put(j.getKey(),j.getValue());
for (Map.Entry<String,File> g : p.artifacts().entrySet()) { for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
File f = artifacts.get(g.getKey()); File f = artifacts.get(g.getKey());
// Check that no two artifacts are stored under the same file. // 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()); artifacts.put(g.getKey(), g.getValue());
} }
} }

View File

@ -36,19 +36,18 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import com.sun.tools.sjavac.options.Options; 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. * The clean properties transform should not be necessary.
* Eventually we will cleanup the property file sources in the OpenJDK instead. * Eventually we will cleanup the property file sources in the OpenJDK instead.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class CleanProperties implements Transformer public class CleanProperties implements Transformer {
{
public void setExtra(String e) { public void setExtra(String e) {
// Any extra information is ignored for clean properties. // 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. // Any extra information is ignored for clean properties.
} }
public boolean transform(JavacService javacService, public boolean transform(Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs, Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses, Map<URI,Set<String>> visibleClasses,
@ -70,8 +69,7 @@ public class CleanProperties implements Transformer
boolean incremental, boolean incremental,
int numCores, int numCores,
PrintStream out, PrintStream out,
PrintStream err) PrintStream err) {
{
boolean rc = true; boolean rc = true;
for (String pkgName : pkgSrcs.keySet()) { for (String pkgName : pkgSrcs.keySet()) {
String pkgNameF = pkgName.replace('.',File.separatorChar); String pkgNameF = pkgName.replace('.',File.separatorChar);
@ -87,9 +85,12 @@ public class CleanProperties implements Transformer
return rc; return rc;
} }
boolean clean(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel, boolean clean(String pkgName,
Map<String,Set<URI>> packageArtifacts) String pkgNameF,
{ File src,
File destRoot,
int debugLevel,
Map<String,Set<URI>> packageArtifacts) {
// Load the properties file. // Load the properties file.
Properties p = new Properties(); Properties p = new Properties();
try { try {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 * 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. * the total number of sources/packages to be compiled for this sjavac invocation.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class CompileChunk implements Comparable<CompileChunk> { public class CompileChunk implements Comparable<CompileChunk> {
public int numPackages; public int numPackages;

View File

@ -30,13 +30,12 @@ import java.io.PrintStream;
import java.net.URI; import java.net.URI;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.Map; import java.util.Map;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.server.CompilationResult; 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; import com.sun.tools.sjavac.server.SysInfo;
/** /**
@ -67,7 +66,7 @@ public class CompileJavaPackages implements Transformer {
args = a; args = a;
} }
public boolean transform(final JavacService javacService, public boolean transform(final Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
final Set<URI> visibleSources, final Set<URI> visibleSources,
final Map<URI,Set<String>> visibleClasses, final Map<URI,Set<String>> visibleClasses,
@ -86,18 +85,12 @@ public class CompileJavaPackages implements Transformer {
boolean concurrentCompiles = true; boolean concurrentCompiles = true;
// Fetch the id. // Fetch the id.
String idOpt = Util.extractStringOption("id", args.getServerConf()); final String id = Util.extractStringOption("id", sjavac.serverSettings());
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;
// Only keep portfile and sjavac settings.. // 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! // Get maximum heap size from the server!
SysInfo sysinfo = javacService.getSysInfo(); SysInfo sysinfo = sjavac.getSysInfo();
if (sysinfo.numCores == -1) { if (sysinfo.numCores == -1) {
Log.error("Could not query server for sysinfo!"); Log.error("Could not query server for sysinfo!");
return false; return false;
@ -222,7 +215,7 @@ public class CompileJavaPackages implements Transformer {
requests[i] = new Thread() { requests[i] = new Thread() {
@Override @Override
public void run() { public void run() {
rn[ii] = javacService.compile("n/a", rn[ii] = sjavac.compile("n/a",
id + "-" + ii, id + "-" + ii,
args.prepJavacArgs(), args.prepJavacArgs(),
Collections.<File>emptyList(), Collections.<File>emptyList(),
@ -253,6 +246,8 @@ public class CompileJavaPackages implements Transformer {
requests[ii].run(); requests[ii].run();
// If there was an error, then stop early when running single threaded. // If there was an error, then stop early when running single threaded.
if (rn[i].returnCode != 0) { if (rn[i].returnCode != 0) {
Log.info(rn[i].stdout);
Log.error(rn[i].stderr);
return false; return false;
} }
} }
@ -269,6 +264,8 @@ public class CompileJavaPackages implements Transformer {
for (int i=0; i<numCompiles; ++i) { for (int i=0; i<numCompiles; ++i) {
if (compileChunks[i].srcs.size() > 0) { if (compileChunks[i].srcs.size() > 0) {
if (rn[i].returnCode != 0) { if (rn[i].returnCode != 0) {
Log.info(rn[i].stdout);
Log.error(rn[i].stderr);
rc = false; rc = false;
} }
} }

View File

@ -38,20 +38,19 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import com.sun.tools.sjavac.options.Options; 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. * Compile properties transform a properties file into a Java source file.
* Java has built in support for reading properties from either a text file * Java has built in support for reading properties from either a text file
* in the source or a compiled java source file. * in the source or a compiled java source file.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * 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: // Any extra information passed from the command line, for example if:
// -tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle // -tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
// then extra will be "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 void setExtra(Options a) {
} }
public boolean transform(JavacService javacService, public boolean transform(Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs, Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses, Map<URI,Set<String>> visibleClasses,

View File

@ -32,16 +32,16 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import com.sun.tools.sjavac.options.Options; 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 . * The copy file transform simply copies a matching file from -src to -d .
* Such files are typically images, xml documents and other data files. * Such files are typically images, xml documents and other data files.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class CopyFile implements Transformer { public class CopyFile implements Transformer {
@ -51,7 +51,7 @@ public class CopyFile implements Transformer {
public void setExtra(Options a) { public void setExtra(Options a) {
} }
public boolean transform(JavacService javacService, public boolean transform(Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSrcs, Set<URI> visibleSrcs,
Map<URI,Set<String>> visibleClasses, Map<URI,Set<String>> visibleClasses,

View File

@ -26,7 +26,6 @@
package com.sun.tools.sjavac; package com.sun.tools.sjavac;
import java.io.*; import java.io.*;
import java.nio.file.Path;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
@ -39,20 +38,18 @@ import java.net.URI;
import java.util.*; import java.util.*;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.options.SourceLocation; import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.JavacService;
/** /**
* The javac state class maintains the previous (prev) and the current (now) * The javac state class maintains the previous (prev) and the current (now)
* build states and everything else that goes into the javac_state file. * build states and everything else that goes into the javac_state file.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class JavacState public class JavacState {
{
// The arguments to the compile. If not identical, then it cannot // The arguments to the compile. If not identical, then it cannot
// be an incremental build! // be an incremental build!
String theArgs; String theArgs;
@ -60,7 +57,6 @@ public class JavacState
int numCores; int numCores;
// The bin_dir/javac_state // The bin_dir/javac_state
private String javacStateFilename;
private File javacState; private File javacState;
// The previous build state is loaded from javac_state // The previous build state is loaded from javac_state
@ -99,7 +95,7 @@ public class JavacState
private Set<String> recompiledPackages; private Set<String> recompiledPackages;
// The output directories filled with tasty artifacts. // 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. // The current status of the file system.
private Set<File> binArtifacts; private Set<File> binArtifacts;
@ -128,7 +124,11 @@ public class JavacState
// Where to send stdout and stderr. // Where to send stdout and stderr.
private PrintStream out, err; 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; out = o;
err = e; err = e;
numCores = options.getNumCores(); numCores = options.getNumCores();
@ -136,8 +136,8 @@ public class JavacState
binDir = Util.pathToFile(options.getDestDir()); binDir = Util.pathToFile(options.getDestDir());
gensrcDir = Util.pathToFile(options.getGenSrcDir()); gensrcDir = Util.pathToFile(options.getGenSrcDir());
headerDir = Util.pathToFile(options.getHeaderDir()); headerDir = Util.pathToFile(options.getHeaderDir());
javacStateFilename = binDir.getPath()+File.separator+"javac_state"; stateDir = Util.pathToFile(options.getStateDir());
javacState = new File(javacStateFilename); javacState = new File(stateDir, "javac_state");
if (removeJavacState && javacState.exists()) { if (removeJavacState && javacState.exists()) {
javacState.delete(); javacState.delete();
} }
@ -148,7 +148,7 @@ public class JavacState
// We do not want to risk building a broken incremental build. // 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, // 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. // we avoid deleting files here, if the option --permit-unidentified-classes was supplied.
if (!options.isUnidentifiedArtifactPermitted()) { if (!options.areUnidentifiedArtifactsPermitted()) {
deleteContents(binDir); deleteContents(binDir);
deleteContents(gensrcDir); deleteContents(gensrcDir);
deleteContents(headerDir); deleteContents(headerDir);
@ -268,7 +268,7 @@ public class JavacState
*/ */
public void save() throws IOException { public void save() throws IOException {
if (!needsSaving) return; if (!needsSaving) return;
try (FileWriter out = new FileWriter(javacStateFilename)) { try (FileWriter out = new FileWriter(javacState)) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
long millisNow = System.currentTimeMillis(); long millisNow = System.currentTimeMillis();
Date d = new Date(millisNow); Date d = new Date(millisNow);
@ -311,7 +311,7 @@ public class JavacState
boolean newCommandLine = false; boolean newCommandLine = false;
boolean syntaxError = false; boolean syntaxError = false;
try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) { try (BufferedReader in = new BufferedReader(new FileReader(db.javacState))) {
for (;;) { for (;;) {
String l = in.readLine(); String l = in.readLine();
if (l==null) break; if (l==null) break;
@ -512,7 +512,8 @@ public class JavacState
allKnownArtifacts.add(javacState); allKnownArtifacts.add(javacState);
for (File f : binArtifacts) { 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."); Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
f.delete(); f.delete();
} }
@ -605,13 +606,16 @@ public class JavacState
/** /**
* Recursively delete a directory and all its contents. * Recursively delete a directory and all its contents.
*/ */
private static void deleteContents(File dir) { private void deleteContents(File dir) {
if (dir != null && dir.exists()) { if (dir != null && dir.exists()) {
for (File f : dir.listFiles()) { for (File f : dir.listFiles()) {
if (f.isDirectory()) { if (f.isDirectory()) {
deleteContents(f); 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! * 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, Options args,
Set<String> recentlyCompiled, Set<String> recentlyCompiled,
boolean[] rcValue) { boolean[] rcValue) {
@ -656,7 +660,7 @@ public class JavacState
suffixRules.put(".java", compileJavaPackages); suffixRules.put(".java", compileJavaPackages);
compileJavaPackages.setExtra(args); compileJavaPackages.setExtra(args);
rcValue[0] = perform(javacService, binDir, suffixRules); rcValue[0] = perform(sjavac, binDir, suffixRules);
recentlyCompiled.addAll(taintedPackages()); recentlyCompiled.addAll(taintedPackages());
clearTaintedPackages(); clearTaintedPackages();
boolean again = !packagesWithChangedPublicApis.isEmpty(); boolean again = !packagesWithChangedPublicApis.isEmpty();
@ -686,10 +690,9 @@ public class JavacState
* For all packages, find all sources belonging to the package, group the sources * 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. * 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, File outputDir,
Map<String,Transformer> suffixRules) Map<String,Transformer> suffixRules) {
{
boolean rc = true; boolean rc = true;
// Group sources based on transforms. A source file can only belong to a single transform. // Group sources based on transforms. A source file can only belong to a single transform.
Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<>(); Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<>();
@ -713,7 +716,7 @@ public class JavacState
Map<String,String> packagePublicApis = Map<String,String> packagePublicApis =
Collections.synchronizedMap(new HashMap<String, String>()); Collections.synchronizedMap(new HashMap<String, String>());
boolean r = t.transform(javacService, boolean r = t.transform(sjavac,
srcs, srcs,
visibleSrcs, visibleSrcs,
visibleClasses, visibleClasses,
@ -791,9 +794,7 @@ public class JavacState
* Used to detect bugs where the makefile and sjavac have different opinions on which files * Used to detect bugs where the makefile and sjavac have different opinions on which files
* should be compiled. * should be compiled.
*/ */
public void compareWithMakefileList(File makefileSourceList) public void compareWithMakefileList(File makefileSourceList) throws ProblemException {
throws ProblemException
{
// If we are building on win32 using for example cygwin the paths in the makefile source list // 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:\.... // might be /cygdrive/c/.... which does not match c:\....
// We need to adjust our calculated sources to be identical, if necessary. // We need to adjust our calculated sources to be identical, if necessary.

View File

@ -31,10 +31,10 @@ import java.io.PrintStream;
* Utility class only for sjavac logging. * Utility class only for sjavac logging.
* The log level can be set using for example --log=DEBUG on the sjavac command line. * 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. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class Log { public class Log {
private static PrintStream out, err; private static PrintStream out, err;

View File

@ -31,19 +31,21 @@ import java.util.*;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Files; 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.Options;
import com.sun.tools.sjavac.options.SourceLocation; import com.sun.tools.sjavac.options.SourceLocation;
import com.sun.tools.sjavac.server.JavacService; import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.JavacServer; import com.sun.tools.sjavac.server.SjavacServer;
import com.sun.tools.sjavac.server.JavacServiceClient;
/** /**
* The main class of the smart javac wrapper tool. * The main class of the smart javac wrapper tool.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class Main { public class Main {
@ -163,13 +165,19 @@ public class Main {
return; return;
} }
// Spawn a background server. // Spawn a background server.
int rc = JavacServer.startServer(args[0], System.err); try {
System.exit(rc); 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(); Main main = new Main();
int rc = main.go(args, System.out, System.err); int rc = main.go(args, System.out, System.err);
// Remove the portfile, but only if this background=false was used. // Remove the portfile, but only if this background=false was used.
JavacServer.cleanup(args); SjavacServer.cleanup(args);
System.exit(rc); System.exit(rc);
} }
@ -205,6 +213,9 @@ public class Main {
if (!createIfMissing(options.getDestDir())) if (!createIfMissing(options.getDestDir()))
return -1; return -1;
if (!createIfMissing(options.getStateDir()))
return -1;
Path gensrc = options.getGenSrcDir(); Path gensrc = options.getGenSrcDir();
if (gensrc != null && !createIfMissing(gensrc)) if (gensrc != null && !createIfMissing(gensrc))
return -1; return -1;
@ -302,7 +313,7 @@ public class Main {
// For examples, files that have been manually copied into these dirs. // 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 // 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. // in javac_state) have already been removed when the javac_state was loaded.
if (!options.isUnidentifiedArtifactPermitted()) { if (!options.areUnidentifiedArtifactsPermitted()) {
javac_state.removeUnidentifiedArtifacts(); javac_state.removeUnidentifiedArtifacts();
} }
// Go through all sources and taint all packages that miss artifacts. // 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. // Collect the name of all compiled packages.
Set<String> recently_compiled = new HashSet<>(); Set<String> recently_compiled = new HashSet<>();
boolean[] rc = new boolean[1]; boolean[] rc = new boolean[1];
Sjavac sjavac;
boolean background = Util.extractBooleanOption("background", options.getServerConf(), true);
do { do {
// Clean out artifacts in tainted packages. // Clean out artifacts in tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages(); javac_state.deleteClassArtifactsInTaintedPackages();
// Create a JavacService to delegate the actual compilation to. // Create an sjavac implementation to be used for compilation
// Currently sjavac always connects to a server through a socket if (background) {
// regardless if sjavac runs as a background service or not. sjavac = new SjavacClient(options);
// This will most likely change in the future. } else {
JavacService javacService = new JavacServiceClient(options.getServerConf()); int poolsize = Util.extractIntOption("poolsize", options.getServerConf());
again = javac_state.performJavaCompilations(javacService, options, recently_compiled, rc); 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; if (!rc[0]) break;
} while (again); } while (again);
// Only update the state if the compile went well. // 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. // Remove artifacts that were generated during the last compile, but not this one.
javac_state.removeSuperfluousArtifacts(recently_compiled); javac_state.removeSuperfluousArtifacts(recently_compiled);
} }
if (!background)
sjavac.shutdown();
return rc[0] ? 0 : -1; return rc[0] ? 0 : -1;
} catch (ProblemException e) { } catch (ProblemException e) {
Log.error(e.getMessage()); Log.error(e.getMessage());
@ -375,8 +395,6 @@ public class Main {
err = "Please specify output directory."; err = "Please specify output directory.";
} else if (options.isJavaFilesAmongJavacArgs()) { } else if (options.isJavaFilesAmongJavacArgs()) {
err = "Sjavac does not handle explicit compilation of single .java files."; 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) { } else if (options.getServerConf() == null) {
err = "No server configuration provided."; err = "No server configuration provided.";
} else if (!options.getImplicitPolicy().equals("none")) { } else if (!options.getImplicitPolicy().equals("none")) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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. * 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. * 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. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class Module implements Comparable<Module> { public class Module implements Comparable<Module> {
private String name; private String name;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.sun.tools.javac.util.Assert;
/** /**
* The Package class maintains meta information about a package. * 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 * the visible recompilation of the dependent packages indicates how much circular
* dependencies your code has. * dependencies your code has.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class Package implements Comparable<Package> { public class Package implements Comparable<Package> {
// The module this package belongs to. (There is a legacy module with an empty string name, // 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) { public Package(Module m, String n) {
int c = n.indexOf(":"); int c = n.indexOf(":");
assert(c != -1); Assert.check(c != -1);
String mn = n.substring(0,c); String mn = n.substring(0,c);
assert(m.name().equals(m.name())); Assert.check(m.name().equals(m.name()));
name = n; name = n;
dirname = n.replace('.', File.separatorChar); dirname = n.replace('.', File.separatorChar);
if (m.name().length() > 0) { if (m.name().length() > 0) {
@ -256,7 +257,7 @@ public class Package implements Comparable<Package> {
} }
public void setArtifacts(Set<URI> as) { public void setArtifacts(Set<URI> as) {
assert(!artifacts.isEmpty()); Assert.check(!artifacts.isEmpty());
artifacts = new HashMap<>(); artifacts = new HashMap<>();
addArtifacts(as); addArtifacts(as);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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. * Used to signal serious problems when running sjavac.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class ProblemException extends Exception { public class ProblemException extends Exception {
static final long serialVersionUID = -3387516993124229949L; static final long serialVersionUID = -3387516993124229949L;

View File

@ -37,10 +37,10 @@ import java.util.Map;
* The class also knows how to find source files (scanRoot) given include/exclude * The class also knows how to find source files (scanRoot) given include/exclude
* patterns and a root. * patterns and a root.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class Source implements Comparable<Source> { public class Source implements Comparable<Source> {
// The package the source belongs to. // The package the source belongs to.

View File

@ -31,7 +31,7 @@ import java.util.Set;
import java.util.Map; import java.util.Map;
import com.sun.tools.sjavac.options.Options; 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. * 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) * 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). * 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. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * 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 * The transform method takes a set of package names, mapped to their source files and to the
* pubapis of the packages. * 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 * 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. * number of threads for heavy work.
*/ */
boolean transform(JavacService javacService, boolean transform(Sjavac sjavac,
Map<String,Set<URI>> pkgSrcs, Map<String,Set<URI>> pkgSrcs,
Set<URI> visibleSources, Set<URI> visibleSources,
Map<URI,Set<String>> visibleClasses, Map<URI,Set<String>> visibleClasses,

View File

@ -26,8 +26,6 @@
package com.sun.tools.sjavac; package com.sun.tools.sjavac;
import java.io.File; import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
@ -37,10 +35,10 @@ import java.util.StringTokenizer;
/** /**
* Utilities. * Utilities.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class Util { public class Util {
@ -64,7 +62,8 @@ public class Util {
public static String justPackageName(String pkgName) { public static String justPackageName(String pkgName) {
int c = pkgName.indexOf(":"); int c = pkgName.indexOf(":");
assert(c != -1); if (c == -1)
throw new IllegalArgumentException("Expected ':' in package name (" + pkgName + ")");
return pkgName.substring(c+1); return pkgName.substring(c+1);
} }

View File

@ -0,0 +1,275 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.client;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URI;
import java.util.List;
import java.util.Set;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.ProblemException;
import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.server.CompilationResult;
import com.sun.tools.sjavac.server.PortFile;
import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SjavacServer;
import com.sun.tools.sjavac.server.SysInfo;
import com.sun.tools.sjavac.options.Options;
/**
* Sjavac implementation that delegates requests to a SjavacServer.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class SjavacClient implements Sjavac {
// The id can perhaps be used in the future by the javac server to reuse the
// JavaCompiler instance for several compiles using the same id.
private final String id;
private final String portfileName;
private final String logfile;
private final String stdouterrfile;
private final boolean background;
// Default keepalive for server is 120 seconds.
// I.e. it will accept 120 seconds of inactivity before quitting.
private final int keepalive;
private final int poolsize;
// The sjavac option specifies how the server part of sjavac is spawned.
// If you have the experimental sjavac in your path, you are done. If not, you have
// to point to a com.sun.tools.sjavac.Main that supports --startserver
// for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
private final String sjavacForkCmd;
// Wait 2 seconds for response, before giving up on javac server.
static int CONNECTION_TIMEOUT = 2000;
static int MAX_CONNECT_ATTEMPTS = 3;
static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 2000;
// Store the server conf settings here.
private final String settings;
public SjavacClient(Options options) {
String tmpServerConf = options.getServerConf();
String serverConf = (tmpServerConf!=null)? tmpServerConf : "";
String tmpId = Util.extractStringOption("id", serverConf);
id = (tmpId!=null) ? tmpId : "id"+(((new java.util.Random()).nextLong())&Long.MAX_VALUE);
String p = Util.extractStringOption("portfile", serverConf);
portfileName = (p!=null) ? p : options.getStateDir().toFile().getAbsolutePath()+File.separatorChar+"javac_server";
logfile = Util.extractStringOption("logfile", serverConf, portfileName + ".javaclog");
stdouterrfile = Util.extractStringOption("stdouterrfile", serverConf, portfileName + ".stdouterr");
background = Util.extractBooleanOption("background", serverConf, true);
sjavacForkCmd = Util.extractStringOption("sjavac", serverConf, "sjavac");
int poolsize = Util.extractIntOption("poolsize", serverConf);
keepalive = Util.extractIntOption("keepalive", serverConf, 120);
this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
settings = (serverConf.equals("")) ? "id="+id+",portfile="+portfileName : serverConf;
}
/**
* Hand out the server settings.
* @return The server settings, possibly a default value.
*/
public String serverSettings() {
return settings;
}
/**
* Make a request to the server only to get the maximum possible heap size to use for compilations.
*
* @param port_file The port file used to synchronize creation of this server.
* @param id The identify of the compilation.
* @param out Standard out information.
* @param err Standard err information.
* @return The maximum heap size in bytes.
*/
@Override
public SysInfo getSysInfo() {
try (Socket socket = tryConnect()) {
// The ObjectInputStream constructor will block until the
// corresponding ObjectOutputStream has written and flushed the
// header, so it is important that the ObjectOutputStreams on server
// and client are opened before the ObjectInputStreams.
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
oos.writeObject(id);
oos.writeObject(SjavacServer.CMD_SYS_INFO);
oos.flush();
return (SysInfo) ois.readObject();
} catch (IOException | ClassNotFoundException ex) {
Log.error("[CLIENT] Exception caught: " + ex);
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
}
return null;
}
@Override
public CompilationResult compile(String protocolId,
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
CompilationResult result;
try (Socket socket = tryConnect()) {
// The ObjectInputStream constructor will block until the
// corresponding ObjectOutputStream has written and flushed the
// header, so it is important that the ObjectOutputStreams on server
// and client are opened before the ObjectInputStreams.
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
oos.writeObject(id);
oos.writeObject(SjavacServer.CMD_COMPILE);
oos.writeObject(protocolId);
oos.writeObject(invocationId);
oos.writeObject(args);
oos.writeObject(explicitSources);
oos.writeObject(sourcesToCompile);
oos.writeObject(visibleSources);
oos.flush();
result = (CompilationResult) ois.readObject();
} catch (IOException | ClassNotFoundException ex) {
Log.error("Exception caught: " + ex);
result = new CompilationResult(CompilationResult.ERROR_FATAL);
result.stderr = ex.getMessage();
}
return result;
}
private Socket tryConnect() throws IOException {
PortFile portFile;
try {
// This should be taken care of at a higher level (JDK-8048451)
portFile = SjavacServer.getPortFile(portfileName);
} catch (FileNotFoundException e) {
// Reached for instance if directory of port file does not exist
Log.error("Port file inaccessable: " + e);
throw new RuntimeException(e);
}
for (int i = 0; i < MAX_CONNECT_ATTEMPTS; i++) {
Log.info(String.format("Trying to connect (attempt %d of %d)",
i+1, MAX_CONNECT_ATTEMPTS));
try {
if (!makeSureServerIsRunning(portFile))
continue;
Socket socket = new Socket();
InetAddress localhost = InetAddress.getByName(null);
socket.connect(new InetSocketAddress(localhost, portFile.getPort()),
CONNECTION_TIMEOUT);
return socket;
} catch (ProblemException | IOException ex) {
Log.error("Caught exception during tryConnect: " + ex);
}
try {
Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
throw new IOException("Could not connect to server");
}
private boolean makeSureServerIsRunning(PortFile portFile)
throws IOException, ProblemException, FileNotFoundException {
synchronized (portFile) {
portFile.lock();
portFile.getValues();
portFile.unlock();
}
if (!portFile.containsPortInfo()) {
String forkCmd = SjavacServer.fork(sjavacForkCmd,
portFile.getFilename(),
logfile,
poolsize,
keepalive,
System.err,
stdouterrfile,
background);
if (!portFile.waitForValidValues()) {
// This can be simplified once JDK-8048457 has been addressed
// since we won't have an SjavacClient if background = false
if (background) {
// There seems be some problem with spawning the external
// process (for instance no fork command provided and no
// sjavac on path)
StringWriter sw = new StringWriter();
SjavacClient.printFailedAttempt(forkCmd,
stdouterrfile,
new PrintWriter(sw));
Log.error(sw.toString());
}
}
}
return portFile.containsPortInfo();
}
public static void printFailedAttempt(String cmd, String f, PrintWriter err) {
err.println("---- Failed to start javac server with this command -----");
err.println(cmd);
try {
BufferedReader in = new BufferedReader(new FileReader(f));
err.println("---- stdout/stderr output from attempt to start javac server -----");
for (;;) {
String l = in.readLine();
if (l == null) {
break;
}
err.println(l);
}
err.println("------------------------------------------------------------------");
} catch (Exception e) {
err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
}
}
@Override
public void shutdown() {
// Nothing to clean up
}
}

View File

@ -30,10 +30,10 @@ import com.sun.tools.javac.code.Symbol;
/** Subclass to Attr that overrides reportDepedence. /** Subclass to Attr that overrides reportDepedence.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class AttrWithDeps extends Attr { public class AttrWithDeps extends Attr {

View File

@ -34,6 +34,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import com.sun.tools.javac.code.Symbol.ClassSymbol; 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.Context;
import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Name; 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 /** Utility class containing dependency information between packages
* and the pubapi for a package. * and the pubapi for a package.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class Dependencies { public class Dependencies {
protected static final Context.Key<Dependencies> dependenciesKey = new Context.Key<>(); protected static final Context.Key<Dependencies> dependenciesKey = new Context.Key<>();
@ -154,7 +155,7 @@ public class Dependencies {
Name n = ((ClassSymbol)e).fullname; Name n = ((ClassSymbol)e).fullname;
Name p = ((ClassSymbol)e).packge().fullname; Name p = ((ClassSymbol)e).packge().fullname;
StringBuffer sb = publicApiPerClass.get(n); StringBuffer sb = publicApiPerClass.get(n);
assert(sb == null); Assert.check(sb == null);
sb = new StringBuffer(); sb = new StringBuffer();
PubapiVisitor v = new PubapiVisitor(sb); PubapiVisitor v = new PubapiVisitor(sb);
v.visit(e); v.visit(e);

View File

@ -32,29 +32,29 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol;
/** Subclass to Resolve that overrides collect. /** Subclass to Resolve that overrides collect.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class JavaCompilerWithDeps extends JavaCompiler { public class JavaCompilerWithDeps extends JavaCompiler {
/** The dependency database /** The dependency database
*/ */
protected Dependencies deps; protected Dependencies deps;
protected JavacServiceImpl javacService; protected SjavacErrorHandler errorHandler;
public JavaCompilerWithDeps(Context context, JavacServiceImpl jsi) { public JavaCompilerWithDeps(Context context, SjavacErrorHandler eh) {
super(context); super(context);
deps = Dependencies.instance(context); deps = Dependencies.instance(context);
javacService = jsi; errorHandler = eh;
needRootClasses = true; 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>() { context.put(compilerKey, new Context.Factory<JavaCompiler>() {
public JavaCompiler make(Context c) { public JavaCompiler make(Context c) {
JavaCompiler instance = new JavaCompilerWithDeps(c, t); JavaCompiler instance = new JavaCompilerWithDeps(c, eh);
c.put(JavaCompiler.class, instance); c.put(JavaCompiler.class, instance);
return 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!) // 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)) { 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 "+ " is located in the wrong package directory, because it contains the class "+
sym.getQualifiedName()); sym.getQualifiedName());
} }

View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.comp;
import java.io.File;
import java.net.URI;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.server.CompilationResult;
import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SysInfo;
/**
* An sjavac implementation that limits the number of concurrent calls by
* wrapping invocations in Callables and delegating them to a FixedThreadPool.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class PooledSjavac implements Sjavac {
final Sjavac delegate;
final ExecutorService pool;
public PooledSjavac(Sjavac delegate, int poolsize) {
Objects.requireNonNull(delegate);
this.delegate = delegate;
pool = Executors.newFixedThreadPool(poolsize, new ThreadFactory() {
AtomicInteger count = new AtomicInteger();
@Override
public Thread newThread(Runnable runnable) {
String cls = PooledSjavac.class.getSimpleName();
int num = count.incrementAndGet();
Thread t = new Thread(runnable, cls + "-" + num);
t.setDaemon(true);
return t;
}
});
}
@Override
public SysInfo getSysInfo() {
try {
return pool.submit(new Callable<SysInfo>() {
@Override
public SysInfo call() throws Exception {
return delegate.getSysInfo();
}
}).get();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error during getSysInfo", e);
}
}
@Override
public CompilationResult compile(final String protocolId,
final String invocationId,
final String[] args,
final List<File> explicitSources,
final Set<URI> sourcesToCompile,
final Set<URI> visibleSources) {
try {
return pool.submit(new Callable<CompilationResult>() {
@Override
public CompilationResult call() throws Exception {
return delegate.compile(protocolId,
invocationId,
args,
explicitSources,
sourcesToCompile,
visibleSources);
}
}).get();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error during compile", e);
}
}
@Override
public void shutdown() {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
Log.error("ThreadPool did not terminate");
}
// Grace period for thread termination
Thread.sleep(1000);
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
delegate.shutdown();
}
@Override
public String serverSettings() {
return delegate.serverSettings();
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 /** Utility class that constructs a textual representation
* of the public api of a class. * of the public api of a class.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class PubapiVisitor extends ElementScanner9<Void, Void> { public class PubapiVisitor extends ElementScanner9<Void, Void> {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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. /** Subclass to Resolve that overrides collect.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class ResolveWithDeps extends Resolve { public class ResolveWithDeps extends Resolve {

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.comp;
/**
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public interface SjavacErrorHandler {
void logError(String msg);
}

View File

@ -22,7 +22,6 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package com.sun.tools.sjavac.comp; package com.sun.tools.sjavac.comp;
import java.io.File; import java.io.File;
@ -32,6 +31,7 @@ import java.net.URI;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject; 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.api.JavacTool;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.ListBuffer; 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.CompilationResult;
import com.sun.tools.sjavac.server.JavacServer; import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.JavacService;
import com.sun.tools.sjavac.server.SysInfo; import com.sun.tools.sjavac.server.SysInfo;
public class JavacServiceImpl implements JavacService { /**
* The sjavac implementation that interacts with javac and performs the actual
JavacServer javacServer; * compilation.
private ThreadLocal<Boolean> forcedExit; *
* <p><b>This is NOT part of any supported API.
public JavacServiceImpl(JavacServer javacServer) { * If you write code that depends on this, you do so at your own risk.
this.javacServer = javacServer; * This code and its internal interfaces are subject to change or
* deletion without notice.</b>
} */
public class SjavacImpl implements Sjavac {
public void logError(String msg) {
// stderr.println(msg);
forcedExit.set(true);
}
@Override @Override
public SysInfo getSysInfo() { public SysInfo getSysInfo() {
@ -75,6 +70,7 @@ public class JavacServiceImpl implements JavacService {
List<File> explicitSources, List<File> explicitSources,
Set<URI> sourcesToCompile, Set<URI> sourcesToCompile,
Set<URI> visibleSources) { Set<URI> visibleSources) {
final AtomicBoolean forcedExit = new AtomicBoolean();
JavacTool compiler = JavacTool.create(); JavacTool compiler = JavacTool.create();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
@ -82,7 +78,12 @@ public class JavacServiceImpl implements JavacService {
Context context = new Context(); Context context = new Context();
ResolveWithDeps.preRegister(context); ResolveWithDeps.preRegister(context);
AttrWithDeps.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.... // Now setup the actual compilation....
CompilationResult compilationResult = new CompilationResult(0); CompilationResult compilationResult = new CompilationResult(0);
@ -100,13 +101,6 @@ public class JavacServiceImpl implements JavacService {
for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) { for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
compilationUnits.append(i); 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); forcedExit.set(false);
// Create a new logger. // Create a new logger.
StringWriter stdoutLog = new StringWriter(); StringWriter stdoutLog = new StringWriter();
@ -120,14 +114,20 @@ public class JavacServiceImpl implements JavacService {
smartFileManager.cleanArtifacts(); smartFileManager.cleanArtifacts();
smartFileManager.setLog(stdout); smartFileManager.setLog(stdout);
// Do the compilation! // 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(); rc = ((JavacTaskImpl) task).doCall();
smartFileManager.flush(); smartFileManager.flush();
} }
} catch (Exception e) { } catch (Exception e) {
stderr.println(e.getMessage()); stderrLog.append(e.getMessage());
forcedExit.set(true); forcedExit.set(true);
} }
@ -139,8 +139,22 @@ public class JavacServiceImpl implements JavacService {
compilationResult.stdout = stdoutLog.toString(); compilationResult.stdout = stdoutLog.toString();
compilationResult.stderr = stderrLog.toString(); compilationResult.stderr = stderrLog.toString();
compilationResult.returnCode = rc.exitCode == 0 && forcedExit.get() ? -1 : rc.exitCode; compilationResult.returnCode = rc.exitCode == 0 && forcedExit.get() ? -1 : rc.exitCode;
return compilationResult; return compilationResult;
} }
@Override
public void shutdown() {
// Nothing to clean up
// ... maybe we should wait for any current request to finish?
}
@Override
public String serverSettings() {
return "";
}
} }

View File

@ -37,7 +37,6 @@ import javax.tools.*;
import javax.tools.JavaFileObject.Kind; import javax.tools.JavaFileObject.Kind;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.ListBuffer; 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. * 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. * Necessary to prevent javac from seeing some sources where the source path points.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager> { public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager> {
@ -97,9 +96,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
public Iterable<JavaFileObject> list(Location location, public Iterable<JavaFileObject> list(Location location,
String packageName, String packageName,
Set<Kind> kinds, Set<Kind> kinds,
boolean recurse) boolean recurse) throws IOException {
throws IOException
{
// Acquire the list of files. // Acquire the list of files.
Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse); Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
if (visibleSources.isEmpty()) { if (visibleSources.isEmpty()) {
@ -112,8 +109,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
String t = uri.toString(); String t = uri.toString();
if (t.startsWith("jar:") if (t.startsWith("jar:")
|| t.endsWith(".class") || t.endsWith(".class")
|| visibleSources.contains(uri)) || visibleSources.contains(uri)) {
{
filteredFiles.add(f); filteredFiles.add(f);
} }
} }
@ -128,9 +124,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
@Override @Override
public JavaFileObject getJavaFileForInput(Location location, public JavaFileObject getJavaFileForInput(Location location,
String className, String className,
Kind kind) Kind kind) throws IOException {
throws IOException
{
JavaFileObject file = super.getJavaFileForInput(location, className, kind); JavaFileObject file = super.getJavaFileForInput(location, className, kind);
if (file == null || visibleSources.isEmpty()) { if (file == null || visibleSources.isEmpty()) {
return file; return file;
@ -146,9 +140,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
public JavaFileObject getJavaFileForOutput(Location location, public JavaFileObject getJavaFileForOutput(Location location,
String className, String className,
Kind kind, Kind kind,
FileObject sibling) FileObject sibling) throws IOException {
throws IOException
{
JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling); JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
if (file == null) return file; if (file == null) return file;
int dp = className.lastIndexOf('.'); int dp = className.lastIndexOf('.');
@ -165,9 +157,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
@Override @Override
public FileObject getFileForInput(Location location, public FileObject getFileForInput(Location location,
String packageName, String packageName,
String relativeName) String relativeName) throws IOException {
throws IOException
{
FileObject file = super.getFileForInput(location, packageName, relativeName); FileObject file = super.getFileForInput(location, packageName, relativeName);
if (file == null || visibleSources.isEmpty()) { if (file == null || visibleSources.isEmpty()) {
return file; return file;
@ -183,9 +173,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
public FileObject getFileForOutput(Location location, public FileObject getFileForOutput(Location location,
String packageName, String packageName,
String relativeName, String relativeName,
FileObject sibling) FileObject sibling) throws IOException {
throws IOException
{
FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling); FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
if (file == null) return file; if (file == null) return file;
if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) && if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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, * and compare the new content with the old content on disk. Only if they differ,
* will the file be updated. * will the file be updated.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class SmartFileObject implements JavaFileObject { public class SmartFileObject implements JavaFileObject {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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. * If not, the file is not touched.
* *
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
public class SmartWriter extends Writer { public class SmartWriter extends Writer {

View File

@ -27,6 +27,12 @@ package com.sun.tools.sjavac.options;
import java.util.Iterator; 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> { public class ArgumentIterator implements Iterator<String> {
/** The underlying argument iterator */ /** The underlying argument iterator */

View File

@ -47,6 +47,11 @@ import com.sun.tools.sjavac.Transformer;
* This enum represents all options from (1) and (2). Note that instances of * This enum represents all options from (1) and (2). Note that instances of
* this enum only entail static information about the option. For storage of * this enum only entail static information about the option. For storage of
* option values, refer to com.sun.tools.sjavac.options.Options. * 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 { public enum Option {
@ -231,7 +236,14 @@ public enum Option {
helper.logLevel("info"); 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 @Override
protected void processMatching(ArgumentIterator iter, OptionHelper helper) { protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
helper.permitUnidentifiedArtifacts(); helper.permitUnidentifiedArtifacts();
@ -274,8 +286,16 @@ public enum Option {
if (dir != null) if (dir != null)
helper.headerDir(dir); 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; public final String arg;
final String description; final String description;

View File

@ -25,17 +25,23 @@
package com.sun.tools.sjavac.options; package com.sun.tools.sjavac.options;
import java.nio.file.Files; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.sjavac.Transformer; import com.sun.tools.sjavac.Transformer;
/** /**
* This class is used to decode sjavac options. * This class is used to decode sjavac options.
* See com.sun.tools.sjavac.options.Options for example usage. * 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 { public abstract class OptionHelper {
@ -78,6 +84,9 @@ public abstract class OptionHelper {
/** Record path for reference source list */ /** Record path for reference source list */
public abstract void compareFoundSources(Path referenceList); 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 */ /** Record the fact that unidentified artifacts are permitted */
public abstract void permitUnidentifiedArtifacts(); public abstract void permitUnidentifiedArtifacts();
@ -102,6 +111,9 @@ public abstract class OptionHelper {
/** Sets the directory for generated headers */ /** Sets the directory for generated headers */
public abstract void headerDir(Path dir); 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 */ /** Sets the implicit policy */
public abstract void implicit(String policy); public abstract void implicit(String policy);
@ -112,7 +124,11 @@ public abstract class OptionHelper {
* @param args the arguments to traverse. * @param args the arguments to traverse.
*/ */
void traverse(String[] args) { 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)); ArgumentIterator argIter = new ArgumentIterator(Arrays.asList(args));
nextArg: nextArg:

View File

@ -32,16 +32,23 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import com.sun.tools.sjavac.Transformer; import com.sun.tools.sjavac.Transformer;
/** /**
* Instances of this class represent values for sjavac command line options. * 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 { public class Options {
// Output directories // Output directories
private Path destDir, genSrcDir, headerDir; private Path destDir, genSrcDir, headerDir, stateDir;
// Input directories // Input directories
private List<SourceLocation> sources = new ArrayList<>(); private List<SourceLocation> sources = new ArrayList<>();
@ -51,7 +58,8 @@ public class Options {
private String logLevel = "info"; private String logLevel = "info";
private boolean permitUnidentifiedArtifact = false; private Set<String> permitted_artifacts = new HashSet<>();
private boolean permitUnidentifiedArtifacts = false;
private boolean permitSourcesInDefaultPackage = false; private boolean permitSourcesInDefaultPackage = false;
private Path sourceReferenceList; private Path sourceReferenceList;
@ -86,6 +94,11 @@ public class Options {
return headerDir; 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 */ /** Get all source locations for files to be compiled */
public List<SourceLocation> getSources() { public List<SourceLocation> getSources() {
return sources; return sources;
@ -114,10 +127,15 @@ public class Options {
return logLevel; 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, /** Returns true iff artifacts in the output directories should be kept,
* even if they would not be generated in a clean build. */ * even if they would not be generated in a clean build. */
public boolean isUnidentifiedArtifactPermitted() { public boolean areUnidentifiedArtifactsPermitted() {
return permitUnidentifiedArtifact; return permitUnidentifiedArtifacts;
} }
/** Returns true iff sources in the default package should be permitted. */ /** Returns true iff sources in the default package should be permitted. */
@ -176,14 +194,6 @@ public class Options {
return false; 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 * 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 * the compilation. (Used for saving the state of the options used in a
@ -239,6 +249,9 @@ public class Options {
if (destDir != null) if (destDir != null)
args.addArg(Option.D, destDir.normalize()); args.addArg(Option.D, destDir.normalize());
if (stateDir != null)
args.addArg(Option.STATE_DIR, stateDir.normalize());
// Source roots // Source roots
args.addSourceLocations(Option.SRC, sources); args.addSourceLocations(Option.SRC, sources);
args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths); args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths);
@ -249,7 +262,11 @@ public class Options {
if (permitSourcesInDefaultPackage) if (permitSourcesInDefaultPackage)
args.addArg(Option.PERMIT_SOURCES_WITHOUT_PACKAGE); 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); args.addArg(Option.PERMIT_UNIDENTIFIED_ARTIFACTS);
// Translation rules // Translation rules
@ -327,6 +344,7 @@ public class Options {
boolean headerProvided = false; boolean headerProvided = false;
boolean genSrcProvided = false; boolean genSrcProvided = false;
boolean stateProvided = false;
@Override @Override
public void reportError(String msg) { public void reportError(String msg) {
@ -398,9 +416,14 @@ public class Options {
sourceReferenceList = referenceList; sourceReferenceList = referenceList;
} }
@Override
public void permitArtifact(String f) {
permitted_artifacts.add(f);
}
@Override @Override
public void permitUnidentifiedArtifacts() { public void permitUnidentifiedArtifacts() {
permitUnidentifiedArtifact = true; permitUnidentifiedArtifacts = true;
} }
@Override @Override
@ -465,6 +488,16 @@ public class Options {
headerDir = dir.toAbsolutePath(); 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) { private List<SourceLocation> createSourceLocations(List<Path> paths) {
List<SourceLocation> result = new ArrayList<>(); List<SourceLocation> result = new ArrayList<>();
for (Path path : paths) { for (Path path : paths) {

View File

@ -37,6 +37,11 @@ import com.sun.tools.sjavac.Source;
/** /**
* Represents a directory to be used for input to sjavac. (For instance a * Represents a directory to be used for input to sjavac. (For instance a
* sourcepath or classpath.) * 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 { public class SourceLocation {

View File

@ -25,28 +25,35 @@
package com.sun.tools.sjavac.server; package com.sun.tools.sjavac.server;
import java.io.Serializable;
import java.net.URI; import java.net.URI;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; 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 // Return code constants
public final static int ERROR_BUT_TRY_AGAIN = -4712;
public final static int ERROR_FATAL = -1; public final static int ERROR_FATAL = -1;
public int returnCode; public int returnCode;
public Map<String, Set<URI>> packageArtifacts = new HashMap<>(); public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
public Map<String, Set<String>> packageDependencies = new HashMap<>(); public Map<String, Set<String>> packageDependencies = new HashMap<>();
public Map<String, String> packagePubapis = new HashMap<>(); public Map<String, String> packagePubapis = new HashMap<>();
public SysInfo sysinfo; public String stdout = "";
public String stdout; public String stderr = "";
public String stderr;
public CompilationResult(int returnCode) { public CompilationResult(int returnCode) {
this.returnCode = returnCode; this.returnCode = returnCode;
this.sysinfo = new SysInfo(-1, -1);
} }
public void setReturnCode(int returnCode) { public void setReturnCode(int returnCode) {

View File

@ -1,165 +0,0 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.Stack;
import java.util.concurrent.Future;
import com.sun.tools.sjavac.comp.JavacServiceImpl;
/** The compiler pool maintains compiler threads.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
public class CompilerPool {
// The javac server that created this pool.
private JavacServer javacServer;
// A semaphore protecting the poolsize number of threads.
private Semaphore available;
// The stack of compiler threads.
private Stack<CompilerThread> compilers = new Stack<>();
// And the executor server to spawn threads.
private final ExecutorService executorPool;
// How many requests are active right now?
private int concurrentRequests = 0;
// When was the last request finished?
private long lastRequestFinished = 0;
// The total number of requests to this pool.
private int numRequests = 0;
// Protect access to the three above values.
private static final Object conc = new Object();
/**
* Return the javac server that this pool belongs to.
*/
public JavacServer getJavacServer() {
return javacServer;
}
/**
* Return how many threads are running at this very moment.
*/
public int numActiveRequests()
{
synchronized (conc) {
return concurrentRequests;
}
}
/**
* Return when the last request was finished.
* I.e. the pool has been idle since.
*/
public long lastRequestFinished()
{
synchronized (conc) {
return lastRequestFinished;
}
}
/**
* Up the number of active requests.
*/
public int startRequest() {
int n;
synchronized (conc) {
concurrentRequests++;
numRequests++;
n = numRequests;
}
return n;
}
/**
* Down the number of active requests. Return the current time.
*/
public long stopRequest() {
synchronized (conc) {
concurrentRequests--;
lastRequestFinished = System.currentTimeMillis();
}
return lastRequestFinished;
}
/**
* Create a new compiler pool.
*/
CompilerPool(int poolsize, JavacServer server) {
available = new Semaphore(poolsize, true);
javacServer = server;
executorPool = Executors.newFixedThreadPool(poolsize);
lastRequestFinished = System.currentTimeMillis();
}
/**
* Execute a compiler thread.
*/
public void execute(CompilerThread ct) {
executorPool.execute(ct);
}
/**
* Execute a minor task, for example generating bytecodes and writing them to disk,
* that belong to a major compiler thread task.
*/
public Future<?> executeSubtask(CompilerThread t, Runnable r) {
return executorPool.submit(r);
}
/**
* Shutdown the pool.
*/
public void shutdown() {
executorPool.shutdown();
}
/**
* Acquire a compiler thread from the pool, or block until a thread is available.
* If the pools is empty, create a new thread, but never more than is "available".
*/
public CompilerThread grabCompilerThread() throws InterruptedException {
available.acquire();
if (compilers.empty()) {
return new CompilerThread(this, new JavacServiceImpl(javacServer));
}
return compilers.pop();
}
/**
* Return the specified compiler thread to the pool.
*/
public void returnCompilerThread(CompilerThread h) {
compilers.push(h);
available.release();
}
}

View File

@ -1,412 +0,0 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.StringUtils;
import com.sun.tools.sjavac.comp.AttrWithDeps;
import com.sun.tools.sjavac.comp.Dependencies;
import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
import com.sun.tools.sjavac.comp.JavacServiceImpl;
import com.sun.tools.sjavac.comp.ResolveWithDeps;
import com.sun.tools.sjavac.comp.SmartFileManager;
/**
* The compiler thread maintains a JavaCompiler instance and
* can receive a request from the client, perform the compilation
* requested and report back the results.
*
* * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
public class CompilerThread implements Runnable {
private JavacServer javacServer;
private CompilerPool compilerPool;
private JavacServiceImpl javacServiceImpl;
private List<Future<?>> subTasks;
// Communicating over this socket.
private Socket socket;
// The necessary classes to do a compilation.
private com.sun.tools.javac.api.JavacTool compiler;
private StandardJavaFileManager fileManager;
private SmartFileManager smartFileManager;
private Context context;
// If true, then this thread is serving a request.
private boolean inUse = false;
CompilerThread(CompilerPool cp, JavacServiceImpl javacServiceImpl) {
compilerPool = cp;
javacServer = cp.getJavacServer();
this.javacServiceImpl = javacServiceImpl;
}
/**
* Execute a minor task, for example generating bytecodes and writing them to disk,
* that belong to a major compiler thread task.
*/
public synchronized void executeSubtask(Runnable r) {
subTasks.add(compilerPool.executeSubtask(this, r));
}
/**
* Count the number of active sub tasks.
*/
public synchronized int numActiveSubTasks() {
int c = 0;
for (Future<?> f : subTasks) {
if (!f.isDone() && !f.isCancelled()) {
c++;
}
}
return c;
}
/**
* Use this socket for the upcoming request.
*/
public void setSocket(Socket s) {
socket = s;
}
/**
* Prepare the compiler thread for use. It is not yet started.
* It will be started by the executor service.
*/
public synchronized void use() {
assert(!inUse);
inUse = true;
compiler = com.sun.tools.javac.api.JavacTool.create();
fileManager = compiler.getStandardFileManager(null, null, null);
smartFileManager = new SmartFileManager(fileManager);
context = new Context();
ResolveWithDeps.preRegister(context);
AttrWithDeps.preRegister(context);
JavaCompilerWithDeps.preRegister(context, javacServiceImpl);
subTasks = new ArrayList<>();
}
/**
* Prepare the compiler thread for idleness.
*/
public synchronized void unuse() {
assert(inUse);
inUse = false;
compiler = null;
fileManager = null;
smartFileManager = null;
context = null;
subTasks = null;
}
/**
* Expect this key on the next line read from the reader.
*/
private static boolean expect(BufferedReader in, String key) throws IOException {
String s = in.readLine();
if (s != null && s.equals(key)) {
return true;
}
return false;
}
// The request identifier, for example GENERATE_NEWBYTECODE
String id = "";
public String currentRequestId() {
return id;
}
PrintWriter stdout;
PrintWriter stderr;
int forcedExitCode = 0;
public void logError(String msg) {
stderr.println(msg);
forcedExitCode = -1;
}
/**
* Invoked by the executor service.
*/
public void run() {
// Unique nr that identifies this request.
int thisRequest = compilerPool.startRequest();
long start = System.currentTimeMillis();
int numClasses = 0;
StringBuilder compiledPkgs = new StringBuilder();
use();
PrintWriter out = null;
try {
javacServer.log("<"+thisRequest+"> Connect from "+socket.getRemoteSocketAddress()+" activethreads="+compilerPool.numActiveRequests());
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream()));
if (!expect(in, JavacServer.PROTOCOL_COOKIE_VERSION)) {
javacServer.log("<"+thisRequest+"> Bad protocol from ip "+socket.getRemoteSocketAddress());
return;
}
String cookie = in.readLine();
if (cookie == null || !cookie.equals(""+javacServer.getCookie())) {
javacServer.log("<"+thisRequest+"> Bad cookie from ip "+socket.getRemoteSocketAddress());
return;
}
if (!expect(in, JavacServer.PROTOCOL_CWD)) {
return;
}
String cwd = in.readLine();
if (cwd == null)
return;
if (!expect(in, JavacServer.PROTOCOL_ID)) {
return;
}
id = in.readLine();
if (id == null)
return;
if (!expect(in, JavacServer.PROTOCOL_ARGS)) {
return;
}
ArrayList<String> the_options = new ArrayList<>();
ArrayList<File> the_classes = new ArrayList<>();
Iterable<File> path = Arrays.<File> asList(new File(cwd));
for (;;) {
String l = in.readLine();
if (l == null)
return;
if (l.equals(JavacServer.PROTOCOL_SOURCES_TO_COMPILE))
break;
if (l.startsWith("--server:"))
continue;
if (!l.startsWith("-") && l.endsWith(".java")) {
the_classes.add(new File(l));
numClasses++;
} else {
the_options.add(l);
}
continue;
}
// Load sources to compile
Set<URI> sourcesToCompile = new HashSet<>();
for (;;) {
String l = in.readLine();
if (l == null)
return;
if (l.equals(JavacServer.PROTOCOL_VISIBLE_SOURCES))
break;
try {
sourcesToCompile.add(new URI(l));
numClasses++;
} catch (URISyntaxException e) {
return;
}
}
// Load visible sources
Set<URI> visibleSources = new HashSet<>();
boolean fix_drive_letter_case =
StringUtils.toLowerCase(System.getProperty("os.name")).startsWith("windows");
for (;;) {
String l = in.readLine();
if (l == null)
return;
if (l.equals(JavacServer.PROTOCOL_END))
break;
try {
URI u = new URI(l);
if (fix_drive_letter_case) {
// Make sure the driver letter is lower case.
String s = u.toString();
if (s.startsWith("file:/") &&
Character.isUpperCase(s.charAt(6))) {
u = new URI("file:/"+Character.toLowerCase(s.charAt(6))+s.substring(7));
}
}
visibleSources.add(u);
} catch (URISyntaxException e) {
return;
}
}
// A completed request has been received.
// Now setup the actual compilation....
// First deal with explicit source files on cmdline and in at file.
ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(the_classes)) {
compilationUnits.append(i);
}
// Now deal with sources supplied as source_to_compile.
ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
for (URI u : sourcesToCompile) {
sourcesToCompileFiles.append(new File(u));
}
for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
compilationUnits.append(i);
}
// Log the options to be used.
StringBuilder options = new StringBuilder();
for (String s : the_options) {
options.append(">").append(s).append("< ");
}
javacServer.log(id+" <"+thisRequest+"> options "+options.toString());
forcedExitCode = 0;
// Create a new logger.
StringWriter stdoutLog = new StringWriter();
StringWriter stderrLog = new StringWriter();
stdout = new PrintWriter(stdoutLog);
stderr = new PrintWriter(stderrLog);
com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
try {
if (compilationUnits.size() > 0) {
smartFileManager.setVisibleSources(visibleSources);
smartFileManager.cleanArtifacts();
smartFileManager.setLog(stdout);
// Do the compilation!
CompilationTask task = compiler.getTask(stderr, smartFileManager, null, the_options, null, compilationUnits, context);
smartFileManager.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
rc = ((JavacTaskImpl) task).doCall();
while (numActiveSubTasks()>0) {
try { Thread.sleep(1000); } catch (InterruptedException e) { }
}
smartFileManager.flush();
}
} catch (Exception e) {
stderr.println(e.getMessage());
forcedExitCode = -1;
}
// Send the response..
out.println(JavacServer.PROTOCOL_STDOUT);
out.print(stdoutLog);
out.println(JavacServer.PROTOCOL_STDERR);
out.print(stderrLog);
// The compilation is complete! And errors will have already been printed on out!
out.println(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS);
Map<String,Set<URI>> pa = smartFileManager.getPackageArtifacts();
for (String aPkgName : pa.keySet()) {
out.println("+"+aPkgName);
Set<URI> as = pa.get(aPkgName);
for (URI a : as) {
out.println(" "+a.toString());
}
}
Dependencies deps = Dependencies.instance(context);
out.println(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES);
Map<String,Set<String>> pd = deps.getDependencies();
for (String aPkgName : pd.keySet()) {
out.println("+"+aPkgName);
Set<String> ds = pd.get(aPkgName);
// Everything depends on java.lang
if (!ds.contains(":java.lang")) ds.add(":java.lang");
for (String d : ds) {
out.println(" "+d);
}
}
out.println(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS);
Map<String,String> pp = deps.getPubapis();
for (String aPkgName : pp.keySet()) {
out.println("+"+aPkgName);
String ps = pp.get(aPkgName);
// getPubapis added a space to each line!
out.println(ps);
compiledPkgs.append(aPkgName+" ");
}
out.println(JavacServer.PROTOCOL_SYSINFO);
out.println("num_cores=" + Runtime.getRuntime().availableProcessors());
out.println("max_memory=" + Runtime.getRuntime().maxMemory());
out.println(JavacServer.PROTOCOL_RETURN_CODE);
// Errors from sjavac that affect compilation status!
int rcv = rc.exitCode;
if (rcv == 0 && forcedExitCode != 0) {
rcv = forcedExitCode;
}
out.println("" + rcv);
out.println(JavacServer.PROTOCOL_END);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) out.close();
if (!socket.isClosed()) {
socket.close();
}
socket = null;
} catch (Exception e) {
javacServer.log("ERROR "+e);
e.printStackTrace();
}
compilerPool.stopRequest();
long duration = System.currentTimeMillis()-start;
javacServer.addBuildTime(duration);
float classpersec = ((float)numClasses)*(((float)1000.0)/((float)duration));
javacServer.log(id+" <"+thisRequest+"> "+compiledPkgs+" duration " + duration+ " ms num_classes="+numClasses+
" classpersec="+classpersec+" subtasks="+subTasks.size());
javacServer.flushLog();
unuse();
compilerPool.returnCompilerThread(this);
}
}
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.io.File;
import java.net.URI;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
/**
* An sjavac implementation that keeps track of idleness and shuts down the
* given Terminable upon idleness timeout.
*
* An idleness timeout kicks in {@code idleTimeout} milliseconds after the last
* request is completed.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class IdleResetSjavac implements Sjavac {
private final Sjavac delegate;
private final AtomicInteger outstandingCalls = new AtomicInteger();
private final Terminable toShutdown;
private final Timer idlenessTimer = new Timer();
private final long idleTimeout;
// Class invariant: idlenessTimerTask != null <-> idlenessTimerTask is scheduled
private TimerTask idlenessTimerTask;
public IdleResetSjavac(Sjavac delegate,
Terminable toShutdown,
long idleTimeout) {
this.delegate = delegate;
this.toShutdown = toShutdown;
this.idleTimeout = idleTimeout;
scheduleTimeout();
}
@Override
public SysInfo getSysInfo() {
startCall();
try {
return delegate.getSysInfo();
} finally {
endCall();
}
}
@Override
public CompilationResult compile(String protocolId,
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
startCall();
try {
return delegate.compile(protocolId,
invocationId,
args,
explicitSources,
sourcesToCompile,
visibleSources);
} finally {
endCall();
}
}
private void startCall() {
// Was there no outstanding calls before this call?
if (outstandingCalls.incrementAndGet() == 1) {
// Then the timer task must have been scheduled
if (idlenessTimerTask == null)
throw new IllegalStateException("Idle timeout already cancelled");
// Cancel timeout task
idlenessTimerTask.cancel();
idlenessTimerTask = null;
}
}
private void endCall() {
if (outstandingCalls.decrementAndGet() == 0) {
// No more outstanding calls. Schedule timeout.
scheduleTimeout();
}
}
private void scheduleTimeout() {
if (idlenessTimerTask != null)
throw new IllegalStateException("Idle timeout already scheduled");
idlenessTimerTask = new TimerTask() {
public void run() {
toShutdown.shutdown("Server has been idle for " + (idleTimeout / 1000) + " seconds.");
}
};
idlenessTimer.schedule(idlenessTimerTask, idleTimeout);
}
@Override
public void shutdown() {
idlenessTimer.cancel();
delegate.shutdown();
}
@Override
public String serverSettings() {
return delegate.serverSettings();
}
}

View File

@ -1,382 +0,0 @@
/*
* Copyright (c) 2011-2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Random;
import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.ProblemException;
import java.io.*;
/**
* The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
*
* <p><b>This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are
* subject to change or deletion without notice.</b></p>
*/
public class JavacServer {
// Responding to this tcp/ip port on localhost.
private final ServerSocket serverSocket;
// The secret cookie shared between server and client through the port file.
private final long myCookie;
// When the server was started.
private long serverStart;
// Accumulated build time for all requests, not counting idle time.
private long totalBuildTime;
// The javac server specific log file.
PrintWriter theLog;
// The compiler pool that maintains the compiler threads.
CompilerPool compilerPool;
// For the client, all port files fetched, one per started javac server.
// Though usually only one javac server is started by a client.
private static Map<String, PortFile> allPortFiles;
private static Map<String, Long> maxServerMemory;
final static String PROTOCOL_COOKIE_VERSION = "----THE-COOKIE-V2----";
final static String PROTOCOL_CWD = "----THE-CWD----";
final static String PROTOCOL_ID = "----THE-ID----";
final static String PROTOCOL_ARGS = "----THE-ARGS----";
final static String PROTOCOL_SOURCES_TO_COMPILE = "----THE-SOURCES-TO-COMPILE----";
final static String PROTOCOL_VISIBLE_SOURCES = "----THE-VISIBLE-SOURCES----";
final static String PROTOCOL_END = "----THE-END----";
final static String PROTOCOL_STDOUT = "----THE-STDOUT----";
final static String PROTOCOL_STDERR = "----THE-STDERR----";
final static String PROTOCOL_PACKAGE_ARTIFACTS = "----THE-PACKAGE_ARTIFACTS----";
final static String PROTOCOL_PACKAGE_DEPENDENCIES = "----THE-PACKAGE_DEPENDENCIES----";
final static String PROTOCOL_PACKAGE_PUBLIC_APIS = "----THE-PACKAGE-PUBLIC-APIS----";
final static String PROTOCOL_SYSINFO = "----THE-SYSINFO----";
final static String PROTOCOL_RETURN_CODE = "----THE-RETURN-CODE----";
// Check if the portfile is gone, every 5 seconds.
static int CHECK_PORTFILE_INTERVAL = 5;
// Wait 2 seconds for response, before giving up on javac server.
static int CONNECTION_TIMEOUT = 2;
static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 1;
static int MAX_NUM_CONNECT_ATTEMPTS = 3;
/**
* Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
*/
public static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
if (allPortFiles == null) {
allPortFiles = new HashMap<>();
}
PortFile pf = allPortFiles.get(filename);
// Port file known. Does it still exist?
if (pf != null) {
try {
if (!pf.exists())
pf = null;
} catch (IOException ioex) {
ioex.printStackTrace();
}
}
if (pf == null) {
pf = new PortFile(filename);
allPortFiles.put(filename, pf);
}
return pf;
}
/**
* Get the cookie used for this server.
*/
long getCookie() {
return myCookie;
}
/**
* Get the port used for this server.
*/
int getPort() {
return serverSocket.getLocalPort();
}
/**
* Sum up the total build time for this javac server.
*/
public void addBuildTime(long inc) {
totalBuildTime += inc;
}
/**
* Log this message.
*/
public void log(String msg) {
if (theLog != null) {
theLog.println(msg);
} else {
System.err.println(msg);
}
}
/**
* Make sure the log is flushed.
*/
public void flushLog() {
if (theLog != null) {
theLog.flush();
}
}
/**
* Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
* is sent as the settings parameter. Returns 0 on success, -1 on failure.
*/
public static int startServer(String settings, PrintStream err) {
try {
String portfile = Util.extractStringOption("portfile", settings);
// The log file collects more javac server specific log information.
String logfile = Util.extractStringOption("logfile", settings);
// The stdouterr file collects all the System.out and System.err writes to disk.
String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
// We could perhaps use System.setOut and setErr here.
// But for the moment we rely on the client to spawn a shell where stdout
// and stderr are redirected already.
// The pool size is a limit the number of concurrent compiler threads used.
// The server might use less than these to avoid memory problems.
int defaultPoolSize = Runtime.getRuntime().availableProcessors();
int poolsize = Util.extractIntOption("poolsize", settings, defaultPoolSize);
// How many seconds of inactivity will the server accept before quitting?
int keepalive = Util.extractIntOption("keepalive", settings, 120);
// The port file is locked and the server port and cookie is written into it.
PortFile portFile = getPortFile(portfile);
JavacServer s;
synchronized (portFile) {
portFile.lock();
portFile.getValues();
if (portFile.containsPortInfo()) {
err.println("Javac server not started because portfile exists!");
portFile.unlock();
return -1;
}
s = new JavacServer(poolsize, logfile);
portFile.setValues(s.getPort(), s.getCookie());
portFile.unlock();
}
// Run the server. Will delete the port file when shutting down.
// It will shut down automatically when no new requests have come in
// during the last 125 seconds.
s.run(portFile, err, keepalive);
// The run loop for the server has exited.
return 0;
} catch (Exception e) {
e.printStackTrace(err);
return -1;
}
}
/**
* Spawn the server instance.
*/
private JavacServer(int poolSize, String logfile) throws IOException {
serverStart = System.currentTimeMillis();
// Create a server socket on a random port that is bound to the localhost/127.0.0.1 interface.
// I.e only local processes can connect to this port.
serverSocket = new ServerSocket(0, 128, InetAddress.getByName(null));
compilerPool = new CompilerPool(poolSize, this);
Random rnd = new Random();
myCookie = rnd.nextLong();
theLog = new PrintWriter(logfile);
log("Javac server started. port=" + getPort() + " date=" + (new java.util.Date()) + " with poolsize=" + poolSize);
flushLog();
}
/**
* Fork a background process. Returns the command line used that can be printed if something failed.
*/
public static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
final PrintStream err, String stdouterrfile, boolean background)
throws IOException, ProblemException {
if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
stdouterrfile = null;
}
final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
if (background) {
sjavac += "%20" + startserver;
sjavac = sjavac.replaceAll("%20", " ");
sjavac = sjavac.replaceAll("%2C", ",");
// If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
if (!(new File("/bin/sh")).canExecute()) {
ArrayList<String> wincmd = new ArrayList<>();
wincmd.add("cmd");
wincmd.add("/c");
wincmd.add("start");
wincmd.add("cmd");
wincmd.add("/c");
wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
cmd = wincmd.toArray(new String[wincmd.size()]);
}
Process pp = null;
try {
pp = Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
e.printStackTrace(err);
e.printStackTrace(new PrintWriter(stdouterrfile));
}
StringBuilder rs = new StringBuilder();
for (String s : cmd) {
rs.append(s + " ");
}
return rs.toString();
}
// Do not spawn a background server, instead run it within the same JVM.
Thread t = new Thread() {
@Override
public void run() {
try {
JavacServer.startServer(startserver, err);
} catch (Throwable t) {
t.printStackTrace(err);
}
}
};
t.start();
return "";
}
/**
* Run the server thread until it exits. Either because of inactivity or because the port file has been deleted by someone else, or overtaken by some other
* javac server.
*/
private void run(PortFile portFile, PrintStream err, int keepalive) {
boolean fileDeleted = false;
long timeSinceLastCompile;
try {
// Every 5 second (check_portfile_interval) we test if the portfile has disappeared => quit
// Or if the last request was finished more than 125 seconds ago => quit
// 125 = seconds_of_inactivity_before_shutdown+check_portfile_interval
serverSocket.setSoTimeout(CHECK_PORTFILE_INTERVAL*1000);
for (;;) {
try {
Socket s = serverSocket.accept();
CompilerThread ct = compilerPool.grabCompilerThread();
ct.setSocket(s);
compilerPool.execute(ct);
flushLog();
} catch (java.net.SocketTimeoutException e) {
if (compilerPool.numActiveRequests() > 0) {
// Never quit while there are active requests!
continue;
}
// If this is the timeout after the portfile
// has been deleted by us. Then we truly stop.
if (fileDeleted) {
log("Quitting because of "+(keepalive+CHECK_PORTFILE_INTERVAL)+" seconds of inactivity!");
break;
}
// Check if the portfile is still there.
if (!portFile.exists()) {
// Time to quit because the portfile was deleted by another
// process, probably by the makefile that is done building.
log("Quitting because portfile was deleted!");
flushLog();
break;
}
// Check if portfile.stop is still there.
if (portFile.markedForStop()) {
// Time to quit because another process touched the file
// server.port.stop to signal that the server should stop.
// This is necessary on some operating systems that lock
// the port file hard!
log("Quitting because a portfile.stop file was found!");
portFile.delete();
flushLog();
break;
}
// Does the portfile still point to me?
if (!portFile.stillMyValues()) {
// Time to quit because another build has started.
log("Quitting because portfile is now owned by another javac server!");
flushLog();
break;
}
// Check how long since the last request finished.
long diff = System.currentTimeMillis() - compilerPool.lastRequestFinished();
if (diff < keepalive * 1000) {
// Do not quit if we have waited less than 120 seconds.
continue;
}
// Ok, time to quit because of inactivity. Perhaps the build
// was killed and the portfile not cleaned up properly.
portFile.delete();
fileDeleted = true;
log("" + keepalive + " seconds of inactivity quitting in "
+ CHECK_PORTFILE_INTERVAL + " seconds!");
flushLog();
// Now we have a second 5 second grace
// period where javac remote requests
// that have loaded the data from the
// recently deleted portfile can connect
// and complete their requests.
}
}
} catch (Exception e) {
e.printStackTrace(err);
e.printStackTrace(theLog);
flushLog();
} finally {
compilerPool.shutdown();
}
long realTime = System.currentTimeMillis() - serverStart;
log("Shutting down.");
log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
flushLog();
}
public static void cleanup(String... args) {
String settings = Util.findServerSettings(args);
if (settings == null) return;
String portfile = Util.extractStringOption("portfile", settings);
String background = Util.extractStringOption("background", settings);
if (background != null && background.equals("false")) {
// If the server runs within this jvm, then delete the portfile,
// since this jvm is about to exit soon.
File f = new File(portfile);
f.delete();
}
}
}

View File

@ -1,433 +0,0 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.Util;
import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
public class JavacServiceClient implements JavacService {
// The id can perhaps be used in the future by the javac server to reuse the
// JavaCompiler instance for several compiles using the same id.
private final String id;
private final String portfile;
private final String logfile;
private final String stdouterrfile;
private final boolean background;
// Default keepalive for server is 120 seconds.
// I.e. it will accept 120 seconds of inactivity before quitting.
private final int keepalive;
private final int poolsize;
// The sjavac option specifies how the server part of sjavac is spawned.
// If you have the experimental sjavac in your path, you are done. If not, you have
// to point to a com.sun.tools.sjavac.Main that supports --startserver
// for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
private final String sjavac;
public JavacServiceClient(String settings) {
id = Util.extractStringOption("id", settings);
portfile = Util.extractStringOption("portfile", settings);
logfile = Util.extractStringOption("logfile", settings, portfile + ".javaclog");
stdouterrfile = Util.extractStringOption("stdouterrfile", settings, portfile + ".stdouterr");
background = Util.extractBooleanOption("background", settings, true);
sjavac = Util.extractStringOption("sjavac", settings, "sjavac");
int poolsize = Util.extractIntOption("poolsize", settings);
keepalive = Util.extractIntOption("keepalive", settings, 120);
this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
}
/**
* Make a request to the server only to get the maximum possible heap size to use for compilations.
*
* @param port_file The port file used to synchronize creation of this server.
* @param id The identify of the compilation.
* @param out Standard out information.
* @param err Standard err information.
* @return The maximum heap size in bytes.
*/
@Override
public SysInfo getSysInfo() {
try {
CompilationResult cr = useServer(new String[0],
Collections.<URI>emptySet(),
Collections.<URI>emptySet(),
Collections.<URI, Set<String>>emptyMap());
return cr.sysinfo;
} catch (Exception e) {
return new SysInfo(-1, -1);
}
}
@Override
public CompilationResult compile(String protocolId,
String invocationId,
String[] args,
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
// Delegate to useServer, which delegates to compileHelper
return useServer(args, sourcesToCompile, visibleSources, null);
}
/**
* Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
* supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
*/
public CompilationResult compileHelper(String id,
String[] args,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
CompilationResult rc = new CompilationResult(-3);
try {
PortFile portFile = JavacServer.getPortFile(this.portfile);
int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
if (port == 0) {
return new CompilationResult(ERROR_BUT_TRY_AGAIN);
}
long cookie = portFile.getCookie();
// Acquire the localhost/127.0.0.1 address.
InetAddress addr = InetAddress.getByName(null);
SocketAddress sockaddr = new InetSocketAddress(addr, port);
Socket sock = new Socket();
int timeoutMs = JavacServer.CONNECTION_TIMEOUT * 1000;
try {
sock.connect(sockaddr, timeoutMs);
} catch (java.net.ConnectException e) {
rc.setReturnCode(ERROR_BUT_TRY_AGAIN);
rc.stderr = "Could not connect to javac server found in portfile: " + portFile.getFilename() + " " + e;
return rc;
}
if (!sock.isConnected()) {
rc.setReturnCode(ERROR_BUT_TRY_AGAIN);
rc.stderr = "Could not connect to javac server found in portfile: " + portFile.getFilename();
return rc;
}
//
// Send arguments
//
BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
PrintWriter sockout = new PrintWriter(sock.getOutputStream());
sockout.println(JavacServer.PROTOCOL_COOKIE_VERSION);
sockout.println("" + cookie);
sockout.println(JavacServer.PROTOCOL_CWD);
sockout.println(System.getProperty("user.dir"));
sockout.println(JavacServer.PROTOCOL_ID);
sockout.println(id);
sockout.println(JavacServer.PROTOCOL_ARGS);
for (String s : args) {
StringBuffer buf = new StringBuffer();
String[] paths = s.split(File.pathSeparator);
int c = 0;
for (String path : paths) {
File f = new File(path);
if (f.isFile() || f.isDirectory()) {
buf.append(f.getAbsolutePath());
c++;
if (c < paths.length) {
buf.append(File.pathSeparator);
}
} else {
buf = new StringBuffer(s);
break;
}
}
sockout.println(buf.toString());
}
sockout.println(JavacServer.PROTOCOL_SOURCES_TO_COMPILE);
for (URI uri : sourcesToCompile) {
sockout.println(uri.toString());
}
sockout.println(JavacServer.PROTOCOL_VISIBLE_SOURCES);
for (URI uri : visibleSources) {
sockout.println(uri.toString());
}
sockout.println(JavacServer.PROTOCOL_END);
sockout.flush();
//
// Receive result
//
StringBuffer stdout = new StringBuffer();
StringBuffer stderr = new StringBuffer();
if (!JavacServiceClient.expect(in, JavacServer.PROTOCOL_STDOUT)) {
return new CompilationResult(ERROR_FATAL);
}
// Load stdout
for (;;) {
String l = in.readLine();
if (l == null) {
return new CompilationResult(ERROR_FATAL);
}
if (l.equals(JavacServer.PROTOCOL_STDERR)) {
break;
}
stdout.append(l);
stdout.append('\n');
}
// Load stderr
for (;;) {
String l = in.readLine();
if (l == null) {
return new CompilationResult(ERROR_FATAL);
}
if (l.equals(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS)) {
break;
}
stderr.append(l);
stderr.append('\n');
}
// Load the package artifacts
Set<URI> lastUriSet = null;
for (;;) {
String l = in.readLine();
if (l == null) {
return new CompilationResult(ERROR_FATAL);
}
if (l.equals(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES)) {
break;
}
if (l.length() > 1 && l.charAt(0) == '+') {
String pkg = l.substring(1);
lastUriSet = new HashSet<>();
rc.packageArtifacts.put(pkg, lastUriSet);
} else if (l.length() > 1 && lastUriSet != null) {
lastUriSet.add(new URI(l.substring(1)));
}
}
// Load package dependencies
Set<String> lastPackageSet = null;
for (;;) {
String l = in.readLine();
if (l == null) {
return new CompilationResult(ERROR_FATAL);
}
if (l.equals(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS)) {
break;
}
if (l.length() > 1 && l.charAt(0) == '+') {
String pkg = l.substring(1);
lastPackageSet = new HashSet<>();
rc.packageDependencies.put(pkg, lastPackageSet);
} else if (l.length() > 1 && lastPackageSet != null) {
lastPackageSet.add(l.substring(1));
}
}
// Load package pubapis
Map<String, StringBuffer> tmp = new HashMap<>();
StringBuffer lastPublicApi = null;
for (;;) {
String l = in.readLine();
if (l == null) {
return new CompilationResult(ERROR_FATAL);
}
if (l.equals(JavacServer.PROTOCOL_SYSINFO)) {
break;
}
if (l.length() > 1 && l.charAt(0) == '+') {
String pkg = l.substring(1);
lastPublicApi = new StringBuffer();
tmp.put(pkg, lastPublicApi);
} else if (l.length() > 1 && lastPublicApi != null) {
lastPublicApi.append(l.substring(1));
lastPublicApi.append("\n");
}
}
for (String p : tmp.keySet()) {
//assert (packagePublicApis.get(p) == null);
String api = tmp.get(p).toString();
rc.packagePubapis.put(p, api);
}
// Now reading the max memory possible.
for (;;) {
String l = in.readLine();
if (l == null) {
return new CompilationResult(ERROR_FATAL);
}
if (l.equals(JavacServer.PROTOCOL_RETURN_CODE)) {
break;
}
if (l.startsWith("num_cores=")) {
rc.sysinfo.numCores = Integer.parseInt(l.substring(10));
}
if (l.startsWith("max_memory=")) {
rc.sysinfo.maxMemory = Long.parseLong(l.substring(11));
}
}
String l = in.readLine();
if (l == null) {
rc.setReturnCode(ERROR_FATAL);
rc.stderr = "No return value from the server!";
return rc;
}
rc.setReturnCode(Integer.parseInt(l));
rc.stdout = stdout.toString();
rc.stderr = stderr.toString();
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
rc.stderr = sw.toString();
}
return rc;
}
/**
* Dispatch a compilation request to a javac server.
*
* @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
*
* The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
*
* @param sources_to_compile The sources to compile.
*
* @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
* (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
*
* @param visibleClasses If visible classes for a specific root/jar has a non zero size, then visible_classes are the only class files that the javac server
* can see, in that root/jar. It maps from a classpath root or a jar file to the set of visible classes for that root/jar.
*
* The server return meta data about the build in the following parameters.
* @param package_artifacts, map from package name to set of created artifacts for that package.
* @param package_dependencies, map from package name to set of packages that it depends upon.
* @param package_pubapis, map from package name to unique string identifying its pub api.
*/
public CompilationResult useServer(String[] args,
Set<URI> sourcesToCompile,
Set<URI> visibleSources,
Map<URI, Set<String>> visibleClasses) {
try {
if (portfile == null) {
CompilationResult cr = new CompilationResult(CompilationResult.ERROR_FATAL);
cr.stderr = "No portfile was specified!";
return cr;
}
int attempts = 0;
CompilationResult rc;
do {
PortFile port_file = JavacServer.getPortFile(portfile);
synchronized (port_file) {
port_file.lock();
port_file.getValues();
port_file.unlock();
}
if (!port_file.containsPortInfo()) {
String cmd = JavacServer.fork(sjavac, port_file.getFilename(), logfile, poolsize, keepalive, System.err, stdouterrfile, background);
if (background && !port_file.waitForValidValues()) {
// Ouch the server did not start! Lets print its stdouterrfile and the command used.
StringWriter sw = new StringWriter();
JavacServiceClient.printFailedAttempt(cmd, stdouterrfile, new PrintWriter(sw));
// And give up.
CompilationResult cr = new CompilationResult(ERROR_FATAL);
cr.stderr = sw.toString();
return cr;
}
}
rc = compileHelper(id, args, sourcesToCompile, visibleSources);
// Try again until we manage to connect. Any error after that
// will cause the compilation to fail.
if (rc.returnCode == CompilationResult.ERROR_BUT_TRY_AGAIN) {
// We could not connect to the server. Try again.
attempts++;
try {
Thread.sleep(JavacServer.WAIT_BETWEEN_CONNECT_ATTEMPTS * 1000);
} catch (InterruptedException e) {
}
}
} while (rc.returnCode == ERROR_BUT_TRY_AGAIN && attempts < JavacServer.MAX_NUM_CONNECT_ATTEMPTS);
return rc;
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
CompilationResult cr = new CompilationResult(ERROR_FATAL);
cr.stderr = sw.toString();
return cr;
}
}
public static void printFailedAttempt(String cmd, String f, PrintWriter err) {
err.println("---- Failed to start javac server with this command -----");
err.println(cmd);
try {
BufferedReader in = new BufferedReader(new FileReader(f));
err.println("---- stdout/stderr output from attempt to start javac server -----");
for (;;) {
String l = in.readLine();
if (l == null) {
break;
}
err.println(l);
}
err.println("------------------------------------------------------------------");
} catch (Exception e) {
err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
}
}
/**
* Expect this key on the next line read from the reader.
*/
public static boolean expect(BufferedReader in, String key) throws IOException {
String s = in.readLine();
if (s != null && s.equals(key)) {
return true;
}
return false;
}
}

View File

@ -33,6 +33,7 @@ import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.channels.FileLockInterruptionException; import java.nio.channels.FileLockInterruptionException;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.sjavac.Log; 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 * 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. * 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. * <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own * If you write code that depends on this, you do so at your own risk.
* risk. This code and its internal interfaces are subject to change * This code and its internal interfaces are subject to change or
* or deletion without notice.</b></p> * deletion without notice.</b>
*/ */
class PortFile { public class PortFile {
// Port file format: // Port file format:
// byte ordering: high byte first = big endian // byte ordering: high byte first = big endian
@ -72,8 +73,7 @@ class PortFile {
* Create a new portfile. * Create a new portfile.
* @param filename is the path to the file. * @param filename is the path to the file.
*/ */
public PortFile(String fn) throws FileNotFoundException public PortFile(String fn) throws FileNotFoundException {
{
filename = fn; filename = fn;
file = new File(filename); file = new File(filename);
stopFile = new File(filename+".stop"); stopFile = new File(filename+".stop");
@ -88,7 +88,7 @@ class PortFile {
/** /**
* Lock the port file. * Lock the port file.
*/ */
void lock() throws IOException { public void lock() throws IOException {
lock = channel.lock(); lock = channel.lock();
} }
@ -115,7 +115,7 @@ class PortFile {
containsPortInfo = false; containsPortInfo = false;
} }
} }
} catch (Exception e) { } catch (IOException e) {
containsPortInfo = false; containsPortInfo = false;
} }
} }
@ -131,7 +131,7 @@ class PortFile {
* If so, then we can acquire the tcp/ip port on localhost. * If so, then we can acquire the tcp/ip port on localhost.
*/ */
public int getPort() { public int getPort() {
assert(containsPortInfo); Assert.check(containsPortInfo);
return serverPort; return serverPort;
} }
@ -139,7 +139,7 @@ class PortFile {
* If so, then we can acquire the server cookie. * If so, then we can acquire the server cookie.
*/ */
public long getCookie() { public long getCookie() {
assert(containsPortInfo); Assert.check(containsPortInfo);
return serverCookie; return serverCookie;
} }
@ -147,7 +147,7 @@ class PortFile {
* Store the values into the locked port file. * Store the values into the locked port file.
*/ */
public void setValues(int port, long cookie) throws IOException { public void setValues(int port, long cookie) throws IOException {
assert(lock != null); Assert.check(lock != null);
rwfile.seek(0); rwfile.seek(0);
// Write the magic nr that identifes a port file. // Write the magic nr that identifes a port file.
rwfile.writeInt(magicNr); rwfile.writeInt(magicNr);
@ -192,7 +192,7 @@ class PortFile {
* Unlock the port file. * Unlock the port file.
*/ */
public void unlock() throws IOException { public void unlock() throws IOException {
assert(lock != null); Assert.check(lock != null);
lock.release(); lock.release();
lock = null; lock = null;
} }

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
/**
* Monitors the presence of a port file and shuts down the given SjavacServer
* whenever the port file is deleted or invalidated.
*
* TODO: JDK-8046882
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class PortFileMonitor {
// Check if the portfile is gone, every 5 seconds.
private final static int CHECK_PORTFILE_INTERVAL = 5000;
final private Timer timer = new Timer();
final private PortFile portFile;
final private SjavacServer server;
public PortFileMonitor(PortFile portFile,
SjavacServer server) {
this.portFile = portFile;
this.server = server;
}
public void start() {
TimerTask shutdownCheck = new TimerTask() {
public void run() {
try {
if (!portFile.exists()) {
// Time to quit because the portfile was deleted by another
// process, probably by the makefile that is done building.
server.shutdown("Quitting because portfile was deleted!");
} else if (portFile.markedForStop()) {
// Time to quit because another process touched the file
// server.port.stop to signal that the server should stop.
// This is necessary on some operating systems that lock
// the port file hard!
server.shutdown("Quitting because a portfile.stop file was found!");
} else if (!portFile.stillMyValues()) {
// Time to quit because another build has started.
server.shutdown("Quitting because portfile is now owned by another javac server!");
}
} catch (IOException e) {
e.printStackTrace(server.theLog);
server.flushLog();
}
}
};
timer.schedule(shutdownCheck, 0, CHECK_PORTFILE_INTERVAL);
}
public void shutdown() {
timer.cancel();
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Socket;
import java.net.URI;
import java.util.List;
import java.util.Set;
import com.sun.tools.sjavac.Log;
/**
* A RequestHandler handles requests performed over a socket. Specifically it
* - Reads the command string specifying which method is to be invoked
* - Reads the appropriate arguments
* - Delegates the actual invocation to the given sjavac implementation
* - Writes the result back to the socket output stream
*
* None of the work performed by this class is really bound by the CPU. It
* should be completely fine to have a large number of RequestHandlers active.
* To limit the number of concurrent compilations, use PooledSjavac.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class RequestHandler implements Runnable {
private final Socket socket;
private final Sjavac sjavac;
public RequestHandler(Socket socket, Sjavac sjavac) {
this.socket = socket;
this.sjavac = sjavac;
}
@Override
public void run() {
try (ObjectOutputStream oout = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream oin = new ObjectInputStream(socket.getInputStream())) {
String id = (String) oin.readObject();
String cmd = (String) oin.readObject();
Log.info("Handling request, id: " + id + " cmd: " + cmd);
switch (cmd) {
case SjavacServer.CMD_SYS_INFO: handleSysInfoRequest(oin, oout); break;
case SjavacServer.CMD_COMPILE: handleCompileRequest(oin, oout); break;
default: Log.error("Unknown command: " + cmd);
}
} catch (Exception ex) {
// Not much to be done at this point. The client side request
// code will most likely throw an IOException and the
// compilation will fail.
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
Log.error(sw.toString());
}
}
private void handleSysInfoRequest(ObjectInputStream oin,
ObjectOutputStream oout) throws IOException {
oout.writeObject(sjavac.getSysInfo());
oout.flush();
}
@SuppressWarnings("unchecked")
private void handleCompileRequest(ObjectInputStream oin,
ObjectOutputStream oout) throws IOException {
try {
// Read request arguments
String protocolId = (String) oin.readObject();
String invocationId = (String) oin.readObject();
String[] args = (String[]) oin.readObject();
List<File> explicitSources = (List<File>) oin.readObject();
Set<URI> sourcesToCompile = (Set<URI>) oin.readObject();
Set<URI> visibleSources = (Set<URI>) oin.readObject();
// Perform compilation
CompilationResult cr = sjavac.compile(protocolId,
invocationId,
args,
explicitSources,
sourcesToCompile,
visibleSources);
// Write request response
oout.writeObject(cr);
oout.flush();
} catch (ClassNotFoundException cnfe) {
throw new IOException(cnfe);
}
}
}

View File

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

View File

@ -0,0 +1,349 @@
/*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import com.sun.tools.sjavac.ProblemException;
import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.comp.SjavacImpl;
import com.sun.tools.sjavac.comp.PooledSjavac;
/**
* The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class SjavacServer implements Terminable {
// Used in protocol to indicate which method to invoke
public final static String CMD_COMPILE = "compile";
public final static String CMD_SYS_INFO = "sys-info";
final private String portfilename;
final private String logfile;
final private String stdouterrfile;
final private int poolsize;
final private int keepalive;
final private PrintStream err;
// The secret cookie shared between server and client through the port file.
// Used to prevent clients from believing that they are communicating with
// an old server when a new server has started and reused the same port as
// an old server.
private final long myCookie;
// Accumulated build time, not counting idle time, used for logging purposes
private long totalBuildTime;
// The javac server specific log file.
PrintWriter theLog;
// The sjavac implementation to delegate requests to
Sjavac sjavac;
private ServerSocket serverSocket;
private PortFile portFile;
private PortFileMonitor portFileMonitor;
// Set to false break accept loop
final AtomicBoolean keepAcceptingRequests = new AtomicBoolean();
// For the client, all port files fetched, one per started javac server.
// Though usually only one javac server is started by a client.
private static Map<String, PortFile> allPortFiles;
private static Map<String, Long> maxServerMemory;
public SjavacServer(String settings, PrintStream err) throws FileNotFoundException {
// Extract options. TODO: Change to proper constructor args
portfilename = Util.extractStringOption("portfile", settings);
logfile = Util.extractStringOption("logfile", settings);
stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
keepalive = Util.extractIntOption("keepalive", settings, 120);
poolsize = Util.extractIntOption("poolsize", settings,
Runtime.getRuntime().availableProcessors());
this.err = err;
myCookie = new Random().nextLong();
theLog = new PrintWriter(logfile);
}
/**
* Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
*/
public static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
if (allPortFiles == null) {
allPortFiles = new HashMap<>();
}
PortFile pf = allPortFiles.get(filename);
// Port file known. Does it still exist?
if (pf != null) {
try {
if (!pf.exists())
pf = null;
} catch (IOException ioex) {
ioex.printStackTrace();
}
}
if (pf == null) {
pf = new PortFile(filename);
allPortFiles.put(filename, pf);
}
return pf;
}
/**
* Get the cookie used for this server.
*/
long getCookie() {
return myCookie;
}
/**
* Get the port used for this server.
*/
int getPort() {
return serverSocket.getLocalPort();
}
/**
* Sum up the total build time for this javac server.
*/
public void addBuildTime(long inc) {
totalBuildTime += inc;
}
/**
* Log this message.
*/
public void log(String msg) {
if (theLog != null) {
theLog.println(msg);
} else {
System.err.println(msg);
}
}
/**
* Make sure the log is flushed.
*/
public void flushLog() {
if (theLog != null) {
theLog.flush();
}
}
/**
* Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
* is sent as the settings parameter. Returns 0 on success, -1 on failure.
*/
public int startServer() throws IOException {
long serverStart = System.currentTimeMillis();
// The port file is locked and the server port and cookie is written into it.
portFile = getPortFile(portfilename);
synchronized (portFile) {
portFile.lock();
portFile.getValues();
if (portFile.containsPortInfo()) {
err.println("Javac server not started because portfile exists!");
portFile.unlock();
return -1;
}
// .-----------. .--------. .------.
// socket -->| IdleReset |-->| Pooled |-->| Impl |--> javac
// '-----------' '--------' '------'
sjavac = new SjavacImpl();
sjavac = new PooledSjavac(sjavac, poolsize);
sjavac = new IdleResetSjavac(sjavac,
this,
keepalive * 1000);
serverSocket = new ServerSocket();
InetAddress localhost = InetAddress.getByName(null);
serverSocket.bind(new InetSocketAddress(localhost, 0));
// At this point the server accepts connections, so it is now safe
// to publish the port / cookie information
portFile.setValues(getPort(), getCookie());
portFile.unlock();
}
portFileMonitor = new PortFileMonitor(portFile, this);
portFileMonitor.start();
log("Sjavac server started. Accepting connections...");
log(" port: " + getPort());
log(" time: " + new java.util.Date());
log(" poolsize: " + poolsize);
flushLog();
keepAcceptingRequests.set(true);
do {
try {
Socket socket = serverSocket.accept();
new Thread(new RequestHandler(socket, sjavac)).start();
} catch (SocketException se) {
// Caused by serverSocket.close() and indicates shutdown
}
} while (keepAcceptingRequests.get());
log("Shutting down.");
// No more connections accepted. If any client managed to connect after
// the accept() was interrupted but before the server socket is closed
// here, any attempt to read or write to the socket will result in an
// IOException on the client side.
long realTime = System.currentTimeMillis() - serverStart;
log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
flushLog();
// Shut down
sjavac.shutdown();
return 0;
}
/**
* Fork a background process. Returns the command line used that can be printed if something failed.
*/
public static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
final PrintStream err, String stdouterrfile, boolean background)
throws IOException, ProblemException {
if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
stdouterrfile = null;
}
final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
if (background) {
sjavac += "%20" + startserver;
sjavac = sjavac.replaceAll("%20", " ");
sjavac = sjavac.replaceAll("%2C", ",");
// If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
if (!(new File("/bin/sh")).canExecute()) {
ArrayList<String> wincmd = new ArrayList<>();
wincmd.add("cmd");
wincmd.add("/c");
wincmd.add("start");
wincmd.add("cmd");
wincmd.add("/c");
wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
cmd = wincmd.toArray(new String[wincmd.size()]);
}
Process pp = null;
try {
pp = Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
e.printStackTrace(err);
e.printStackTrace(new PrintWriter(stdouterrfile));
}
StringBuilder rs = new StringBuilder();
for (String s : cmd) {
rs.append(s + " ");
}
return rs.toString();
}
// Do not spawn a background server, instead run it within the same JVM.
Thread t = new Thread() {
@Override
public void run() {
try {
SjavacServer server = new SjavacServer(startserver, err);
server.startServer();
} catch (Throwable t) {
t.printStackTrace(err);
}
}
};
t.setDaemon(true);
t.start();
return "";
}
@Override
public void shutdown(String quitMsg) {
if (!keepAcceptingRequests.compareAndSet(false, true)) {
// Already stopped, no need to shut down again
return;
}
log("Quitting: " + quitMsg);
flushLog();
portFileMonitor.shutdown(); // No longer any need to monitor port file
// Unpublish port before shutting down socket to minimize the number of
// failed connection attempts
try {
portFile.delete();
} catch (IOException e) {
e.printStackTrace(theLog);
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace(theLog);
}
}
public static void cleanup(String... args) {
String settings = Util.findServerSettings(args);
if (settings == null) return;
String portfile = Util.extractStringOption("portfile", settings);
String background = Util.extractStringOption("background", settings);
if (background != null && background.equals("false")) {
// If the server runs within this jvm, then delete the portfile,
// since this jvm is about to exit soon.
File f = new File(portfile);
f.delete();
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,7 +34,18 @@
*/ */
package com.sun.tools.sjavac.server; 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 int numCores;
public long maxMemory; public long maxMemory;

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.server;
/**
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public interface Terminable {
void shutdown(String quitMsg);
}

View File

@ -38,6 +38,7 @@ import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
@ -290,6 +291,7 @@ public abstract class JavadocTester {
break; break;
} }
} }
out.println("args: " + Arrays.toString(args));
// log.setOutDir(outputDir); // log.setOutDir(outputDir);
outputDirectoryCheck.check(outputDir); outputDirectoryCheck.check(outputDir);

View File

@ -25,7 +25,7 @@
* @test * @test
* @bug 4908512 5024825 4957203 4993280 4996963 6174696 6177059 7041249 * @bug 4908512 5024825 4957203 4993280 4996963 6174696 6177059 7041249
* @summary Make sure apt is removed and doesn't come back * @summary Make sure apt is removed and doesn't come back
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main CheckAptIsRemovedTest * @run main CheckAptIsRemovedTest
*/ */
@ -34,7 +34,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
//original test: test/tools/apt/Basics/apt.sh // Original test: test/tools/apt/Basics/apt.sh
public class CheckAptIsRemovedTest { public class CheckAptIsRemovedTest {
//I think this class can be let with the imports only and that should be enough for as test's purpose //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 = private static final String NullAPFSrc =
@ -77,20 +77,18 @@ public class CheckAptIsRemovedTest {
Path aptLin = Paths.get(testJDK, "bin", "apt"); Path aptLin = Paths.get(testJDK, "bin", "apt");
Path aptWin = Paths.get(testJDK, "bin", "apt.exe"); 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)) { if (Files.exists(aptLin) || Files.exists(aptWin)) {
throw new AssertionError("apt executable should not exist"); 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"); Path classpath = Paths.get(testJDK, "lib", "tools.jar");
ToolBox.JavaToolArgs javacArgs = ToolBox tb = new ToolBox();
new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL) tb.new JavacTask()
.setOptions("-sourcepath", ".", .classpath(classpath.toString()) // TODO: add overload
"-classpath", classpath.toString()) .sourcepath(".")
.setSources(NullAPFSrc); .sources(NullAPFSrc)
ToolBox.javac(javacArgs); .run(ToolBox.Expect.FAIL)
.writeAll();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,15 +25,17 @@
* @test * @test
* @bug 4846262 * @bug 4846262
* @summary check that javac operates correctly in EBCDIC locale * @summary check that javac operates correctly in EBCDIC locale
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main CheckEBCDICLocaleTest * @run main CheckEBCDICLocaleTest
*/ */
import java.io.File; import java.io.File;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
public class CheckEBCDICLocaleTest { public class CheckEBCDICLocaleTest {
@ -58,39 +60,32 @@ public class CheckEBCDICLocaleTest {
} }
public void test() throws Exception { public void test() throws Exception {
String native2asciiBinary = Paths.get( ToolBox tb = new ToolBox();
System.getProperty("test.jdk"),"bin", "native2ascii").toString(); Path native2asciiBinary = tb.getJDKTool("native2ascii");
ToolBox.createJavaFileFromSource(TestSrc); tb.writeFile("Test.java", TestSrc);
Files.createDirectory(Paths.get("output")); tb.createDirectories("output");
ToolBox.AnyToolArgs nativeCmdParams = tb.new ExecTask(native2asciiBinary)
new ToolBox.AnyToolArgs() .args("-reverse", "-encoding", "IBM1047", "Test.java", "output/Test.java")
.appendArgs(native2asciiBinary) .run();
.appendArgs(ToolBox.testToolVMOpts)
.appendArgs("-reverse", "-encoding", "IBM1047", "Test.java",
"output/Test.java");
ToolBox.executeCommand(nativeCmdParams);
ToolBox.AnyToolArgs javacParams = tb.new JavacTask(ToolBox.Mode.EXEC)
new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) .redirect(ToolBox.OutputKind.STDERR, "Test.tmp")
.appendArgs(ToolBox.javacBinary) .options("-J-Duser.language=en",
.appendArgs(ToolBox.testToolVMOpts) "-J-Duser.region=US",
.appendArgs("-J-Duser.language=en", "-J-Dfile.encoding=IBM1047")
"-J-Duser.region=US", "-J-Dfile.encoding=IBM1047", .files("output/Test.java")
"output/Test.java") .run(ToolBox.Expect.FAIL);
.setErrOutput(new File("Test.tmp"));
ToolBox.executeCommand(javacParams);
nativeCmdParams = new ToolBox.AnyToolArgs() tb.new ExecTask(native2asciiBinary)
.appendArgs(native2asciiBinary) .args("-encoding", "IBM1047", "Test.tmp", "Test.out")
.appendArgs(ToolBox.testToolVMOpts) .run();
.appendArgs("-encoding", "IBM1047", "Test.tmp", "Test.out");
ToolBox.executeCommand(nativeCmdParams);
String goldenFile = String.format(TestOutTemplate, File.separator); List<String> expectLines = Arrays.asList(
ToolBox.compareLines(Paths.get("Test.out"), String.format(TestOutTemplate, File.separator).split("\n"));
Arrays.asList(goldenFile.split("\n")), null, true); List<String> actualLines = Files.readAllLines(Paths.get("Test.out"));
tb.checkEqual(expectLines, actualLines);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,7 +26,7 @@
* @bug 6302184 6350124 6357979 * @bug 6302184 6350124 6357979
* @summary javac hidden options that generate source should use the given * @summary javac hidden options that generate source should use the given
* encoding, if available * encoding, if available
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run compile -encoding iso-8859-1 -XD-printsource T6302184.java * @run compile -encoding iso-8859-1 -XD-printsource T6302184.java
* @run main HiddenOptionsShouldUseGivenEncodingTest * @run main HiddenOptionsShouldUseGivenEncodingTest
@ -34,16 +34,19 @@
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; 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 class HiddenOptionsShouldUseGivenEncodingTest {
public static void main(String[] args) throws Exception { 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 ToolBox tb = new ToolBox();
//diff ${DIFFOPTS} -c ${TC}${FS}T6302184.java ${TS}${FS}T6302184.out String encoding = "iso-8859-1";
Path path1 = Paths.get(System.getProperty("test.classes"), "T6302184.java"); Path path1 = Paths.get(ToolBox.testClasses, "T6302184.java");
Path path2 = Paths.get(System.getProperty("test.src"), "T6302184.out"); List<String> file1 = tb.readAllLines(path1, encoding);
ToolBox.compareLines(path1, path2, "iso-8859-1"); Path path2 = Paths.get(ToolBox.testSrc, "T6302184.out");
List<String> file2 = tb.readAllLines(path2, encoding);
tb.checkEqual(file1, file2);
} }
} }

View File

@ -25,19 +25,18 @@
* @test * @test
* @bug 8023945 * @bug 8023945
* @summary javac wrongly allows a subclass of an anonymous class * @summary javac wrongly allows a subclass of an anonymous class
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main AnonymousSubclassTest * @run main AnonymousSubclassTest
*/ */
import java.util.ArrayList;
import java.io.IOException;
public class AnonymousSubclassTest { public class AnonymousSubclassTest {
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
new AnonymousSubclassTest().run(); new AnonymousSubclassTest().run();
} }
ToolBox tb = new ToolBox();
// To trigger the error we want, first we need to compile // To trigger the error we want, first we need to compile
// a class with an anonymous inner class: Foo$1. // a class with an anonymous inner class: Foo$1.
final String foo = final String foo =
@ -65,20 +64,21 @@ public class AnonymousSubclassTest {
"}"; "}";
void compOk(String code) throws Exception { 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 { void compFail(String code) throws Exception {
ArrayList<String> errors = new ArrayList<>(); String errs = tb.new JavacTask()
ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs(); .sources(code)
args.setSources(code) .classpath(".")
.appendArgs("-cp", ".", "-XDrawDiagnostics") .options("-XDrawDiagnostics")
.set(ToolBox.Expect.FAIL) .run(ToolBox.Expect.FAIL)
.setErrOutput(errors); .writeAll()
ToolBox.javac(args); .getOutput(ToolBox.OutputKind.DIRECT);
if (!errors.get(0).contains("cant.inherit.from.anon")) { if (!errs.contains("cant.inherit.from.anon")) {
System.out.println(errors.get(0));
throw new Exception("test failed"); throw new Exception("test failed");
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,19 +25,14 @@
* @test * @test
* @bug 4241229 4785453 * @bug 4241229 4785453
* @summary Test -classpath option and classpath defaults. * @summary Test -classpath option and classpath defaults.
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main ClassPathTest * @run main ClassPathTest
*/ */
import java.nio.file.Paths; 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 { public class ClassPathTest {
private static final String ClassPathTest1Src = private static final String ClassPathTest1Src =
@ -70,12 +65,12 @@ public class ClassPathTest {
"package pkg;\n" + "package pkg;\n" +
"public class ClassPathTestAux3 {}"; "public class ClassPathTestAux3 {}";
ProcessBuilder pb = null;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
new ClassPathTest().test(); new ClassPathTest().test();
} }
ToolBox tb = new ToolBox();
public void test() throws Exception { public void test() throws Exception {
createOutputDirAndSourceFiles(); createOutputDirAndSourceFiles();
checkCompileCommands(); checkCompileCommands();
@ -83,14 +78,16 @@ public class ClassPathTest {
void createOutputDirAndSourceFiles() throws Exception { void createOutputDirAndSourceFiles() throws Exception {
//dirs and files creation //dirs and files creation
ToolBox.createJavaFileFromSource(ClassPathTest1Src); tb.writeJavaFiles(Paths.get("."),
ToolBox.createJavaFileFromSource(ClassPathTest2Src); ClassPathTest1Src,
ToolBox.createJavaFileFromSource(ClassPathTest3Src); ClassPathTest2Src,
ToolBox.createJavaFileFromSource(Paths.get("foo"), ClassPathTest3Src);
tb.writeJavaFiles(Paths.get("foo"),
fooPkgClassPathTestAux1Src); fooPkgClassPathTestAux1Src);
ToolBox.createJavaFileFromSource(Paths.get("bar"), tb.writeJavaFiles(Paths.get("bar"),
barPkgClassPathTestAux2Src); barPkgClassPathTestAux2Src);
ToolBox.createJavaFileFromSource(pkgClassPathTestAux3Src); tb.writeJavaFiles(Paths.get("."),
pkgClassPathTestAux3Src);
} }
void checkCompileCommands() throws Exception { void checkCompileCommands() throws Exception {
@ -99,80 +96,55 @@ public class ClassPathTest {
// automatically but this is not happening when called using ProcessBuilder // automatically but this is not happening when called using ProcessBuilder
// testJavac success ClassPathTest3.java // testJavac success ClassPathTest3.java
List<String> mainArgs = new ArrayList<>(); tb.new JavacTask(ToolBox.Mode.EXEC)
mainArgs.add(ToolBox.javacBinary.toString()); .classpath(".")
if (ToolBox.testToolVMOpts != null) { .files("ClassPathTest3.java")
mainArgs.addAll(ToolBox.testToolVMOpts); .run();
}
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);
// testJavac failure ClassPathTest1.java // testJavac failure ClassPathTest1.java
ToolBox.AnyToolArgs failParams = tb.new JavacTask(ToolBox.Mode.EXEC)
new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) .classpath(".")
.appendArgs(commonArgs) .files("ClassPathTest1.java")
.appendArgs("ClassPathTest1.java"); .run(ToolBox.Expect.FAIL);
ToolBox.executeCommand(failParams);
// This is done inside the executeCommand method
// CLASSPATH=bar; export CLASSPATH
Map<String, String> extVars = new TreeMap<>();
extVars.put("CLASSPATH", "bar");
// testJavac success ClassPathTest2.java // testJavac success ClassPathTest2.java
successParams = new ToolBox.AnyToolArgs() tb.new JavacTask(ToolBox.Mode.EXEC)
.appendArgs(mainArgs) .envVar("CLASSPATH", "bar")
.appendArgs("ClassPathTest2.java") .files("ClassPathTest2.java")
.set(extVars); .run();
ToolBox.executeCommand(successParams);
// testJavac failure ClassPathTest1.java // testJavac failure ClassPathTest1.java
failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) tb.new JavacTask(ToolBox.Mode.EXEC)
.appendArgs(mainArgs) .envVar("CLASSPATH", "bar")
.appendArgs("ClassPathTest1.java") .files("ClassPathTest1.java")
.set(extVars); .run(ToolBox.Expect.FAIL);
ToolBox.executeCommand(failParams);
// testJavac failure ClassPathTest3.java // testJavac failure ClassPathTest3.java
failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) tb.new JavacTask(ToolBox.Mode.EXEC)
.appendArgs(mainArgs) .envVar("CLASSPATH", "bar")
.appendArgs("ClassPathTest3.java") .files("ClassPathTest3.java")
.set(extVars); .run(ToolBox.Expect.FAIL);
ToolBox.executeCommand(failParams);
// testJavac success -classpath foo ClassPathTest1.java // testJavac success -classpath foo ClassPathTest1.java
tb.new JavacTask(ToolBox.Mode.EXEC)
commonArgs.clear(); .envVar("CLASSPATH", "bar")
commonArgs.addAll(mainArgs); .classpath("foo")
commonArgs.addAll(Arrays.asList("-cp", "foo")); .files("ClassPathTest1.java")
.run();
successParams = new ToolBox.AnyToolArgs()
.appendArgs(commonArgs)
.appendArgs("ClassPathTest1.java")
.set(extVars);
ToolBox.executeCommand(successParams);
// testJavac failure -classpath foo ClassPathTest2.java // testJavac failure -classpath foo ClassPathTest2.java
failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) tb.new JavacTask(ToolBox.Mode.EXEC)
.appendArgs(commonArgs) .envVar("CLASSPATH", "bar")
.appendArgs("ClassPathTest2.java") .classpath("foo")
.set(extVars); .files("ClassPathTest2.java")
ToolBox.executeCommand(failParams); .run(ToolBox.Expect.FAIL);
// testJavac failure -classpath foo ClassPathTest3.java // testJavac failure -classpath foo ClassPathTest3.java
failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) tb.new JavacTask(ToolBox.Mode.EXEC)
.appendArgs(commonArgs) .envVar("CLASSPATH", "bar")
.appendArgs("ClassPathTest3.java") .classpath("foo")
.set(extVars); .files("ClassPathTest3.java")
ToolBox.executeCommand(failParams); .run(ToolBox.Expect.FAIL);
} }
} }

View File

@ -25,7 +25,7 @@
* @test * @test
* @bug 8025505 * @bug 8025505
* @summary Constant folding deficiency * @summary Constant folding deficiency
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main ConstFoldTest * @run main ConstFoldTest
*/ */
@ -45,23 +45,23 @@ public class ConstFoldTest {
int x; int x;
if (1 != 2) x=1; else x=0; if (1 != 2) x=1; else x=0;
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;
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 = 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;
x = null != null ? 1 : 0; x = null != null ? 1 : 0;
boolean b; boolean b;
b = 1 != 2 && true; b = 1 != 2 && true;
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;
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"; final String regex = "\\sif(?:null|nonnull|eq|ne){1}\\s";
void run() throws Exception { void run() throws Exception {
URL url = ConstFoldTest.class.getResource("ConstFoldTest$CFTest.class"); ToolBox tb = new ToolBox();
String result = ToolBox.javap(new ToolBox.JavaToolArgs().setAllArgs("-c", url.getFile()));
System.out.println(result);
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()) { if (!bad_codes.isEmpty()) {
for (String code : bad_codes) for (String code : bad_codes)
System.out.println("Bad OpCode Found: " + code); System.out.println("Bad OpCode Found: " + code);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,18 +25,14 @@
* @test * @test
* @bug 4204897 4256097 4785453 4863609 * @bug 4204897 4256097 4785453 4863609
* @summary Test that '.jar' files in -extdirs are found. * @summary Test that '.jar' files in -extdirs are found.
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main ExtDirTest * @run main ExtDirTest
*/ */
import java.io.File; 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 { public class ExtDirTest {
private static final String ExtDirTestClass1Src = private static final String ExtDirTestClass1Src =
@ -100,72 +96,73 @@ public class ExtDirTest {
"SHA-Digest: ILJOhwHg5US+yuw1Sc1d+Avu628=\n" + "SHA-Digest: ILJOhwHg5US+yuw1Sc1d+Avu628=\n" +
"MD5-Digest: j8wnz8wneEcuJ/gjXBBQNA==\n"; "MD5-Digest: j8wnz8wneEcuJ/gjXBBQNA==\n";
List<String> ouputDirParam = Arrays.asList("-d", ".");
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
new ExtDirTest().run(); new ExtDirTest().run();
} }
private final ToolBox tb = new ToolBox();
void run() throws Exception { void run() throws Exception {
createJars(); createJars();
compileWithExtDirs(); compileWithExtDirs();
} }
void createJars() throws Exception { void createJars() throws Exception {
sun.tools.jar.Main jarGenerator = tb.new JavacTask()
new sun.tools.jar.Main(System.out, System.err, "jar"); .outdir(".")
.sources(ExtDirTestClass1Src)
.run();
ToolBox.JavaToolArgs javacParams = tb.new JarTask("pkg1.jar")
new ToolBox.JavaToolArgs() .manifest(jar1Manifest)
.setOptions(ouputDirParam) .files("pkg1/ExtDirTestClass1.class")
.setSources(ExtDirTestClass1Src); .run();
ToolBox.javac(javacParams);
ToolBox.writeFile(Paths.get("pkg1", "MANIFEST.MF"), jar1Manifest); tb.new JavacTask()
jarGenerator.run(new String[] {"cfm", "pkg1.jar", "pkg1/MANIFEST.MF", .outdir(".")
"pkg1/ExtDirTestClass1.class"}); .sources(ExtDirTestClass2Src)
.run();
javacParams.setSources(ExtDirTestClass2Src); tb.new JarTask("pkg2.jar")
ToolBox.javac(javacParams); .manifest(jar2Manifest)
.files("pkg2/ExtDirTestClass2.class")
.run();
ToolBox.writeFile(Paths.get("pkg2", "MANIFEST.MF"), jar2Manifest); tb.createDirectories("ext1", "ext2", "ext3");
jarGenerator.run(new String[] {"cfm", "pkg2.jar", "pkg2/MANIFEST.MF", tb.copyFile("pkg1.jar", "ext1");
"pkg2/ExtDirTestClass2.class"}); 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")); tb.deleteFiles(
ToolBox.copyFile(Paths.get("ext2", "pkg2.jar"), Paths.get("pkg2.jar")); "pkg1.jar",
ToolBox.copyFile(Paths.get("ext3", "pkg1.jar"), Paths.get("pkg1.jar")); "pkg2.jar",
ToolBox.copyFile(Paths.get("ext3", "pkg2.jar"), Paths.get("pkg2.jar")); "pkg1/ExtDirTestClass1.class",
"pkg1",
Files.delete(Paths.get("pkg1.jar")); "pkg2/ExtDirTestClass2.class",
Files.delete(Paths.get("pkg2.jar")); "pkg2"
);
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"));
} }
void compileWithExtDirs() throws Exception { void compileWithExtDirs() throws Exception {
tb.new JavacTask()
.outdir(".")
.options("-extdirs", "ext1")
.sources(ExtDirTest_1Src)
.run()
.writeAll();
//javac -extdirs ext1 ExtDirTest_1.java tb.new JavacTask()
ToolBox.JavaToolArgs params = .outdir(".")
new ToolBox.JavaToolArgs() .options("-extdirs", "ext1" + File.pathSeparator + "ext2")
.setOptions("-d", ".", "-extdirs", "ext1") .sources(ExtDirTest_2Src)
.setSources(ExtDirTest_1Src); .run();
ToolBox.javac(params);
//javac -extdirs ext1:ext2 ExtDirTest_2.java tb.new JavacTask()
params.setOptions("-d", ".", "-extdirs", "ext1" + File.pathSeparator + "ext2") .outdir(".")
.setSources(ExtDirTest_2Src); .options("-extdirs", "ext3")
ToolBox.javac(params); .sources(ExtDirTest_3Src)
.run();
//javac -extdirs ext3 ExtDirTest_3.java
params.setOptions("-d", ".", "-extdirs", "ext3")
.setSources(ExtDirTest_3Src);
ToolBox.javac(params);
} }
} }

View File

@ -25,7 +25,7 @@
* @test * @test
* @bug 8034924 * @bug 8034924
* @summary Incorrect inheritance of inaccessible static method * @summary Incorrect inheritance of inaccessible static method
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main IncorrectInheritanceTest * @run main IncorrectInheritanceTest
*/ */
@ -59,10 +59,11 @@ public class IncorrectInheritanceTest {
} }
public void test() throws Exception { public void test() throws Exception {
ToolBox.JavaToolArgs javacParams = ToolBox tb = new ToolBox();
new ToolBox.JavaToolArgs()
.setSources(ASrc, BSrc, CSrc); tb.new JavacTask()
ToolBox.javac(javacParams); .sources(ASrc, BSrc, CSrc)
.run();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,25 +26,26 @@
* @bug 4509051 4785453 * @bug 4509051 4785453
* @summary javac <AT>sourcefiles should catch Exception, when sourcefiles * @summary javac <AT>sourcefiles should catch Exception, when sourcefiles
* doesn't exist. * doesn't exist.
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main MissingIncludeTest * @run main MissingIncludeTest
*/ */
//original test: test/tools/javac/MissingInclude.sh // Original test: test/tools/javac/MissingInclude.sh
public class MissingIncludeTest { public class MissingIncludeTest {
private static final String MissingIncludeSrc = private static final String MissingIncludeFile = "MissingInclude.java";
"class MissingInclude {}"; private static final String MissingIncludeSrc = "class MissingInclude {}";
public static void main(String[] args) throws Exception { 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} tb.writeFile(MissingIncludeFile, MissingIncludeSrc);
ToolBox.JavaToolArgs params =
new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL) tb.new JavacTask(ToolBox.Mode.CMDLINE)
.setAllArgs("@/nonexistent_file", "MissingInclude.java"); .options("@/nonexistent_file")
ToolBox.javac(params); .files(MissingIncludeFile)
.run(ToolBox.Expect.FAIL);
} }
} }

View File

@ -23,36 +23,49 @@
/* /*
* @test * @test
* @ignore 8055500 [javac] fix for 8030046 is incorrect
* @bug 8030046 * @bug 8030046
* @summary javac incorrectly handles absolute paths in manifest classpath * @summary javac incorrectly handles absolute paths in manifest classpath
* @author govereau * @author govereau
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main AbsolutePathTest * @run main AbsolutePathTest
*/ */
import java.io.File; import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class AbsolutePathTest { public class AbsolutePathTest {
public static void main(String... cmdline) throws Exception { public static void main(String... cmdline) throws Exception {
ToolBox tb = new ToolBox();
// compile test.Test // compile test.Test
ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs(); tb.new JavacTask()
args.appendArgs("-d", "."); // this is needed to get the classfiles in test .outdir(".") // this is needed to get the classfiles in test
ToolBox.javac(args.setSources("package test; public class Test{}")); .sources("package test; public class Test{}")
.run();
// build test.jar containing test.Test // build test.jar containing test.Test
// we need the jars in a directory different from the working // we need the jars in a directory different from the working
// directory to trigger the bug. I will reuse test/ // directory to trigger the bug.
ToolBox.jar("cf", "test/test.jar", "test/Test.class"); 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 // an absolute path reference to the first jar
String path = new File("test/test.jar").getAbsolutePath(); tb.new JarTask("jars/test2.jar")
ToolBox.mkManifestWithClassPath(null, path); .classpath(new File("jars/test.jar").getAbsolutePath())
ToolBox.jar("cfm", "test/test2.jar", "MANIFEST.MF"); .run();
// this should not fail // this should not fail
args.appendArgs("-cp", "."); tb.new JavacTask()
ToolBox.javac(args.setSources("import test.Test; class Test2 {}")); .outdir(".")
.classpath("jars/test2.jar")
.sources("import test.Test; class Test2 {}")
.run()
.writeAll();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,13 +25,13 @@
* @test * @test
* @bug 4087314 4800342 4307565 * @bug 4087314 4800342 4307565
* @summary Verify allowed access to protected class from another package * @summary Verify allowed access to protected class from another package
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main ProtectedInnerClassesTest * @run main ProtectedInnerClassesTest
*/ */
//original tests: test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh // Original tests: test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh
//and test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java // and test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java
public class ProtectedInnerClassesTest { public class ProtectedInnerClassesTest {
private static final String protectedInnerClass1Src = private static final String protectedInnerClass1Src =
@ -74,45 +74,36 @@ public class ProtectedInnerClassesTest {
new ProtectedInnerClassesTest().run(); new ProtectedInnerClassesTest().run();
} }
ToolBox tb = new ToolBox();
void run() throws Exception { void run() throws Exception {
compileAndExecute(); compileAndExecute();
compileOnly(); compileOnly();
} }
void compileAndExecute() throws Exception { void compileAndExecute() throws Exception {
//"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d "${TESTCLASSES}" "${TESTSRC}${FS}p1${FS}ProtectedInnerClass1.java" "${TESTSRC}${FS}p2${FS}ProtectedInnerClass2.java" tb.new JavacTask()
ToolBox.JavaToolArgs javacParams = .outdir(".")
new ToolBox.JavaToolArgs() .sources(protectedInnerClass1Src, protectedInnerClass2Src)
.setOptions("-d", ".") .run();
.setSources(protectedInnerClass1Src, protectedInnerClass2Src);
ToolBox.javac(javacParams); tb.new JavaTask()
.classpath(System.getProperty("user.dir"))
//"${TESTJAVA}${FS}bin${FS}java" ${TESTVMOPTS} -classpath "${CLASSPATH}${PS}${TESTCLASSES}" p2.ProtectedInnerClass2 .className("p2.ProtectedInnerClass2")
ToolBox.AnyToolArgs javaParams = .run();
new ToolBox.AnyToolArgs()
.appendArgs(ToolBox.javaBinary)
.appendArgs(ToolBox.testVMOpts)
.appendArgs("-classpath", System.getProperty("user.dir"),
"p2.ProtectedInnerClass2");
ToolBox.executeCommand(javaParams);
} }
//from test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java //from test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java
void compileOnly() throws Exception { void compileOnly() throws Exception {
//@run compile p1/ProtectedInnerClass1.java tb.new JavacTask()
ToolBox.JavaToolArgs javacParams = .outdir(".")
new ToolBox.JavaToolArgs() .sources(protectedInnerClass1Src)
.appendArgs("-d", ".") .run();
.setSources(protectedInnerClass1Src);
ToolBox.javac(javacParams); tb.new JavacTask()
.outdir(".")
//@run compile/fail p2/ProtectedInnerClass3.java .sources(protectedInnerClass3Src)
javacParams = new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL) .run(ToolBox.Expect.FAIL);
.appendArgs("-d", ".")
.setSources(protectedInnerClass3Src);
ToolBox.javac(javacParams);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,7 @@
* @test * @test
* @bug 5090006 * @bug 5090006
* @summary javac fails with assertion error * @summary javac fails with assertion error
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main AssertionFailureTest * @run main AssertionFailureTest
*/ */
@ -33,7 +33,7 @@
import java.io.File; import java.io.File;
import java.nio.file.Paths; import java.nio.file.Paths;
//original test: test/tools/javac/T5090006/compiler.sh // Original test: test/tools/javac/T5090006/compiler.sh
public class AssertionFailureTest { public class AssertionFailureTest {
private static final String testSrc = private static final String testSrc =
@ -54,16 +54,14 @@ public class AssertionFailureTest {
"}"; "}";
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
String classpath = Paths.get(System.getProperty("test.src"), "broken.jar") ToolBox tb = new ToolBox();
.toString(); String classpath = Paths.get(tb.testSrc, "broken.jar")
classpath = new StringBuilder(classpath) + File.pathSeparator
.append(File.pathSeparator).append(".").toString(); + ".";
// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -verbose -d "${TESTCLASSES}" -cp "${TESTSRC}${FS}broken.jar" "${TESTSRC}${FS}$1" tb.new JavacTask()
ToolBox.JavaToolArgs params = .classpath(classpath)
new ToolBox.JavaToolArgs() .sources(testSrc)
.setOptions("-cp", classpath) .run();
.setSources(testSrc);
ToolBox.javac(params);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,7 @@
* @test * @test
* @bug 6970173 * @bug 6970173
* @summary Debug pointer at bad position * @summary Debug pointer at bad position
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main DebugPointerAtBadPositionTest * @run main DebugPointerAtBadPositionTest
*/ */
@ -75,9 +75,10 @@ public class DebugPointerAtBadPositionTest {
} }
void compileTestClass() throws Exception { void compileTestClass() throws Exception {
ToolBox.JavaToolArgs javacSuccessArgs = ToolBox tb = new ToolBox();
new ToolBox.JavaToolArgs().setSources(testSource); tb.new JavacTask()
ToolBox.javac(javacSuccessArgs); .sources(testSource)
.run();
} }
void checkClassFile(final File cfile, String methodToFind) throws Exception { void checkClassFile(final File cfile, String methodToFind) throws Exception {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,7 @@
* @test * @test
* @bug 7008643 * @bug 7008643
* @summary inlined finally clauses confuse debuggers * @summary inlined finally clauses confuse debuggers
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main InlinedFinallyConfuseDebuggersTest * @run main InlinedFinallyConfuseDebuggersTest
*/ */
@ -73,6 +73,8 @@ public class InlinedFinallyConfuseDebuggersTest {
new InlinedFinallyConfuseDebuggersTest().run(); new InlinedFinallyConfuseDebuggersTest().run();
} }
ToolBox tb = new ToolBox();
void run() throws Exception { void run() throws Exception {
compileTestClass(); compileTestClass();
checkClassFile(new File(Paths.get(System.getProperty("user.dir"), checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
@ -80,9 +82,9 @@ public class InlinedFinallyConfuseDebuggersTest {
} }
void compileTestClass() throws Exception { void compileTestClass() throws Exception {
ToolBox.JavaToolArgs javacSuccessArgs = tb.new JavacTask()
new ToolBox.JavaToolArgs().setSources(testSource); .sources(testSource)
ToolBox.javac(javacSuccessArgs); .run();
} }
void checkClassFile(final File cfile, String methodToFind) throws Exception { void checkClassFile(final File cfile, String methodToFind) throws Exception {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,14 +27,13 @@
* @test * @test
* @bug 8009640 * @bug 8009640
* @summary -profile <compact> does not work when -bootclasspath specified * @summary -profile <compact> does not work when -bootclasspath specified
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main CheckRejectProfileBCPOptionsIfUsedTogetherTest * @run main CheckRejectProfileBCPOptionsIfUsedTogetherTest
*/ */
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import java.util.ArrayList; import java.nio.file.Paths;
import java.util.List;
public class CheckRejectProfileBCPOptionsIfUsedTogetherTest { public class CheckRejectProfileBCPOptionsIfUsedTogetherTest {
@ -44,21 +43,16 @@ public class CheckRejectProfileBCPOptionsIfUsedTogetherTest {
"}"; "}";
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
List<String> errOutput = new ArrayList<>(); ToolBox tb = new ToolBox();
String testJDK = ToolBox.jdkUnderTest;
ToolBox.createJavaFileFromSource(TestSrc);
ToolBox.AnyToolArgs javacParams = ToolBox.Result result = tb.new JavacTask(ToolBox.Mode.CMDLINE)
new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL) .options("-profile", "compact1",
.appendArgs(ToolBox.javacBinary) "-bootclasspath", Paths.get(ToolBox.testJDK, "jre/lib/rt.jar").toString())
.appendArgs(ToolBox.testToolVMOpts) .sources(TestSrc)
.appendArgs("-profile", "compact1", "-bootclasspath", .run(ToolBox.Expect.FAIL);
testJDK + "/jre/lib/rt.jar", "Test.java")
.setErrOutput(errOutput);
ToolBox.executeCommand(javacParams); String out = result.getOutput(ToolBox.OutputKind.DIRECT);
Assert.check(out.startsWith(
Assert.check(errOutput.get(0).startsWith(
"javac: profile and bootclasspath options cannot be used together"), "javac: profile and bootclasspath options cannot be used together"),
"Incorrect javac error output"); "Incorrect javac error output");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,7 @@
* @test * @test
* @bug 8010659 * @bug 8010659
* @summary Javac Crashes while building OpenJFX * @summary Javac Crashes while building OpenJFX
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main CompilerCrashWhenMixingBinariesAndSourcesTest * @run main CompilerCrashWhenMixingBinariesAndSourcesTest
*/ */
@ -48,19 +48,18 @@ public class CompilerCrashWhenMixingBinariesAndSourcesTest {
" Object m(int i) {return null;}\n" + " Object m(int i) {return null;}\n" +
"}"; "}";
public static void main (String[] args) throws Exception{ public static void main(String[] args) throws Exception {
ToolBox.JavaToolArgs javacParams = new ToolBox.JavaToolArgs() ToolBox tb = new ToolBox();
.setSources(ASource, BSource, CSource, DSource);
ToolBox.javac(javacParams);
ToolBox.rm("A.class"); tb.new JavacTask()
ToolBox.rm("A$1.class"); .sources(ASource, BSource, CSource, DSource)
ToolBox.rm("C.class"); .run();
ToolBox.rm("D.class");
javacParams = new ToolBox.JavaToolArgs() tb.deleteFiles("A.class", "A$1.class", "C.class", "D.class");
.setOptions("-cp", ".")
.setSources(ASource, CSource, DSource); tb.new JavacTask()
ToolBox.javac(javacParams); .classpath(".")
.sources(ASource, CSource, DSource)
.run();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,7 @@
* @test * @test
* @bug 8013394 * @bug 8013394
* @summary compile of iterator use fails with error "defined in an inaccessible class or interface" * @summary compile of iterator use fails with error "defined in an inaccessible class or interface"
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main CompileErrorWithIteratorTest * @run main CompileErrorWithIteratorTest
*/ */
@ -71,15 +71,16 @@ public class CompileErrorWithIteratorTest {
new CompileErrorWithIteratorTest().run(); new CompileErrorWithIteratorTest().run();
} }
ToolBox tb = new ToolBox();
void run() throws Exception { void run() throws Exception {
compile(); compile();
} }
void compile() throws Exception { void compile() throws Exception {
ToolBox.JavaToolArgs javacParams = tb.new JavacTask()
new ToolBox.JavaToolArgs() .sources(TestCollectionSrc, TestSrc)
.setSources(TestCollectionSrc, TestSrc); .run();
ToolBox.javac(javacParams);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,7 @@
* @test * @test
* @bug 8019486 8026861 8027142 * @bug 8019486 8026861 8027142
* @summary javac, generates erroneous LVT for a test case with lambda code * @summary javac, generates erroneous LVT for a test case with lambda code
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main WrongLNTForLambdaTest * @run main WrongLNTForLambdaTest
*/ */
@ -125,6 +125,8 @@ public class WrongLNTForLambdaTest {
new WrongLNTForLambdaTest().run(); new WrongLNTForLambdaTest().run();
} }
ToolBox tb = new ToolBox();
void run() throws Exception { void run() throws Exception {
compileTestClass(); compileTestClass();
checkClassFile(new File(Paths.get(System.getProperty("user.dir"), checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
@ -146,9 +148,9 @@ public class WrongLNTForLambdaTest {
} }
void compileTestClass() throws Exception { void compileTestClass() throws Exception {
ToolBox.JavaToolArgs javacSuccessArgs = tb.new JavacTask()
new ToolBox.JavaToolArgs().setSources(testSource); .sources(testSource)
ToolBox.javac(javacSuccessArgs); .run();
} }
void checkClassFile(final File cfile, String methodToFind, int[][] expectedLNT) throws Exception { void checkClassFile(final File cfile, String methodToFind, int[][] expectedLNT) throws Exception {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,14 +25,11 @@
* @test * @test
* @bug 8022162 * @bug 8022162
* @summary Incorrect signature determination for certain inner class generics * @summary Incorrect signature determination for certain inner class generics
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main IncorrectSignatureDeterminationForInnerClassesTest * @run main IncorrectSignatureDeterminationForInnerClassesTest
*/ */
import java.nio.file.Files;
import java.nio.file.Paths;
public class IncorrectSignatureDeterminationForInnerClassesTest { public class IncorrectSignatureDeterminationForInnerClassesTest {
private static final String DSrc = private static final String DSrc =
@ -69,21 +66,20 @@ public class IncorrectSignatureDeterminationForInnerClassesTest {
} }
void compile() throws Exception { void compile() throws Exception {
Files.createDirectory(Paths.get("classes")); ToolBox tb = new ToolBox();
tb.createDirectories("classes");
ToolBox.JavaToolArgs javacParams = tb.new JavacTask()
new ToolBox.JavaToolArgs() .outdir("classes")
.appendArgs("-d", "classes") .sources(DSrc)
.setSources(DSrc); .run();
ToolBox.javac(javacParams);
// compile class H against the class files for classes D and Q // compile class H against the class files for classes D and Q
javacParams = tb.new JavacTask()
new ToolBox.JavaToolArgs() .outdir("classes")
.appendArgs("-d", "classes", "-cp", "classes") .classpath("classes")
.setSources(HSrc); .sources(HSrc)
ToolBox.javac(javacParams); .run();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,7 @@
* @test * @test
* @bug 8024039 * @bug 8024039
* @summary javac, previous solution for JDK-8022186 was incorrect * @summary javac, previous solution for JDK-8022186 was incorrect
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main NoDeadCodeGenerationOnTrySmtTest * @run main NoDeadCodeGenerationOnTrySmtTest
*/ */
@ -76,6 +76,8 @@ public class NoDeadCodeGenerationOnTrySmtTest {
static final String[] methodsToLookFor = {"m1", "m2"}; static final String[] methodsToLookFor = {"m1", "m2"};
ToolBox tb = new ToolBox();
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
new NoDeadCodeGenerationOnTrySmtTest().run(); new NoDeadCodeGenerationOnTrySmtTest().run();
} }
@ -87,9 +89,9 @@ public class NoDeadCodeGenerationOnTrySmtTest {
} }
void compileTestClass() throws Exception { void compileTestClass() throws Exception {
ToolBox.JavaToolArgs javacSuccessArgs = tb.new JavacTask()
new ToolBox.JavaToolArgs().setSources(testSource); .sources(testSource)
ToolBox.javac(javacSuccessArgs); .run();
} }
void checkClassFile(final File cfile, String[] methodsToFind) throws Exception { void checkClassFile(final File cfile, String[] methodsToFind) throws Exception {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,7 @@
* @test * @test
* @bug 8024437 * @bug 8024437
* @summary Inferring the exception thrown by a lambda: sometimes fails to compile * @summary Inferring the exception thrown by a lambda: sometimes fails to compile
* @library /tools/javac/lib * @library /tools/lib
* @build ToolBox * @build ToolBox
* @run main ExceptionInferenceFromClassFileTest * @run main ExceptionInferenceFromClassFileTest
*/ */
@ -56,19 +56,19 @@ public class ExceptionInferenceFromClassFileTest {
"}"; "}";
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Files.createDirectory(Paths.get("out")); ToolBox tb = new ToolBox();
tb.createDirectories("out");
ToolBox.JavaToolArgs compileABParams = tb.new JavacTask()
new ToolBox.JavaToolArgs() .outdir("out")
.setOptions("-d", "out") .sources(ABSrc)
.setSources(ABSrc); .run();
ToolBox.javac(compileABParams);
ToolBox.JavaToolArgs compileCParams = tb.new JavacTask()
new ToolBox.JavaToolArgs() .outdir("out")
.setOptions("-d", "out", "-cp", "out") .classpath("out")
.setSources(CSrc); .sources(CSrc)
ToolBox.javac(compileCParams); .run();
} }
} }

View File

@ -0,0 +1,11 @@
/*
* @test /nodynamiccopyright/
* @bug 8054964
* @summary Invalid package annotations
* @author sogoel
*
* @compile/fail/ref=InvalidPackageAnno.out -XDrawDiagnostics bar/package-info.java
*/
package bar;

View File

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

View File

@ -1,32 +1,9 @@
/* /*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6393539 * @bug 6393539
* @summary no compile-time error for clone, etc. in annotation type * @summary no compile-time error for clone, etc. in annotation type
* @author Peter von der Ah\u00e9 * @author Peter von der Ah\u00e9
* @compile/fail NoAnnotationMethods.java * @compile/fail/ref=NoAnnotationMethods.out -XDrawDiagnostics NoAnnotationMethods.java
*/ */
public @interface NoAnnotationMethods { public @interface NoAnnotationMethods {

View File

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

View File

@ -1,32 +1,9 @@
/* /*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6393539 * @bug 6393539
* @summary no compile-time error for clone, etc. in annotation type * @summary no compile-time error for clone, etc. in annotation type
* @author Peter von der Ah\u00e9 * @author Peter von der Ah\u00e9
* @compile/fail NoClone.java * @compile/fail/ref=NoClone.out -XDrawDiagnostics NoClone.java
*/ */
public @interface NoClone { public @interface NoClone {

View File

@ -0,0 +1,3 @@
NoClone.java:10:5: compiler.err.invalid.annotation.member.type
NoClone.java:10:12: compiler.err.intf.annotation.member.clash: clone(), java.lang.Object
2 errors

View File

@ -1,32 +1,9 @@
/* /*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6393539 * @bug 6393539
* @summary no compile-time error for clone, etc. in annotation type * @summary no compile-time error for clone, etc. in annotation type
* @author Peter von der Ah\u00e9 * @author Peter von der Ah\u00e9
* @compile/fail NoObjectMethods.java * @compile/fail/ref=NoObjectMethods.out -XDrawDiagnostics NoObjectMethods.java
*/ */
public @interface NoObjectMethods { public @interface NoObjectMethods {

View File

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

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4901264 * @bug 4901264
* @summary JSR175 (2): don't allow annotating members from Object * @summary JSR175 (2): don't allow annotating members from Object
* @author gafter * @author gafter
* *
* @compile/fail ObjectMembers.java * @compile/fail/ref=ObjectMembers.out -XDrawDiagnostics ObjectMembers.java
*/ */
@ObjectMembers(hashCode = 23) @ObjectMembers(hashCode = 23)

View File

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

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4901275 4989669 * @bug 4901275 4989669
* @summary JSR175 (7): implement <at>Overrides * @summary JSR175 (7): implement <at>Overrides
* @author gafter * @author gafter
* *
* @compile/fail OverrideNo.java * @compile/fail/ref=OverrideNo.out -XDrawDiagnostics OverrideNo.java
*/ */
package overrideNo; package overrideNo;

View File

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

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4901290 * @bug 4901290
* @summary Package annotations * @summary Package annotations
* @author gafter * @author gafter
* *
* @compile/fail Package.java * @compile/fail/ref=Package.out -XDrawDiagnostics Package.java
*/ */
@java.lang.annotation.Documented @java.lang.annotation.Documented

View File

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

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4993451 * @bug 4993451
* @summary compiler crash with malformed annotations * @summary compiler crash with malformed annotations
* @author gafter * @author gafter
* *
* @compile/fail Recovery.java * @compile/fail/ref=Recovery.out -XDrawDiagnostics Recovery.java
*/ */
import java.lang.annotation.*; import java.lang.annotation.*;

View File

@ -0,0 +1,2 @@
Recovery.java:12:2: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.annotation.RetentionPolicy, java.lang.annotation.Annotation)
1 error

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4963450 * @bug 4963450
* @summary Assertion error is thrown when an annotation class cannot be found. * @summary Assertion error is thrown when an annotation class cannot be found.
* @author gafter * @author gafter
* *
* @compile/fail Recovery1.java * @compile/fail/ref=Recovery1.out -XDrawDiagnostics Recovery1.java
*/ */
package recovery1; package recovery1;

View File

@ -0,0 +1,4 @@
Recovery1.java:14:5: compiler.err.cant.resolve.location: kindname.class, Marker, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
Recovery1.java:14:30: compiler.err.cant.resolve.location: kindname.class, Marker, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
Recovery1.java:18:43: compiler.err.cant.resolve.location.args: kindname.method, markerToo, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
3 errors

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4901280 * @bug 4901280
* @summary name lookup scope for annotations * @summary name lookup scope for annotations
* @author gafter * @author gafter
* *
* @compile/fail Scope.java * @compile/fail/ref=Scope.out -XDrawDiagnostics Scope.java
*/ */
package annotation.scope; package annotation.scope;

View File

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

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4974524 * @bug 4974524
* @summary compiler crash with ill-formed annotation * @summary compiler crash with ill-formed annotation
* @author gafter * @author gafter
* *
* @compile/fail Syntax1.java * @compile/fail/ref=Syntax1.out -XDrawDiagnostics Syntax1.java
*/ */
package syntax1; package syntax1;

View File

@ -0,0 +1,4 @@
Syntax1.java:17:20: compiler.err.annotation.value.must.be.name.value
Syntax1.java:17:40: compiler.err.annotation.value.must.be.name.value
Syntax1.java:17:1: compiler.err.annotation.missing.default.value: java.lang.annotation.Target, value
3 errors

View File

@ -1,35 +1,14 @@
/* /*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4901271 * @bug 4901271
* @summary java.lang.annotation.Target * @summary java.lang.annotation.Target
* @author gafter * @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}) @java.lang.annotation.Target({FIELD})
@interface foo { @interface foo {
} }

View File

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

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4973504 * @bug 4973504
* @summary Compiler allows Inherited meta-attribute on local variable declaration. * @summary Compiler allows Inherited meta-attribute on local variable declaration.
* @author gafter * @author gafter
* *
* @compile/fail WrongTarget2.java * @compile/fail/ref=WrongTarget2.out -XDrawDiagnostics WrongTarget2.java
*/ */
import java.lang.annotation.Inherited; import java.lang.annotation.Inherited;

View File

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

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4951298 * @bug 4951298
* @summary compiler: crashes when attributes with same elements are used in place of other * @summary compiler: crashes when attributes with same elements are used in place of other
* @author gafter * @author gafter
* *
* @compile/fail WrongValue.java * @compile/fail/ref=WrongValue.out -XDrawDiagnostics WrongValue.java
*/ */
@interface TestM2 { @interface TestM2 {

View File

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

View File

@ -1,33 +1,10 @@
/* /*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. * @test /nodynamiccopyright/
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4865660 * @bug 4865660
* @summary implement "metadata" (attribute interfaces and program annotations) * @summary implement "metadata" (attribute interfaces and program annotations)
* @author gafter * @author gafter
* *
* @compile/fail Z1.java * @compile/fail/ref=Z1.out -XDrawDiagnostics Z1.java
*/ */
enum Color { red, green, blue } enum Color { red, green, blue }

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