提交 e90a4362 编写于 作者: V vinnie

Merge

......@@ -244,6 +244,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
for (i = 0; i < argc ; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
AddOption("-Dsun.java.launcher.diag=true", NULL);
}
CreateExecutionEnvironment(&argc, &argv,
......@@ -1009,6 +1010,8 @@ ParseArguments(int *pargc, char ***pargv,
} else if (JLI_StrCmp(arg, "-XshowSettings") == 0 ||
JLI_StrCCmp(arg, "-XshowSettings:") == 0) {
showSettings = arg;
} else if (JLI_StrCmp(arg, "-Xdiag") == 0) {
AddOption("-Dsun.java.launcher.diag=true", NULL);
/*
* The following case provide backward compatibility with old-style
* command line options.
......
......@@ -143,7 +143,7 @@ public class Continuation extends ResolveResult {
e.setRemainingName(remainingName);
e.setResolvedObj(resolvedObj);
if (starter == null)
if (starter == null || starter.isEmpty())
e.setResolvedName(null);
else if (remainingName == null)
e.setResolvedName(starter);
......
......@@ -70,11 +70,11 @@ public class PrintStream extends FilterOutputStream
private OutputStreamWriter charOut;
/**
* nonNull is explicitly declared here so as not to create an extra
* dependency on java.util.Objects.nonNull. PrintStream is loaded
* requireNonNull is explicitly declared here so as not to create an extra
* dependency on java.util.Objects.requireNonNull. PrintStream is loaded
* early during system initialization.
*/
private static <T> T nonNull(T obj, String message) {
private static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
......@@ -88,7 +88,7 @@ public class PrintStream extends FilterOutputStream
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
nonNull(csn, "charsetName");
requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
......@@ -148,7 +148,7 @@ public class PrintStream extends FilterOutputStream
* @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
*/
public PrintStream(OutputStream out, boolean autoFlush) {
this(autoFlush, nonNull(out, "Null output stream"));
this(autoFlush, requireNonNull(out, "Null output stream"));
}
/**
......@@ -173,7 +173,7 @@ public class PrintStream extends FilterOutputStream
throws UnsupportedEncodingException
{
this(autoFlush,
nonNull(out, "Null output stream"),
requireNonNull(out, "Null output stream"),
toCharset(encoding));
}
......
......@@ -82,7 +82,7 @@ public class PrintWriter extends Writer {
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
Objects.nonNull(csn, "charsetName");
Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
......
......@@ -68,8 +68,8 @@ public final class StackTraceElement implements java.io.Serializable {
*/
public StackTraceElement(String declaringClass, String methodName,
String fileName, int lineNumber) {
this.declaringClass = Objects.nonNull(declaringClass, "Declaring class is null");
this.methodName = Objects.nonNull(methodName, "Method name is null");
this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
this.methodName = Objects.requireNonNull(methodName, "Method name is null");
this.fileName = fileName;
this.lineNumber = lineNumber;
}
......
......@@ -56,7 +56,7 @@ public final class DirectoryIteratorException
* if the cause is {@code null}
*/
public DirectoryIteratorException(IOException cause) {
super(Objects.nonNull(cause));
super(Objects.requireNonNull(cause));
}
/**
......
......@@ -69,8 +69,7 @@ class FileTreeWalker {
FileVisitResult result = walk(start,
0,
new ArrayList<AncestorDirectory>());
if (result == null)
throw new NullPointerException("FileVisitor returned null");
Objects.requireNonNull(result, "FileVisitor returned null");
}
/**
......
......@@ -2779,7 +2779,7 @@ public final class Files {
throws IOException
{
// ensure not null before opening file
Objects.nonNull(in);
Objects.requireNonNull(in);
// check for REPLACE_EXISTING
boolean replaceExisting = false;
......@@ -2861,7 +2861,7 @@ public final class Files {
*/
public static long copy(Path source, OutputStream out) throws IOException {
// ensure not null before opening file
Objects.nonNull(out);
Objects.requireNonNull(out);
try (InputStream in = newInputStream(source)) {
return copy(in, out);
......@@ -3035,7 +3035,7 @@ public final class Files {
throws IOException
{
// ensure bytes is not null before opening file
Objects.nonNull(bytes);
Objects.requireNonNull(bytes);
try (OutputStream out = Files.newOutputStream(path, options)) {
int len = bytes.length;
......@@ -3094,7 +3094,7 @@ public final class Files {
throws IOException
{
// ensure lines is not null before opening file
Objects.nonNull(lines);
Objects.requireNonNull(lines);
CharsetEncoder encoder = cs.newEncoder();
OutputStream out = newOutputStream(path, options);
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
......
......@@ -57,8 +57,8 @@ public class SimpleFileVisitor<T> implements FileVisitor<T> {
public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
throws IOException
{
Objects.nonNull(dir);
Objects.nonNull(attrs);
Objects.requireNonNull(dir);
Objects.requireNonNull(attrs);
return FileVisitResult.CONTINUE;
}
......@@ -72,8 +72,8 @@ public class SimpleFileVisitor<T> implements FileVisitor<T> {
public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
throws IOException
{
Objects.nonNull(file);
Objects.nonNull(attrs);
Objects.requireNonNull(file);
Objects.requireNonNull(attrs);
return FileVisitResult.CONTINUE;
}
......@@ -87,7 +87,7 @@ public class SimpleFileVisitor<T> implements FileVisitor<T> {
public FileVisitResult visitFileFailed(T file, IOException exc)
throws IOException
{
Objects.nonNull(file);
Objects.requireNonNull(file);
throw exc;
}
......@@ -104,7 +104,7 @@ public class SimpleFileVisitor<T> implements FileVisitor<T> {
public FileVisitResult postVisitDirectory(T dir, IOException exc)
throws IOException
{
Objects.nonNull(dir);
Objects.requireNonNull(dir);
if (exc != null)
throw exc;
return FileVisitResult.CONTINUE;
......
......@@ -47,9 +47,6 @@ import java.text.DateFormatSymbols;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -1859,7 +1856,7 @@ public final class Formatter implements Closeable, Flushable {
private static Charset toCharset(String csn)
throws UnsupportedEncodingException
{
Objects.nonNull(csn, "charsetName");
Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
......@@ -2179,7 +2176,7 @@ public final class Formatter implements Closeable, Flushable {
*/
public Formatter(PrintStream ps) {
this(Locale.getDefault(Locale.Category.FORMAT),
(Appendable)Objects.nonNull(ps));
(Appendable)Objects.requireNonNull(ps));
}
/**
......
......@@ -187,7 +187,7 @@ public final class Objects {
* and constructors, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar) {
* this.bar = Objects.nonNull(bar);
* this.bar = Objects.requireNonNull(bar);
* }
* </pre></blockquote>
*
......@@ -196,7 +196,7 @@ public final class Objects {
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
public static <T> T nonNull(T obj) {
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
......@@ -209,8 +209,8 @@ public final class Objects {
* constructors with multiple parameters, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar, Baz baz) {
* this.bar = Objects.nonNull(bar, "bar must not be null");
* this.baz = Objects.nonNull(baz, "baz must not be null");
* this.bar = Objects.requireNonNull(bar, "bar must not be null");
* this.baz = Objects.requireNonNull(baz, "baz must not be null");
* }
* </pre></blockquote>
*
......@@ -221,7 +221,7 @@ public final class Objects {
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
public static <T> T nonNull(T obj, String message) {
public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
......
......@@ -35,6 +35,7 @@ import java.nio.channels.*;
import java.nio.charset.*;
import java.text.*;
import java.util.Locale;
import sun.misc.LRUCache;
/**
......@@ -592,7 +593,7 @@ public final class Scanner implements Iterator<String>, Closeable {
* interface
*/
public Scanner(Readable source) {
this(Objects.nonNull(source, "source"), WHITESPACE_PATTERN);
this(Objects.requireNonNull(source, "source"), WHITESPACE_PATTERN);
}
/**
......@@ -619,7 +620,7 @@ public final class Scanner implements Iterator<String>, Closeable {
* does not exist
*/
public Scanner(InputStream source, String charsetName) {
this(makeReadable(Objects.nonNull(source, "source"), toCharset(charsetName)),
this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)),
WHITESPACE_PATTERN);
}
......@@ -629,7 +630,7 @@ public final class Scanner implements Iterator<String>, Closeable {
* @throws IllegalArgumentException if the charset is not supported
*/
private static Charset toCharset(String csn) {
Objects.nonNull(csn, "charsetName");
Objects.requireNonNull(csn, "charsetName");
try {
return Charset.forName(csn);
} catch (IllegalCharsetNameException|UnsupportedCharsetException e) {
......@@ -670,7 +671,7 @@ public final class Scanner implements Iterator<String>, Closeable {
public Scanner(File source, String charsetName)
throws FileNotFoundException
{
this(Objects.nonNull(source), toDecoder(charsetName));
this(Objects.requireNonNull(source), toDecoder(charsetName));
}
private Scanner(File source, CharsetDecoder dec)
......@@ -680,7 +681,7 @@ public final class Scanner implements Iterator<String>, Closeable {
}
private static CharsetDecoder toDecoder(String charsetName) {
Objects.nonNull(charsetName, "charsetName");
Objects.requireNonNull(charsetName, "charsetName");
try {
return Charset.forName(charsetName).newDecoder();
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
......@@ -729,7 +730,7 @@ public final class Scanner implements Iterator<String>, Closeable {
* @since 1.7
*/
public Scanner(Path source, String charsetName) throws IOException {
this(Objects.nonNull(source), toCharset(charsetName));
this(Objects.requireNonNull(source), toCharset(charsetName));
}
private Scanner(Path source, Charset charset) throws IOException {
......@@ -755,7 +756,7 @@ public final class Scanner implements Iterator<String>, Closeable {
* @param source A channel to scan
*/
public Scanner(ReadableByteChannel source) {
this(makeReadable(Objects.nonNull(source, "source")),
this(makeReadable(Objects.requireNonNull(source, "source")),
WHITESPACE_PATTERN);
}
......@@ -775,7 +776,7 @@ public final class Scanner implements Iterator<String>, Closeable {
* does not exist
*/
public Scanner(ReadableByteChannel source, String charsetName) {
this(makeReadable(Objects.nonNull(source, "source"), toDecoder(charsetName)),
this(makeReadable(Objects.requireNonNull(source, "source"), toDecoder(charsetName)),
WHITESPACE_PATTERN);
}
......
......@@ -101,6 +101,11 @@ import java.util.Arrays;
* <td headers="matches">The character with hexadecimal&nbsp;value&nbsp;<tt>0x</tt><i>hh</i></td></tr>
* <tr><td valign="top" headers="construct characters"><tt>&#92;u</tt><i>hhhh</i></td>
* <td headers="matches">The character with hexadecimal&nbsp;value&nbsp;<tt>0x</tt><i>hhhh</i></td></tr>
* <tr><td valign="top" headers="construct characters"><tt>&#92;x</tt><i>{h...h}</i></td>
* <td headers="matches">The character with hexadecimal&nbsp;value&nbsp;<tt>0x</tt><i>h...h</i>
* ({@link java.lang.Character#MIN_CODE_POINT Character.MIN_CODE_POINT}
* &nbsp;&lt;=&nbsp;<tt>0x</tt><i>h...h</i>&nbsp;&lt;=&nbsp
* {@link java.lang.Character#MAX_CODE_POINT Character.MAX_CODE_POINT})</td></tr>
* <tr><td valign="top" headers="matches"><tt>\t</tt></td>
* <td headers="matches">The tab character (<tt>'&#92;u0009'</tt>)</td></tr>
* <tr><td valign="top" headers="construct characters"><tt>\n</tt></td>
......@@ -529,6 +534,13 @@ import java.util.Arrays;
* while not equal, compile into the same pattern, which matches the character
* with hexadecimal value <tt>0x2014</tt>.
*
* <p> A Unicode character can also be represented in a regular-expression by
* using its hexadecimal code point value directly as described in construct
* <tt>&#92;x{...}</tt>, for example a supplementary character U+2011F
* can be specified as <tt>&#92;x{2011F}</tt>, instead of two consecutive
* Unicode escape sequences of the surrogate pair
* <tt>&#92;uD840</tt><tt>&#92;uDD1F</tt>.
*
* <a name="ubc">
* <p>Unicode scripts, blocks and categories are written with the <tt>\p</tt> and
* <tt>\P</tt> constructs as in Perl. <tt>\p{</tt><i>prop</i><tt>}</tt> matches if
......@@ -2993,6 +3005,16 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
if (ASCII.isHexDigit(m)) {
return ASCII.toDigit(n) * 16 + ASCII.toDigit(m);
}
} else if (n == '{' && ASCII.isHexDigit(peek())) {
int ch = 0;
while (ASCII.isHexDigit(n = read())) {
ch = (ch << 4) + ASCII.toDigit(n);
if (ch > Character.MAX_CODE_POINT)
throw error("Hexadecimal codepoint is too big");
}
if (n != '}')
throw error("Unclosed hexadecimal escape sequence");
return ch;
}
throw error("Illegal hexadecimal escape sequence");
}
......
......@@ -63,8 +63,6 @@ import java.util.jar.Manifest;
public enum LauncherHelper {
INSTANCE;
private static final String defaultBundleName =
"sun.launcher.resources.launcher";
private static final String MAIN_CLASS = "Main-Class";
private static StringBuilder outBuf = new StringBuilder();
......@@ -76,11 +74,14 @@ public enum LauncherHelper {
private static final String PROP_SETTINGS = "Property settings:";
private static final String LOCALE_SETTINGS = "Locale settings:";
private static synchronized ResourceBundle getLauncherResourceBundle() {
if (javarb == null) {
javarb = ResourceBundle.getBundle(defaultBundleName);
}
return javarb;
// sync with java.c and sun.misc.VM
private static final String diagprop = "sun.java.launcher.diag";
private static final String defaultBundleName =
"sun.launcher.resources.launcher";
private static class ResourceBundleHolder {
private static final ResourceBundle RB =
ResourceBundle.getBundle(defaultBundleName);
}
/*
......@@ -308,7 +309,7 @@ public enum LauncherHelper {
* apply any arguments that we might pass.
*/
private static String getLocalizedMessage(String key, Object... args) {
String msg = getLauncherResourceBundle().getString(key);
String msg = ResourceBundleHolder.RB.getString(key);
return (args != null) ? MessageFormat.format(msg, args) : msg;
}
......@@ -380,25 +381,29 @@ public enum LauncherHelper {
File.pathSeparator));
}
static String getMainClassFromJar(String jarname) throws IOException {
JarFile jarFile = null;
static String getMainClassFromJar(PrintStream ostream, String jarname) {
try {
jarFile = new JarFile(jarname);
Manifest manifest = jarFile.getManifest();
if (manifest == null) {
throw new IOException("manifest not found in " + jarname);
}
Attributes mainAttrs = manifest.getMainAttributes();
if (mainAttrs == null) {
throw new IOException("no main mainifest attributes, in " +
jarname);
}
return mainAttrs.getValue(MAIN_CLASS).trim();
} finally {
if (jarFile != null) {
jarFile.close();
JarFile jarFile = null;
try {
jarFile = new JarFile(jarname);
Manifest manifest = jarFile.getManifest();
if (manifest == null) {
abort(ostream, null, "java.launcher.jar.error2", jarname);
}
Attributes mainAttrs = manifest.getMainAttributes();
if (mainAttrs == null) {
abort(ostream, null, "java.launcher.jar.error3", jarname);
}
return mainAttrs.getValue(MAIN_CLASS).trim();
} finally {
if (jarFile != null) {
jarFile.close();
}
}
} catch (IOException ioe) {
abort(ostream, ioe, "java.launcher.jar.error1", jarname);
}
return null;
}
......@@ -409,6 +414,20 @@ public enum LauncherHelper {
private static final int LM_CLASS = 1;
private static final int LM_JAR = 2;
static void abort(PrintStream ostream, Throwable t, String msgKey, Object... args) {
if (msgKey != null) {
ostream.println(getLocalizedMessage(msgKey, args));
}
if (sun.misc.VM.getSavedProperty(diagprop) != null) {
if (t != null) {
t.printStackTrace();
} else {
Thread.currentThread().dumpStack();
}
}
System.exit(1);
}
/**
* This method does the following:
* 1. gets the classname from a Jar's manifest, if necessary
......@@ -426,39 +445,31 @@ public enum LauncherHelper {
* @param isJar
* @param name
* @return
* @throws java.io.IOException
*/
public static Class<?> checkAndLoadMain(boolean printToStderr,
int mode,
String what) throws IOException
{
ClassLoader ld = ClassLoader.getSystemClassLoader();
String what) {
final PrintStream ostream = (printToStderr) ? System.err : System.out;
final ClassLoader ld = ClassLoader.getSystemClassLoader();
// get the class name
String cn = null;
switch (mode) {
case LM_CLASS:
cn = what;
break;
case LM_JAR:
cn = getMainClassFromJar(what);
break;
default:
throw new InternalError("" + mode + ": Unknown launch mode");
case LM_CLASS:
cn = what;
break;
case LM_JAR:
cn = getMainClassFromJar(ostream, what);
break;
default:
// should never happen
throw new InternalError("" + mode + ": Unknown launch mode");
}
cn = cn.replace('/', '.');
PrintStream ostream = (printToStderr) ? System.err : System.out;
Class<?> c = null;
try {
c = ld.loadClass(cn);
} catch (ClassNotFoundException cnfe) {
ostream.println(getLocalizedMessage("java.launcher.cls.error1",
cn));
NoClassDefFoundError ncdfe = new NoClassDefFoundError(cn);
ncdfe.initCause(cnfe);
throw ncdfe;
abort(ostream, cnfe, "java.launcher.cls.error1", cn);
}
signatureDiagnostic(ostream, c);
return c;
......@@ -470,9 +481,7 @@ public enum LauncherHelper {
try {
method = clazz.getMethod("main", String[].class);
} catch (NoSuchMethodException nsme) {
ostream.println(getLocalizedMessage("java.launcher.cls.error4",
classname));
throw new RuntimeException("Main method not found in " + classname);
abort(ostream, null, "java.launcher.cls.error4", classname);
}
/*
* getMethod (above) will choose the correct method, based
......@@ -481,17 +490,10 @@ public enum LauncherHelper {
*/
int mod = method.getModifiers();
if (!Modifier.isStatic(mod)) {
ostream.println(getLocalizedMessage("java.launcher.cls.error2",
"static", classname));
throw new RuntimeException("Main method is not static in class " +
classname);
abort(ostream, null, "java.launcher.cls.error2", "static", classname);
}
if (method.getReturnType() != java.lang.Void.TYPE) {
ostream.println(getLocalizedMessage("java.launcher.cls.error3",
classname));
throw new RuntimeException("Main method must return a value" +
" of type void in class " +
classname);
abort(ostream, null, "java.launcher.cls.error3", classname);
}
return;
}
......
......@@ -84,6 +84,7 @@ java.launcher.X.usage=\
\ append to end of bootstrap class path\n\
\ -Xbootclasspath/p:<directories and zip/jar files separated by {0}>\n\
\ prepend in front of bootstrap class path\n\
\ -Xdiag show additional diagnostic messages\n\
\ -Xnoclassgc disable class garbage collection\n\
\ -Xincgc enable incremental garbage collection\n\
\ -Xloggc:<file> log GC status to a file with time stamps\n\
......@@ -109,7 +110,7 @@ java.launcher.X.usage=\
The -X options are non-standard and subject to change without notice.\n
java.launcher.cls.error1=\
Error: Could not find main class {0}
Error: Could not find or load main class {0}
java.launcher.cls.error2=\
Error: Main method is not {0} in class {1}, please define the main method as:\n\
\ public static void main(String[] args)
......@@ -120,5 +121,7 @@ java.launcher.cls.error3=\
java.launcher.cls.error4=\
Error: Main method not found in class {0}, please define the main method as:\n\
\ public static void main(String[] args)
java.launcher.jar.error1=\
Error: An unexpected error occurred while trying to open file {0}
java.launcher.jar.error2=manifest not found in {0}
java.launcher.jar.error3=no main manifest attribute, in {0}
/*
* Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2011, 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
......@@ -66,6 +66,14 @@ public class JarIndex {
*/
public static final String INDEX_NAME = "META-INF/INDEX.LIST";
/**
* true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
* If true, the names of the files in META-INF, and its subdirectories, will
* be added to the index. Otherwise, just the directory names are added.
*/
private static final boolean metaInfFilenames =
"true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
/**
* Constructs a new, empty jar index.
*/
......@@ -186,6 +194,18 @@ public class JarIndex {
addToList(jarName, packageName, jarMap);
}
/**
* Same as add(String,String) except that it doesn't strip off from the
* last index of '/'. It just adds the filename.
*/
private void addExplicit(String fileName, String jarName) {
// add the mapping to indexMap
addToList(fileName, jarName, indexMap);
// add the mapping to jarMap
addToList(jarName, fileName, jarMap);
}
/**
* Go through all the jar files and construct the
* index table.
......@@ -204,15 +224,31 @@ public class JarIndex {
Enumeration entries = zrf.entries();
while(entries.hasMoreElements()) {
String fileName = ((ZipEntry)(entries.nextElement())).getName();
// Index the META-INF directory, but not the index or manifest.
if (!fileName.startsWith("META-INF/") ||
!(fileName.equals("META-INF/") ||
fileName.equals(INDEX_NAME) ||
fileName.equals(JarFile.MANIFEST_NAME))) {
ZipEntry entry = (ZipEntry) entries.nextElement();
String fileName = entry.getName();
// Skip the META-INF directory, the index, and manifest.
// Any files in META-INF/ will be indexed explicitly
if (fileName.equals("META-INF/") ||
fileName.equals(INDEX_NAME) ||
fileName.equals(JarFile.MANIFEST_NAME))
continue;
if (!metaInfFilenames) {
add(fileName, currentJar);
} else {
if (!fileName.startsWith("META-INF/")) {
add(fileName, currentJar);
} else if (!entry.isDirectory()) {
// Add files under META-INF explicitly so that certain
// services, like ServiceLoader, etc, can be located
// with greater accuracy. Directories can be skipped
// since each file will be added explicitly.
addExplicit(fileName, currentJar);
}
}
}
zrf.close();
}
}
......
......@@ -235,6 +235,9 @@ public class VM {
return savedProps.getProperty(key);
}
// TODO: the Property Management needs to be refactored and
// the appropriate prop keys need to be accessible to the
// calling classes to avoid duplication of keys.
private static final Properties savedProps = new Properties();
// Save a private copy of the system properties and remove
......@@ -283,6 +286,9 @@ public class VM {
// used by java.util.zip.ZipFile
props.remove("sun.zip.disableMemoryMapping");
// used by sun.launcher.LauncherHelper
props.remove("sun.java.launcher.diag");
}
// Initialize any miscellenous operating system settings that need to be
......
......@@ -106,6 +106,9 @@ public class KeepAliveCache
keepAliveTimer = new Thread(grp, cache, "Keep-Alive-Timer");
keepAliveTimer.setDaemon(true);
keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2);
// Set the context class loader to null in order to avoid
// keeping a strong reference to an application classloader.
keepAliveTimer.setContextClassLoader(null);
keepAliveTimer.start();
return null;
}
......
......@@ -185,6 +185,9 @@ class KeepAliveStream extends MeteredStream implements Hurryable {
cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner");
cleanerThread.setDaemon(true);
cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
// Set the context class loader to null in order to avoid
// keeping a strong reference to an application classloader.
cleanerThread.setContextClassLoader(null);
cleanerThread.start();
return null;
}
......
......@@ -173,7 +173,7 @@ class KrbAsRep extends KrbKdcRep {
}
Credentials getCreds() {
return Objects.nonNull(creds, "Creds not available yet.");
return Objects.requireNonNull(creds, "Creds not available yet.");
}
sun.security.krb5.internal.ccache.Credentials getCCreds() {
......
......@@ -55,12 +55,23 @@
#include "sun_nio_fs_UnixNativeDispatcher.h"
/**
* Size of password or group entry when not available via sysconf
*/
#define ENT_BUF_SIZE 1024
#define RESTARTABLE(_cmd, _result) do { \
do { \
_result = _cmd; \
} while((_result == -1) && (errno == EINTR)); \
} while(0)
#define RESTARTABLE_RETURN_PTR(_cmd, _result) do { \
do { \
_result = _cmd; \
} while((_result == NULL) && (errno == EINTR)); \
} while(0)
static jfieldID attrs_st_mode;
static jfieldID attrs_st_ino;
static jfieldID attrs_st_dev;
......@@ -858,37 +869,41 @@ Java_sun_nio_fs_UnixNativeDispatcher_getpwuid(JNIEnv* env, jclass this, jint uid
{
jbyteArray result = NULL;
int buflen;
char* pwbuf;
/* allocate buffer for password record */
buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
if (buflen == -1) {
throwUnixException(env, errno);
if (buflen == -1)
buflen = ENT_BUF_SIZE;
pwbuf = (char*)malloc(buflen);
if (pwbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
} else {
char* pwbuf = (char*)malloc(buflen);
if (pwbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
} else {
struct passwd pwent;
struct passwd* p;
int res = 0;
#ifdef __solaris__
p = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen);
#else
res = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p);
#endif
if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
struct passwd pwent;
struct passwd* p = NULL;
int res = 0;
errno = 0;
#ifdef __solaris__
RESTARTABLE_RETURN_PTR(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen), p);
#else
RESTARTABLE(getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p), res);
#endif
if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
/* not found or error */
if (errno != 0 && errno != ENOENT)
throwUnixException(env, errno);
} else {
jsize len = strlen(p->pw_name);
result = (*env)->NewByteArray(env, len);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
}
} else {
jsize len = strlen(p->pw_name);
result = (*env)->NewByteArray(env, len);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
}
free(pwbuf);
}
free(pwbuf);
}
return result;
}
......@@ -898,36 +913,55 @@ Java_sun_nio_fs_UnixNativeDispatcher_getgrgid(JNIEnv* env, jclass this, jint gid
{
jbyteArray result = NULL;
int buflen;
int retry;
/* initial size of buffer for group record */
buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
if (buflen == -1) {
throwUnixException(env, errno);
} else {
if (buflen == -1)
buflen = ENT_BUF_SIZE;
do {
struct group grent;
struct group* g = NULL;
int res = 0;
char* grbuf = (char*)malloc(buflen);
if (grbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
} else {
struct group grent;
struct group* g;
int res = 0;
return NULL;
}
#ifdef __solaris__
g = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen);
#else
res = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g);
#endif
if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
throwUnixException(env, errno);
} else {
jsize len = strlen(g->gr_name);
result = (*env)->NewByteArray(env, len);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
errno = 0;
#ifdef __solaris__
RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen), g);
#else
RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g), res);
#endif
retry = 0;
if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
/* not found or error */
if (errno != 0 && errno != ENOENT) {
if (errno == ERANGE) {
/* insufficient buffer size so need larger buffer */
buflen += ENT_BUF_SIZE;
retry = 1;
} else {
throwUnixException(env, errno);
}
}
free(grbuf);
} else {
jsize len = strlen(g->gr_name);
result = (*env)->NewByteArray(env, len);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
}
}
}
free(grbuf);
} while (retry);
return result;
}
......@@ -938,36 +972,37 @@ Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0(JNIEnv* env, jclass this,
jint uid = -1;
int buflen;
char* pwbuf;
struct passwd pwent;
struct passwd* p;
int res = 0;
const char* name = (const char*)jlong_to_ptr(nameAddress);
/* allocate buffer for password record */
buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
if (buflen == -1) {
throwUnixException(env, errno);
return -1;
}
if (buflen == -1)
buflen = ENT_BUF_SIZE;
pwbuf = (char*)malloc(buflen);
if (pwbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
return -1;
}
#ifdef __solaris__
p = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen);
#else
res = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p);
#endif
if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
/* not found or error */
} else {
uid = p->pw_uid;
struct passwd pwent;
struct passwd* p = NULL;
int res = 0;
const char* name = (const char*)jlong_to_ptr(nameAddress);
errno = 0;
#ifdef __solaris__
RESTARTABLE_RETURN_PTR(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen), p);
#else
RESTARTABLE(getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p), res);
#endif
if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
/* not found or error */
if (errno != 0 && errno != ENOENT)
throwUnixException(env, errno);
} else {
uid = p->pw_uid;
}
free(pwbuf);
}
free(pwbuf);
return uid;
}
......@@ -976,36 +1011,52 @@ Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0(JNIEnv* env, jclass this,
jlong nameAddress)
{
jint gid = -1;
int buflen;
char* grbuf;
struct group grent;
struct group* g;
int res = 0;
const char* name = (const char*)jlong_to_ptr(nameAddress);
int buflen, retry;
/* initial size of buffer for group record */
buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
if (buflen == -1) {
throwUnixException(env, errno);
return -1;
}
grbuf = (char*)malloc(buflen);
if (grbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
return -1;
}
if (buflen == -1)
buflen = ENT_BUF_SIZE;
#ifdef __solaris__
g = getgrnam_r(name, &grent, grbuf, (size_t)buflen);
#else
res = getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g);
#endif
do {
struct group grent;
struct group* g = NULL;
int res = 0;
char *grbuf;
const char* name = (const char*)jlong_to_ptr(nameAddress);
if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
/* not found or error */
} else {
gid = g->gr_gid;
}
free(grbuf);
grbuf = (char*)malloc(buflen);
if (grbuf == NULL) {
JNU_ThrowOutOfMemoryError(env, "native heap");
return -1;
}
errno = 0;
#ifdef __solaris__
RESTARTABLE_RETURN_PTR(getgrnam_r(name, &grent, grbuf, (size_t)buflen), g);
#else
RESTARTABLE(getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g), res);
#endif
retry = 0;
if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
/* not found or error */
if (errno != 0 && errno != ENOENT) {
if (errno == ERANGE) {
/* insufficient buffer size so need larger buffer */
buflen += ENT_BUF_SIZE;
retry = 1;
} else {
throwUnixException(env, errno);
}
}
} else {
gid = g->gr_gid;
}
free(grbuf);
} while (retry);
return gid;
}
......
/**
* @test
* @bug 6997561
* @summary A request for better error handling in JNDI
*/
import java.net.Socket;
import java.net.ServerSocket;
import java.io.*;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import java.util.Collections;
import java.util.Hashtable;
public class EmptyNameSearch {
public static void main(String[] args) throws Exception {
// Start the LDAP server
Server s = new Server();
s.start();
Thread.sleep(3000);
// Setup JNDI parameters
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:" + s.getPortNumber());
try {
// Create initial context
System.out.println("Client: connecting...");
DirContext ctx = new InitialDirContext(env);
System.out.println("Client: performing search...");
ctx.search(new LdapName(Collections.EMPTY_LIST), "cn=*", null);
ctx.close();
// Exit
throw new RuntimeException();
} catch (NamingException e) {
System.err.println("Passed: caught the expected Exception - " + e);
} catch (Exception e) {
System.err.println("Failed: caught an unexpected Exception - " + e);
throw e;
}
}
static class Server extends Thread {
private int serverPort = 0;
private byte[] bindResponse = {
0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A,
0x01, 0x00, 0x04, 0x00, 0x04, 0x00
};
private byte[] searchResponse = {
0x30, 0x0C, 0x02, 0x01, 0x02, 0x65, 0x07, 0x0A,
0x01, 0x02, 0x04, 0x00, 0x04, 0x00
};
Server() {
}
public int getPortNumber() {
return serverPort;
}
public void run() {
try {
ServerSocket serverSock = new ServerSocket(0);
serverPort = serverSock.getLocalPort();
System.out.println("Server: listening on port " + serverPort);
Socket socket = serverSock.accept();
System.out.println("Server: connection accepted");
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
// Read the LDAP BindRequest
System.out.println("Server: reading request...");
while (in.read() != -1) {
in.skip(in.available());
break;
}
// Write an LDAP BindResponse
System.out.println("Server: writing response...");
out.write(bindResponse);
out.flush();
// Read the LDAP SearchRequest
System.out.println("Server: reading request...");
while (in.read() != -1) {
in.skip(in.available());
break;
}
// Write an LDAP SearchResponse
System.out.println("Server: writing response...");
out.write(searchResponse);
out.flush();
in.close();
out.close();
socket.close();
serverSock.close();
} catch (IOException e) {
// ignore
}
}
}
}
......@@ -38,8 +38,7 @@ public class Duped {
public static void main(String args[]) throws Exception {
StringBuffer s = new StringBuffer();
int c;
while ((System.in.available() != 0)
&& ((c = System.in.read()) != -1))
while ((c = System.in.read()) != -1)
s.append((char)c);
System.out.println(s);
}
......
......@@ -164,7 +164,7 @@ public class BasicObjectsTest {
// Test 1-arg variant
try {
s = Objects.nonNull("pants");
s = Objects.requireNonNull("pants");
if (s != "pants") {
System.err.printf("1-arg non-null failed to return its arg");
errors++;
......@@ -175,7 +175,7 @@ public class BasicObjectsTest {
}
try {
s = Objects.nonNull(null);
s = Objects.requireNonNull(null);
System.err.printf("1-arg nonNull failed to throw NPE");
errors++;
} catch (NullPointerException e) {
......@@ -184,7 +184,7 @@ public class BasicObjectsTest {
// Test 2-arg variant
try {
s = Objects.nonNull("pants", "trousers");
s = Objects.requireNonNull("pants", "trousers");
if (s != "pants") {
System.err.printf("2-arg nonNull failed to return its arg");
errors++;
......@@ -195,7 +195,7 @@ public class BasicObjectsTest {
}
try {
s = Objects.nonNull(null, "pantaloons");
s = Objects.requireNonNull(null, "pantaloons");
System.err.printf("2-arg nonNull failed to throw NPE");
errors++;
} catch (NullPointerException e) {
......
......@@ -32,7 +32,7 @@
* 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476
* 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
* 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
* 6350801 6676425 6878475 6919132 6931676 6948903
* 6350801 6676425 6878475 6919132 6931676 6948903 7014645
*/
import java.util.regex.*;
......@@ -136,6 +136,7 @@ public class RegExTest {
namedGroupCaptureTest();
nonBmpClassComplementTest();
unicodePropertiesTest();
unicodeHexNotationTest();
if (failure)
throw new RuntimeException("Failure in the RE handling.");
else
......@@ -161,18 +162,19 @@ public class RegExTest {
private static void check(Matcher m, String result, boolean expected) {
m.find();
if (m.group().equals(result))
failCount += (expected) ? 0 : 1;
else
failCount += (expected) ? 1 : 0;
if (m.group().equals(result) != expected)
failCount++;
}
private static void check(Pattern p, String s, boolean expected) {
Matcher matcher = p.matcher(s);
if (matcher.find())
failCount += (expected) ? 0 : 1;
else
failCount += (expected) ? 1 : 0;
if (p.matcher(s).find() != expected)
failCount++;
}
private static void check(String p, String s, boolean expected) {
Matcher matcher = Pattern.compile(p).matcher(s);
if (matcher.find() != expected)
failCount++;
}
private static void check(String p, char c, boolean expected) {
......@@ -3614,4 +3616,45 @@ public class RegExTest {
}
report("unicodeProperties");
}
private static void unicodeHexNotationTest() throws Exception {
// negative
checkExpectedFail("\\x{-23}");
checkExpectedFail("\\x{110000}");
checkExpectedFail("\\x{}");
checkExpectedFail("\\x{AB[ef]");
// codepoint
check("^\\x{1033c}$", "\uD800\uDF3C", true);
check("^\\xF0\\x90\\x8C\\xBC$", "\uD800\uDF3C", false);
check("^\\x{D800}\\x{DF3c}+$", "\uD800\uDF3C", false);
check("^\\xF0\\x90\\x8C\\xBC$", "\uD800\uDF3C", false);
// in class
check("^[\\x{D800}\\x{DF3c}]+$", "\uD800\uDF3C", false);
check("^[\\xF0\\x90\\x8C\\xBC]+$", "\uD800\uDF3C", false);
check("^[\\x{D800}\\x{DF3C}]+$", "\uD800\uDF3C", false);
check("^[\\x{DF3C}\\x{D800}]+$", "\uD800\uDF3C", false);
check("^[\\x{D800}\\x{DF3C}]+$", "\uDF3C\uD800", true);
check("^[\\x{DF3C}\\x{D800}]+$", "\uDF3C\uD800", true);
for (int cp = 0; cp <= 0x10FFFF; cp++) {
String s = "A" + new String(Character.toChars(cp)) + "B";
String hexUTF16 = (cp <= 0xFFFF)? String.format("\\u%04x", cp)
: String.format("\\u%04x\\u%04x",
(int) Character.toChars(cp)[0],
(int) Character.toChars(cp)[1]);
String hexCodePoint = "\\x{" + Integer.toHexString(cp) + "}";
if (!Pattern.matches("A" + hexUTF16 + "B", s))
failCount++;
if (!Pattern.matches("A[" + hexUTF16 + "]B", s))
failCount++;
if (!Pattern.matches("A" + hexCodePoint + "B", s))
failCount++;
if (!Pattern.matches("A[" + hexCodePoint + "]B", s))
failCount++;
}
report("unicodeHexNotation");
}
}
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6887710
* @summary Verify the impact of sun.misc.JarIndex.metaInfFilenames on Service loaders
* @run main/othervm Basic
*/
import java.io.IOException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Iterator;
import java.util.ServiceLoader;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
/**
* Verifies the impact of sun.misc.JarIndex.metaInfFilenames on service loaders
* (sun.misc.Service & java.util.ServiceLoader), as well as finding resources
* through Class.getResouce.
*
* 1) Compile the test sources:
* jarA:
* META-INF/services/my.happy.land
* com/message/spi/MessageService.java
* a/A.java
* jarB:
* META-INF/JAVA2.DS
* META-INF/services/no.name.service
* b/B.java
* jarC:
* META-INF/fonts.mf
* META-INF/fonts/Company-corporate.ttf
* META-INF/fonts/kidpr.ttf
* META-INF/services/com.message.spi.MessageService
* my/impl/StandardMessageService.java
*
* 2) Build three jar files a.jar, b.jar, c.jar
*
* 3) Create an index in a.jar (jar -i a.jar b.jar c.jar)
* with sun.misc.JarIndex.metaInfFilenames=true
*
* 4) Start a HTTP server serving out the three jars.
*
* The test then tries to locate services/resources within the jars using
* URLClassLoader. Each request to the HTTP server is recorded to ensure
* only the correct amount of requests are being made.
*
* Note: Needs jdk/lib/tools.jar in the classpath to compile and run.
*/
public class Basic {
static final String slash = File.separator;
static final String[] testSources = {
"jarA" + slash + "a" + slash + "A.java",
"jarA" + slash + "com" + slash + "message" + slash + "spi" + slash + "MessageService.java",
"jarB" + slash + "b" + slash + "B.java",
"jarC" + slash + "my" + slash + "impl" + slash + "StandardMessageService.java"};
static final String testSrc = System.getProperty("test.src");
static final String testSrcDir = testSrc != null ? testSrc : ".";
static final String testClasses = System.getProperty("test.classes");
static final String testClassesDir = testClasses != null ? testClasses : ".";
static JarHttpServer httpServer;
public static void main(String[] args) throws Exception {
// Set global url cache to false so that we can track every jar request.
(new URL("http://localhost/")).openConnection().setDefaultUseCaches(false);
buildTest();
try {
httpServer = new JarHttpServer(testClassesDir);
httpServer.start();
doTest(httpServer.getAddress());
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (httpServer != null) { httpServer.stop(2); }
}
}
static void buildTest() {
/* compile the source that will be used to generate the jars */
for (int i=0; i<testSources.length; i++)
testSources[i] = testSrcDir + slash + testSources[i];
compile("-d" , testClassesDir,
"-sourcepath", testSrcDir,
testSources[0], testSources[1], testSources[2], testSources[3]);
/* build the 3 jar files */
jar("-cf", testClassesDir + slash + "a.jar",
"-C", testClassesDir, "a",
"-C", testClassesDir, "com",
"-C", testSrcDir + slash + "jarA", "META-INF");
jar("-cf", testClassesDir + slash + "b.jar",
"-C", testClassesDir, "b",
"-C", testSrcDir + slash + "jarB", "META-INF");
jar("-cf", testClassesDir + slash + "c.jar",
"-C", testClassesDir, "my",
"-C", testSrcDir + slash + "jarC", "META-INF");
/* Create an index in a.jar for b.jar and c.jar */
createIndex(testClassesDir);
}
/* run jar <args> */
static void jar(String... args) {
debug("Running: jar " + Arrays.toString(args));
sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
if (!jar.run(args)) {
throw new RuntimeException("jar failed: args=" + Arrays.toString(args));
}
}
/* run javac <args> */
static void compile(String... args) {
debug("Running: javac " + Arrays.toString(args));
com.sun.tools.javac.main.Main compiler = new com.sun.tools.javac.main.Main("javac");
if (compiler.compile(args) != 0) {
throw new RuntimeException("javac failed: args=" + Arrays.toString(args));
}
}
static String jar;
static {
String javaHome = System.getProperty("java.home");
if (javaHome.endsWith("jre")) {
int index = javaHome.lastIndexOf(slash);
if (index != -1)
javaHome = javaHome.substring(0, index);
}
jar = javaHome + slash+ "bin" + slash + "jar";
}
/* create the index */
static void createIndex(String workingDir) {
// ProcessBuilder is used so that the current directory can be set
// to the directory that directly contains the jars.
debug("Running jar to create the index");
ProcessBuilder pb = new ProcessBuilder(
jar, "-J-Dsun.misc.JarIndex.metaInfFilenames=true", "-i", "a.jar", "b.jar", "c.jar");
pb.directory(new File(workingDir));
//pd.inheritIO();
try {
Process p = pb.start();
if(p.waitFor() != 0)
throw new RuntimeException("jar indexing failed");
if(debug && p != null) {
String line = null;
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line = reader.readLine()) != null)
debug(line);
reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while((line = reader.readLine()) != null)
debug(line);
}
} catch(InterruptedException ie) { throw new RuntimeException(ie);
} catch(IOException e) { throw new RuntimeException(e); }
}
static final boolean debug = true;
static void debug(Object message) { if (debug) System.out.println(message); }
/* service define in c.jar */
static final String messageService = "com.message.spi.MessageService";
/* a service that is not defined in any of the jars */
static final String unknownService = "java.lang.Object";
static void doTest(InetSocketAddress serverAddress) throws IOException {
URL baseURL = new URL("http://localhost:" + serverAddress.getPort() + "/");
int failed = 0;
// Tests using sun.misc.Service
if (!sunMiscServiceTest(baseURL, messageService, true, false, true)) {
System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
failed++;
}
if (!sunMiscServiceTest(baseURL, unknownService, false, false, false)) {
System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
failed++;
}
// Tests using java.util.SerivceLoader
if (!javaUtilServiceLoaderTest(baseURL, messageService, true, false, true)) {
System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
failed++;
}
if (!javaUtilServiceLoaderTest(baseURL, unknownService, false, false, false)) {
System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
failed++;
}
// Tests using java.lang.Class (similar to the FontManager in javafx)
if (!klassLoader(baseURL, "/META-INF/fonts.mf", true, false, true)) {
System.out.println("Test: klassLoader looking for /META-INF/fonts.mf failed");
failed++;
}
if (!klassLoader(baseURL, "/META-INF/unknown.mf", false, false, false)) {
System.out.println("Test: klassLoader looking for /META-INF/unknown.mf failed");
failed++;
}
if (failed > 0)
throw new RuntimeException("Failed: " + failed + " tests");
}
static boolean sunMiscServiceTest(URL baseURL,
String serviceClass,
boolean expectToFind,
boolean expectbDotJar,
boolean expectcDotJar) throws IOException {
debug("----------------------------------");
debug("Running test with sun.misc.Service looking for " + serviceClass);
URLClassLoader loader = getLoader(baseURL);
httpServer.reset();
Class messageServiceClass = null;
try {
messageServiceClass = loader.loadClass(serviceClass);
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe);
throw new RuntimeException("Error in test: " + cnfe);
}
Iterator<Class<?>> iterator = sun.misc.Service.providers(messageServiceClass, loader);
if (expectToFind && !iterator.hasNext()) {
debug(messageServiceClass + " NOT found.");
return false;
}
while (iterator.hasNext()) {
debug("found " + iterator.next() + " " + messageService);
}
debug("HttpServer: " + httpServer);
if (!expectbDotJar && httpServer.bDotJar > 0) {
debug("Unexpeced request sent to the httpserver for b.jar");
return false;
}
if (!expectcDotJar && httpServer.cDotJar > 0) {
debug("Unexpeced request sent to the httpserver for c.jar");
return false;
}
return true;
}
static boolean javaUtilServiceLoaderTest(URL baseURL,
String serviceClass,
boolean expectToFind,
boolean expectbDotJar,
boolean expectcDotJar) throws IOException {
debug("----------------------------------");
debug("Running test with java.util.ServiceLoader looking for " + serviceClass);
URLClassLoader loader = getLoader(baseURL);
httpServer.reset();
Class messageServiceClass = null;
try {
messageServiceClass = loader.loadClass(serviceClass);
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe);
throw new RuntimeException("Error in test: " + cnfe);
}
Iterator<Class<?>> iterator = (ServiceLoader.load(messageServiceClass, loader)).iterator();
if (expectToFind && !iterator.hasNext()) {
debug(messageServiceClass + " NOT found.");
return false;
}
while (iterator.hasNext()) {
debug("found " + iterator.next() + " " + messageService);
}
debug("HttpServer: " + httpServer);
if (!expectbDotJar && httpServer.bDotJar > 0) {
debug("Unexpeced request sent to the httpserver for b.jar");
return false;
}
if (!expectcDotJar && httpServer.cDotJar > 0) {
debug("Unexpeced request sent to the httpserver for c.jar");
return false;
}
return true;
}
/* Tries to find a resource in a similar way to the font manager in javafx
* com.sun.javafx.scene.text.FontManager */
static boolean klassLoader(URL baseURL,
String resource,
boolean expectToFind,
boolean expectbDotJar,
boolean expectcDotJar) throws IOException {
debug("----------------------------------");
debug("Running test looking for " + resource);
URLClassLoader loader = getLoader(baseURL);
httpServer.reset();
Class ADotAKlass = null;
try {
ADotAKlass = loader.loadClass("a.A");
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe);
throw new RuntimeException("Error in test: " + cnfe);
}
URL u = ADotAKlass.getResource(resource);
if (expectToFind && u == null) {
System.out.println("Expected to find " + resource + " but didn't");
return false;
}
debug("HttpServer: " + httpServer);
if (!expectbDotJar && httpServer.bDotJar > 0) {
debug("Unexpeced request sent to the httpserver for b.jar");
return false;
}
if (!expectcDotJar && httpServer.cDotJar > 0) {
debug("Unexpeced request sent to the httpserver for c.jar");
return false;
}
return true;
}
static URLClassLoader getLoader(URL baseURL) throws IOException {
ClassLoader loader = Basic.class.getClassLoader();
while (loader.getParent() != null)
loader = loader.getParent();
return new URLClassLoader( new URL[]{
new URL(baseURL, "a.jar"),
new URL(baseURL, "b.jar"),
new URL(baseURL, "c.jar")}, loader );
}
/**
* HTTP Server to server the jar files.
*/
static class JarHttpServer implements HttpHandler {
final String docsDir;
final HttpServer httpServer;
int aDotJar, bDotJar, cDotJar;
JarHttpServer(String docsDir) throws IOException {
this.docsDir = docsDir;
httpServer = HttpServer.create(new InetSocketAddress(0), 0);
httpServer.createContext("/", this);
}
void start() throws IOException {
httpServer.start();
}
void stop(int delay) {
httpServer.stop(delay);
}
InetSocketAddress getAddress() {
return httpServer.getAddress();
}
void reset() {
aDotJar = bDotJar = cDotJar = 0;
}
@Override
public String toString() {
return "aDotJar=" + aDotJar + ", bDotJar=" + bDotJar + ", cDotJar=" + cDotJar;
}
public void handle(HttpExchange t) throws IOException {
InputStream is = t.getRequestBody();
Headers map = t.getRequestHeaders();
Headers rmap = t.getResponseHeaders();
URI uri = t.getRequestURI();
debug("Server: received request for " + uri);
String path = uri.getPath();
if (path.endsWith("a.jar"))
aDotJar++;
else if (path.endsWith("b.jar"))
bDotJar++;
else if (path.endsWith("c.jar"))
cDotJar++;
else
System.out.println("Unexpected resource request" + path);
while (is.read() != -1);
is.close();
File file = new File(docsDir, path);
if (!file.exists())
throw new RuntimeException("Error: request for " + file);
long clen = file.length();
t.sendResponseHeaders (200, clen);
OutputStream os = t.getResponseBody();
FileInputStream fis = new FileInputStream(file);
try {
byte[] buf = new byte [16 * 1024];
int len;
while ((len=fis.read(buf)) != -1) {
os.write (buf, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
fis.close();
os.close();
}
}
}
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
# The contents of this file do not matter. It exists
# simply to have a service defined in META-INF/services.
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package a;
public class A {
public static void hello() throws Exception {
System.out.println("Hello from a.A");
}
}
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.message.spi;
public interface MessageService {
String message();
}
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
# The contents of this file do not matter. It exists
# simply to have a file under META-INF.
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
# The contents of this file do not matter. It exists
# simply to have a service defined in META-INF/services.
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package b;
public class B {
public static void hello() {
System.out.println("Hello from b.B");
}
}
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
corporate=/fonts/Company-corporate.ttf
crazy-looking=/fonts/kidpr.ttf
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
This is not a real font.
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
This is not a real font.
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
my.impl.StandardMessageService
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package my.impl;
public class StandardMessageService implements com.message.spi.MessageService {
@Override
public String message() {
return "This is a message from the standard message service";
}
}
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* Copyright (c) 2010, 2011, 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
......
......@@ -24,7 +24,7 @@
/**
* @test
* @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
* 6894719
* 6894719 6968053
* @summary Argument parsing validation.
* @compile -XDignore.symbol.file Arrrghs.java TestHelper.java
* @run main Arrrghs
......@@ -250,13 +250,11 @@ public class Arrrghs {
TestHelper.createJar("MIA", new File("some.jar"), new File("Foo"),
(String[])null);
tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar");
tr.contains("Error: Could not find main class MIA");
tr.contains("java.lang.NoClassDefFoundError: MIA");
tr.contains("Error: Could not find or load main class MIA");
System.out.println(tr);
// use classpath to check
tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "MIA");
tr.contains("Error: Could not find main class MIA");
tr.contains("java.lang.NoClassDefFoundError: MIA");
tr.contains("Error: Could not find or load main class MIA");
System.out.println(tr);
// incorrect method access
......@@ -305,12 +303,12 @@ public class Arrrghs {
// amongst a potpourri of kindred main methods, is the right one chosen ?
TestHelper.createJar(new File("some.jar"), new File("Foo"),
"void main(Object[] args){}",
"int main(Float[] args){return 1;}",
"private void main() {}",
"private static void main(int x) {}",
"public int main(int argc, String[] argv) {return 1;}",
"public static void main(String[] args) {System.out.println(\"THE_CHOSEN_ONE\");}");
"void main(Object[] args){}",
"int main(Float[] args){return 1;}",
"private void main() {}",
"private static void main(int x) {}",
"public int main(int argc, String[] argv) {return 1;}",
"public static void main(String[] args) {System.out.println(\"THE_CHOSEN_ONE\");}");
tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar");
tr.contains("THE_CHOSEN_ONE");
System.out.println(tr);
......@@ -326,6 +324,30 @@ public class Arrrghs {
tr.checkPositive();
System.out.println(tr);
}
// tests 6968053, ie. we turn on the -Xdiag (for now) flag and check if
// the suppressed stack traces are exposed.
static void runDiagOptionTests() throws FileNotFoundException {
TestHelper.TestResult tr = null;
// a missing class
TestHelper.createJar("MIA", new File("some.jar"), new File("Foo"),
(String[])null);
tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "-jar", "some.jar");
tr.contains("Error: Could not find or load main class MIA");
tr.contains("java.lang.ClassNotFoundException: MIA");
System.out.println(tr);
// use classpath to check
tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "-cp", "some.jar", "MIA");
tr.contains("Error: Could not find or load main class MIA");
tr.contains("java.lang.ClassNotFoundException: MIA");
System.out.println(tr);
// a missing class on the classpath
tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "NonExistentClass");
tr.contains("Error: Could not find or load main class NonExistentClass");
tr.contains("java.lang.ClassNotFoundException: NonExistentClass");
System.out.println(tr);
}
static void test6894719() {
// test both arguments to ensure they exist
......@@ -352,6 +374,7 @@ public class Arrrghs {
runBasicErrorMessageTests();
runMainMethodTests();
test6894719();
runDiagOptionTests();
if (TestHelper.testExitValue > 0) {
System.out.println("Total of " + TestHelper.testExitValue + " failed");
System.exit(1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册