mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-14 08:58:46 +00:00
8022921: Remove experimental Profile attribute
Reviewed-by: mchung, chegar
This commit is contained in:
parent
e87a2bddaf
commit
9aceb41d6d
@ -57,12 +57,6 @@ import sun.security.util.SecurityConstants;
|
||||
* <p>
|
||||
* The classes that are loaded are by default granted permission only to
|
||||
* access the URLs specified when the URLClassLoader was created.
|
||||
* <p>
|
||||
* Where a JAR file contains the {@link Name#PROFILE Profile} attribute
|
||||
* then its value is the name of the Java SE profile that the library
|
||||
* minimally requires. If this runtime does not support the profile then
|
||||
* it causes {@link java.util.jar.UnsupportedProfileException} to be
|
||||
* thrown at some unspecified time.
|
||||
*
|
||||
* @author David Connelly
|
||||
* @since 1.2
|
||||
|
||||
@ -564,15 +564,6 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
||||
*/
|
||||
public static final Name MAIN_CLASS = new Name("Main-Class");
|
||||
|
||||
/**
|
||||
* {@code Name} object for {@code Profile} manifest attribute used by
|
||||
* applications or libraries packaged as JAR files to indicate the
|
||||
* minimum profile required to execute the application.
|
||||
* @since 1.8
|
||||
* @see UnsupportedProfileException
|
||||
*/
|
||||
public static final Name PROFILE = new Name("Profile");
|
||||
|
||||
/**
|
||||
* <code>Name</code> object for <code>Sealed</code> manifest attribute
|
||||
* used for sealing.
|
||||
|
||||
@ -69,8 +69,6 @@ class JarFile extends ZipFile {
|
||||
|
||||
// indicates if Class-Path attribute present (only valid if hasCheckedSpecialAttributes true)
|
||||
private boolean hasClassPathAttribute;
|
||||
// indicates if Profile attribute present (only valid if hasCheckedSpecialAttributes true)
|
||||
private boolean hasProfileAttribute;
|
||||
// true if manifest checked for special attributes
|
||||
private volatile boolean hasCheckedSpecialAttributes;
|
||||
|
||||
@ -459,15 +457,10 @@ class JarFile extends ZipFile {
|
||||
|
||||
// Statics for hand-coded Boyer-Moore search
|
||||
private static final char[] CLASSPATH_CHARS = {'c','l','a','s','s','-','p','a','t','h'};
|
||||
private static final char[] PROFILE_CHARS = { 'p', 'r', 'o', 'f', 'i', 'l', 'e' };
|
||||
// The bad character shift for "class-path"
|
||||
private static final int[] CLASSPATH_LASTOCC;
|
||||
// The good suffix shift for "class-path"
|
||||
private static final int[] CLASSPATH_OPTOSFT;
|
||||
// The bad character shift for "profile"
|
||||
private static final int[] PROFILE_LASTOCC;
|
||||
// The good suffix shift for "profile"
|
||||
private static final int[] PROFILE_OPTOSFT;
|
||||
|
||||
static {
|
||||
CLASSPATH_LASTOCC = new int[128];
|
||||
@ -483,19 +476,6 @@ class JarFile extends ZipFile {
|
||||
for (int i=0; i<9; i++)
|
||||
CLASSPATH_OPTOSFT[i] = 10;
|
||||
CLASSPATH_OPTOSFT[9]=1;
|
||||
|
||||
PROFILE_LASTOCC = new int[128];
|
||||
PROFILE_OPTOSFT = new int[7];
|
||||
PROFILE_LASTOCC[(int)'p'] = 1;
|
||||
PROFILE_LASTOCC[(int)'r'] = 2;
|
||||
PROFILE_LASTOCC[(int)'o'] = 3;
|
||||
PROFILE_LASTOCC[(int)'f'] = 4;
|
||||
PROFILE_LASTOCC[(int)'i'] = 5;
|
||||
PROFILE_LASTOCC[(int)'l'] = 6;
|
||||
PROFILE_LASTOCC[(int)'e'] = 7;
|
||||
for (int i=0; i<6; i++)
|
||||
PROFILE_OPTOSFT[i] = 7;
|
||||
PROFILE_OPTOSFT[6] = 1;
|
||||
}
|
||||
|
||||
private JarEntry getManEntry() {
|
||||
@ -529,15 +509,6 @@ class JarFile extends ZipFile {
|
||||
return hasClassPathAttribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} iff this JAR file has a manifest with the
|
||||
* Profile attribute
|
||||
*/
|
||||
boolean hasProfileAttribute() throws IOException {
|
||||
checkForSpecialAttributes();
|
||||
return hasProfileAttribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the pattern {@code src} is found in {@code b}.
|
||||
* The {@code lastOcc} and {@code optoSft} arrays are the precomputed
|
||||
@ -564,7 +535,7 @@ class JarFile extends ZipFile {
|
||||
|
||||
/**
|
||||
* On first invocation, check if the JAR file has the Class-Path
|
||||
* and/or Profile attributes. A no-op on subsequent calls.
|
||||
* attribute. A no-op on subsequent calls.
|
||||
*/
|
||||
private void checkForSpecialAttributes() throws IOException {
|
||||
if (hasCheckedSpecialAttributes) return;
|
||||
@ -574,8 +545,6 @@ class JarFile extends ZipFile {
|
||||
byte[] b = getBytes(manEntry);
|
||||
if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT))
|
||||
hasClassPathAttribute = true;
|
||||
if (match(PROFILE_CHARS, b, PROFILE_LASTOCC, PROFILE_OPTOSFT))
|
||||
hasProfileAttribute = true;
|
||||
}
|
||||
}
|
||||
hasCheckedSpecialAttributes = true;
|
||||
|
||||
@ -37,10 +37,6 @@ class JavaUtilJarAccessImpl implements JavaUtilJarAccess {
|
||||
return jar.hasClassPathAttribute();
|
||||
}
|
||||
|
||||
public boolean jarFileHasProfileAttribute(JarFile jar) throws IOException {
|
||||
return jar.hasProfileAttribute();
|
||||
}
|
||||
|
||||
public CodeSource[] getCodeSources(JarFile jar, URL url) {
|
||||
return jar.getCodeSources(url);
|
||||
}
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 java.util.jar;
|
||||
|
||||
/**
|
||||
* Thrown to indicate an attempt to access a JAR file with a {@link
|
||||
* Attributes.Name#PROFILE Profile} attribute that names a profile that
|
||||
* is not supported by this runtime.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public class UnsupportedProfileException extends RuntimeException {
|
||||
private static final long serialVersionUID = -1834773870678792406L;
|
||||
|
||||
/**
|
||||
* Constructs an {@code UnsupportedProfileException} with no detail
|
||||
* message.
|
||||
*/
|
||||
public UnsupportedProfileException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code UnsupportedProfileException} with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param message the detail message
|
||||
*/
|
||||
public UnsupportedProfileException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@ -65,13 +65,10 @@ import java.util.TreeSet;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import sun.misc.Version;
|
||||
import sun.misc.URLClassPath;
|
||||
|
||||
public enum LauncherHelper {
|
||||
INSTANCE;
|
||||
private static final String MAIN_CLASS = "Main-Class";
|
||||
private static final String PROFILE = "Profile";
|
||||
|
||||
private static StringBuilder outBuf = new StringBuilder();
|
||||
|
||||
@ -414,27 +411,6 @@ public enum LauncherHelper {
|
||||
abort(null, "java.launcher.jar.error3", jarname);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is not a full JRE then the Profile attribute must be
|
||||
* present with the Main-Class attribute so as to indicate the minimum
|
||||
* profile required. Note that we need to suppress checking of the Profile
|
||||
* attribute after we detect an error. This is because the abort may
|
||||
* need to lookup resources and this may involve opening additional JAR
|
||||
* files that would result in errors that suppress the main error.
|
||||
*/
|
||||
String profile = mainAttrs.getValue(PROFILE);
|
||||
if (profile == null) {
|
||||
if (!Version.isFullJre()) {
|
||||
URLClassPath.suppressProfileCheckForLauncher();
|
||||
abort(null, "java.launcher.jar.error4", jarname);
|
||||
}
|
||||
} else {
|
||||
if (!Version.supportsProfile(profile)) {
|
||||
URLClassPath.suppressProfileCheckForLauncher();
|
||||
abort(null, "java.launcher.jar.error5", profile, jarname);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Hand off to FXHelper if it detects a JavaFX application
|
||||
* This must be done after ensuring a Main-Class entry
|
||||
|
||||
@ -139,8 +139,6 @@ 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}
|
||||
java.launcher.jar.error4=no Profile manifest attribute in {0}
|
||||
java.launcher.jar.error5=Profile {0} required by {1} not supported by this runtime
|
||||
java.launcher.init.error=initialization error
|
||||
java.launcher.javafx.error1=\
|
||||
Error: The JavaFX launchApplication method has the wrong signature, it\n\
|
||||
|
||||
@ -35,7 +35,6 @@ import java.util.jar.JarFile;
|
||||
|
||||
public interface JavaUtilJarAccess {
|
||||
public boolean jarFileHasClassPathAttribute(JarFile jar) throws IOException;
|
||||
public boolean jarFileHasProfileAttribute(JarFile jar) throws IOException;
|
||||
public CodeSource[] getCodeSources(JarFile jar, URL url);
|
||||
public CodeSource getCodeSource(JarFile jar, URL url, String name);
|
||||
public Enumeration<String> entryNames(JarFile jar, CodeSource[] cs);
|
||||
|
||||
@ -35,7 +35,6 @@ import java.util.jar.JarEntry;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Attributes.Name;
|
||||
import java.util.jar.UnsupportedProfileException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
@ -66,12 +65,6 @@ public class URLClassPath {
|
||||
private static final boolean DEBUG;
|
||||
private static final boolean DISABLE_JAR_CHECKING;
|
||||
|
||||
/**
|
||||
* Used by launcher to indicate that checking of the JAR file "Profile"
|
||||
* attribute has been suppressed.
|
||||
*/
|
||||
private static boolean profileCheckSuppressedByLauncher;
|
||||
|
||||
static {
|
||||
JAVA_VERSION = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("java.version"));
|
||||
@ -593,15 +586,6 @@ public class URLClassPath {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the launcher to suppress further checking of the JAR file Profile
|
||||
* attribute (necessary when the launcher is aborting as the abort involves
|
||||
* a resource lookup that may involve opening additional JAR files)
|
||||
*/
|
||||
public static void suppressProfileCheckForLauncher() {
|
||||
profileCheckSuppressedByLauncher = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inner class used to represent a Loader of resources from a JAR URL.
|
||||
*/
|
||||
@ -828,25 +812,6 @@ public class URLClassPath {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the Profile attribute is present then this method checks that the runtime
|
||||
* supports that profile.
|
||||
*/
|
||||
void checkProfileAttribute() throws IOException {
|
||||
Manifest man = jar.getManifest();
|
||||
if (man != null) {
|
||||
Attributes attr = man.getMainAttributes();
|
||||
if (attr != null) {
|
||||
String value = attr.getValue(Name.PROFILE);
|
||||
if (value != null && !Version.supportsProfile(value)) {
|
||||
String prefix = Version.profileName().length() > 0 ?
|
||||
"This runtime implements " + Version.profileName() + ", " : "";
|
||||
throw new UnsupportedProfileException(prefix + csu + " requires " + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the URL for a resource with the specified name
|
||||
*/
|
||||
@ -1017,12 +982,6 @@ public class URLClassPath {
|
||||
ensureOpen();
|
||||
parseExtensionsDependencies();
|
||||
|
||||
// check Profile attribute if present
|
||||
if (!profileCheckSuppressedByLauncher &&
|
||||
SharedSecrets.javaUtilJarAccess().jarFileHasProfileAttribute(jar)) {
|
||||
checkProfileAttribute();
|
||||
}
|
||||
|
||||
if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary
|
||||
Manifest man = jar.getManifest();
|
||||
if (man != null) {
|
||||
|
||||
@ -339,68 +339,6 @@ public class Version {
|
||||
// Return false if not available which implies an old VM (Tiger or before).
|
||||
private static native boolean getJvmVersionInfo();
|
||||
private static native void getJdkVersionInfo();
|
||||
|
||||
// Possible runtime profiles, ordered from small to large
|
||||
private final static String[] PROFILES = { "compact1", "compact2", "compact3" };
|
||||
|
||||
/**
|
||||
* Returns the name of the profile that this runtime implements. The empty
|
||||
* string is returned for the full Java Runtime.
|
||||
*/
|
||||
public static String profileName() {
|
||||
return java_profile_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this runtime implements the full Java Runtime.
|
||||
*/
|
||||
public static boolean isFullJre() {
|
||||
return java_profile_name.length() == 0;
|
||||
}
|
||||
|
||||
// cached index of this profile's name in PROFILES (1-based)
|
||||
private static int thisRuntimeIndex;
|
||||
|
||||
/**
|
||||
* Indicates if this runtime supports the given profile. Profile names are
|
||||
* case sensitive.
|
||||
*
|
||||
* @return {@code true} if the given profile is supported
|
||||
*/
|
||||
public static boolean supportsProfile(String requiredProfile) {
|
||||
int x = thisRuntimeIndex - 1;
|
||||
if (x < 0) {
|
||||
String profile = profileName();
|
||||
if (profile.length() > 0) {
|
||||
x = 0;
|
||||
while (x < PROFILES.length) {
|
||||
if (PROFILES[x].equals(profile))
|
||||
break;
|
||||
x++;
|
||||
}
|
||||
if (x >= PROFILES.length)
|
||||
throw new InternalError(profile + " not known to sun.misc.Version");
|
||||
|
||||
// okay if another thread has already set it
|
||||
thisRuntimeIndex = x + 1;
|
||||
}
|
||||
// else we are a full JRE
|
||||
}
|
||||
|
||||
int y = 0;
|
||||
while (y < PROFILES.length) {
|
||||
if (PROFILES[y].equals(requiredProfile))
|
||||
break;
|
||||
y++;
|
||||
}
|
||||
if (y >= PROFILES.length) {
|
||||
// profile not found so caller has requested something that is not defined
|
||||
return false;
|
||||
}
|
||||
|
||||
return x < 0 || x >= y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Help Emacs a little because this file doesn't end in .java.
|
||||
|
||||
@ -47,7 +47,7 @@ public
|
||||
class Main {
|
||||
String program;
|
||||
PrintStream out, err;
|
||||
String fname, mname, ename, pname;
|
||||
String fname, mname, ename;
|
||||
String zname = "";
|
||||
String[] files;
|
||||
String rootjar = null;
|
||||
@ -78,9 +78,6 @@ class Main {
|
||||
static final String MANIFEST_DIR = "META-INF/";
|
||||
static final String VERSION = "1.0";
|
||||
|
||||
// valid values for Profile attribute
|
||||
private static final String[] PROFILES = { "compact1", "compact2", "compact3" };
|
||||
|
||||
private static ResourceBundle rsrc;
|
||||
|
||||
/**
|
||||
@ -187,14 +184,6 @@ class Main {
|
||||
if (ename != null) {
|
||||
addMainClass(manifest, ename);
|
||||
}
|
||||
if (pname != null) {
|
||||
if (!addProfileName(manifest, pname)) {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
OutputStream out;
|
||||
if (fname != null) {
|
||||
@ -372,9 +361,6 @@ class Main {
|
||||
case 'e':
|
||||
ename = args[count++];
|
||||
break;
|
||||
case 'p':
|
||||
pname = args[count++];
|
||||
break;
|
||||
default:
|
||||
error(formatMsg("error.illegal.option",
|
||||
String.valueOf(flags.charAt(i))));
|
||||
@ -424,7 +410,7 @@ class Main {
|
||||
usageError();
|
||||
return false;
|
||||
} else if (uflag) {
|
||||
if ((mname != null) || (ename != null) || (pname != null)) {
|
||||
if ((mname != null) || (ename != null)) {
|
||||
/* just want to update the manifest */
|
||||
return true;
|
||||
} else {
|
||||
@ -558,7 +544,7 @@ class Main {
|
||||
|| (Mflag && isManifestEntry)) {
|
||||
continue;
|
||||
} else if (isManifestEntry && ((newManifest != null) ||
|
||||
(ename != null) || (pname != null))) {
|
||||
(ename != null))) {
|
||||
foundManifest = true;
|
||||
if (newManifest != null) {
|
||||
// Don't read from the newManifest InputStream, as we
|
||||
@ -616,7 +602,7 @@ class Main {
|
||||
updateOk = false;
|
||||
}
|
||||
}
|
||||
} else if (ename != null || pname != null) {
|
||||
} else if (ename != null) {
|
||||
if (!updateManifest(new Manifest(), zos)) {
|
||||
updateOk = false;
|
||||
}
|
||||
@ -651,11 +637,6 @@ class Main {
|
||||
if (ename != null) {
|
||||
addMainClass(m, ename);
|
||||
}
|
||||
if (pname != null) {
|
||||
if (!addProfileName(m, pname)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ZipEntry e = new ZipEntry(MANIFEST_NAME);
|
||||
e.setTime(System.currentTimeMillis());
|
||||
if (flag0) {
|
||||
@ -713,28 +694,6 @@ class Main {
|
||||
global.put(Attributes.Name.MAIN_CLASS, mainApp);
|
||||
}
|
||||
|
||||
private boolean addProfileName(Manifest m, String profile) {
|
||||
// check profile name
|
||||
boolean found = false;
|
||||
int i = 0;
|
||||
while (i < PROFILES.length) {
|
||||
if (profile.equals(PROFILES[i])) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!found) {
|
||||
error(formatMsg("error.bad.pvalue", profile));
|
||||
return false;
|
||||
}
|
||||
|
||||
// overrides any existing Profile attribute
|
||||
Attributes global = m.getMainAttributes();
|
||||
global.put(Attributes.Name.PROFILE, profile);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isAmbiguousMainClass(Manifest m) {
|
||||
if (ename != null) {
|
||||
Attributes global = m.getMainAttributes();
|
||||
|
||||
@ -36,8 +36,6 @@ error.bad.uflag=\
|
||||
error.bad.eflag=\
|
||||
'e' flag and manifest with the 'Main-Class' attribute cannot be specified \n\
|
||||
together!
|
||||
error.bad.pvalue=\
|
||||
bad value for 'Profile' attribute: {0}
|
||||
error.nosuch.fileordir=\
|
||||
{0} : no such file or directory
|
||||
error.write.file=\
|
||||
@ -79,7 +77,6 @@ Options:\n\
|
||||
\ \ -m include manifest information from specified manifest file\n\
|
||||
\ \ -e specify application entry point for stand-alone application \n\
|
||||
\ \ bundled into an executable jar file\n\
|
||||
\ \ -p specify profile name\n\
|
||||
\ \ -0 store only; use no ZIP compression\n\
|
||||
\ \ -M do not create a manifest file for the entries\n\
|
||||
\ \ -i generate index information for the specified jar files\n\
|
||||
|
||||
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.File;
|
||||
import java.util.jar.*;
|
||||
|
||||
/**
|
||||
* Attempts to load classes or resources from a JAR file. The load should succeed
|
||||
* if the runtime supports the profile indicated by the Profile attribute, fail
|
||||
* with UnsupportedProfileException otherwise.
|
||||
*/
|
||||
|
||||
public class Basic {
|
||||
|
||||
static int indexOf(String profile) {
|
||||
if (profile == null || "compact1".equals(profile)) return 1;
|
||||
if ("compact2".equals(profile)) return 2;
|
||||
if ("compact3".equals(profile)) return 3;
|
||||
if ("".equals(profile)) return 4;
|
||||
return Integer.MAX_VALUE; // unknown profile name
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length < 2)
|
||||
throw new RuntimeException("Usage: java <jarfile> <classname>");
|
||||
String jar = args[0];
|
||||
String cn = args[1];
|
||||
|
||||
File lib = new File(jar);
|
||||
URL url = lib.toURI().toURL();
|
||||
URL urls[] = { url };
|
||||
|
||||
// ## replace this if there is a standard way to determine the profile
|
||||
String thisProfile = sun.misc.Version.profileName();
|
||||
|
||||
String jarProfile = null;
|
||||
try (JarFile jf = new JarFile(lib)) {
|
||||
Manifest manifest = jf.getManifest();
|
||||
if (manifest != null) {
|
||||
Attributes mainAttrs = manifest.getMainAttributes();
|
||||
if (mainAttrs != null) {
|
||||
jarProfile = mainAttrs.getValue(Attributes.Name.PROFILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean shouldFail = indexOf(thisProfile) < indexOf(jarProfile);
|
||||
|
||||
try (URLClassLoader cl = new URLClassLoader(urls)) {
|
||||
System.out.format("Loading %s from %s ...%n", cn, jar);
|
||||
Class<?> c = Class.forName(cn, true, cl);
|
||||
System.out.println(c);
|
||||
if (shouldFail)
|
||||
throw new RuntimeException("UnsupportedProfileException expected");
|
||||
} catch (UnsupportedProfileException x) {
|
||||
if (!shouldFail)
|
||||
throw x;
|
||||
System.out.println("UnsupportedProfileException thrown as expected");
|
||||
}
|
||||
|
||||
try (URLClassLoader cl = new URLClassLoader(urls)) {
|
||||
System.out.format("Loading resource from %s ...%n", jar);
|
||||
URL r = cl.findResource("META-INF/MANIFEST.MF");
|
||||
System.out.println(r);
|
||||
if (shouldFail)
|
||||
throw new RuntimeException("UnsupportedProfileException expected");
|
||||
} catch (UnsupportedProfileException x) {
|
||||
if (!shouldFail)
|
||||
throw x;
|
||||
System.out.println("UnsupportedProfileException thrown as expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* 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 lib;
|
||||
|
||||
public class Lib {
|
||||
private Lib() { }
|
||||
|
||||
public static void doSomething() { }
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 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.
|
||||
#
|
||||
# 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 8003255
|
||||
# @compile -XDignore.symbol.file Basic.java Lib.java
|
||||
# @summary Test that UnsupportedProfileException thrown when attempting to
|
||||
# load classes or resources from a JAR file with the Profile attribute
|
||||
# @run shell basic.sh
|
||||
|
||||
if [ -z "$TESTJAVA" ]; then
|
||||
if [ $# -lt 1 ]; then exit 1; fi
|
||||
TESTJAVA=$1; shift
|
||||
COMPILEJAVA=$TESTJAVA
|
||||
TESTSRC=`pwd`
|
||||
TESTCLASSES=`pwd`
|
||||
fi
|
||||
|
||||
echo "Creating GoodLib.jar ..."
|
||||
echo "Profile: compact3" > good.mf
|
||||
$COMPILEJAVA/bin/jar cvfm GoodLib.jar good.mf -C $TESTCLASSES lib
|
||||
|
||||
echo "Create BadLib.jar ..."
|
||||
echo "Profile: badname" > bad.mf
|
||||
$COMPILEJAVA/bin/jar cvfm BadLib.jar bad.mf -C $TESTCLASSES lib
|
||||
|
||||
# remove classes so that they aren't on the classpath
|
||||
rm -rf $TESTCLASSES/lib
|
||||
|
||||
echo "Test with GoodLib.jar ..."
|
||||
$TESTJAVA/bin/java -cp $TESTCLASSES Basic GoodLib.jar lib.Lib
|
||||
|
||||
echo "Test with BadLib.jar ..."
|
||||
$TESTJAVA/bin/java -cp $TESTCLASSES Basic BadLib.jar lib.Lib
|
||||
|
||||
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* 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 8003255
|
||||
* @compile -XDignore.symbol.file AddAndUpdateProfile.java
|
||||
* @run main AddAndUpdateProfile
|
||||
* @summary Basic test of jar tool "p" option to add or update the Profile
|
||||
* attribute in the main manifest of a JAR file
|
||||
*/
|
||||
|
||||
import java.util.jar.*;
|
||||
import static java.util.jar.Attributes.Name.*;
|
||||
import java.nio.file.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.tools.jar.Main;
|
||||
|
||||
public class AddAndUpdateProfile {
|
||||
static boolean doJar(String... args) {
|
||||
System.out.print("jar");
|
||||
for (String arg: args)
|
||||
System.out.print(" " + arg);
|
||||
System.out.println("");
|
||||
|
||||
Main jartool = new Main(System.out, System.err, "jar");
|
||||
return jartool.run(args);
|
||||
}
|
||||
|
||||
static void jar(String... args) {
|
||||
if (!doJar(args))
|
||||
throw new RuntimeException("jar command failed");
|
||||
}
|
||||
|
||||
static void jarExpectingFail(String... args) {
|
||||
if (doJar(args))
|
||||
throw new RuntimeException("jar command not expected to succeed");
|
||||
}
|
||||
|
||||
static void checkMainAttribute(String jarfile, Attributes.Name name,
|
||||
String expectedValue)
|
||||
throws IOException
|
||||
{
|
||||
try (JarFile jf = new JarFile(jarfile)) {
|
||||
Manifest mf = jf.getManifest();
|
||||
if (mf == null && expectedValue != null)
|
||||
throw new RuntimeException("Manifest not found");
|
||||
if (mf != null) {
|
||||
String actual = mf.getMainAttributes().getValue(name);
|
||||
if (actual != null) {
|
||||
if (!actual.equals(expectedValue))
|
||||
throw new RuntimeException("Profile attribute has unexpected value");
|
||||
} else {
|
||||
if (expectedValue != null)
|
||||
throw new RuntimeException("Profile attribute should not be present");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Path entry = Files.createFile(Paths.get("xfoo"));
|
||||
String jarfile = "xFoo.jar";
|
||||
try {
|
||||
|
||||
// create JAR file with Profile attribute
|
||||
jar("cfp", jarfile, "compact1", entry.toString());
|
||||
checkMainAttribute(jarfile, PROFILE, "compact1");
|
||||
|
||||
// attempt to create JAR file with Profile attribute and bad value
|
||||
jarExpectingFail("cfp", jarfile, "garbage", entry.toString());
|
||||
jarExpectingFail("cfp", jarfile, "Compact1", entry.toString());
|
||||
jarExpectingFail("cfp", jarfile, "COMPACT1", entry.toString());
|
||||
|
||||
// update value of Profile attribute
|
||||
jar("ufp", jarfile, "compact2");
|
||||
checkMainAttribute(jarfile, PROFILE, "compact2");
|
||||
|
||||
// attempt to update value of Profile attribute to bad value
|
||||
// (update should not change the JAR file)
|
||||
jarExpectingFail("ufp", jarfile, "garbage");
|
||||
checkMainAttribute(jarfile, PROFILE, "compact2");
|
||||
jarExpectingFail("ufp", jarfile, "COMPACT1");
|
||||
checkMainAttribute(jarfile, PROFILE, "compact2");
|
||||
|
||||
// create JAR file with both a Main-Class and Profile attribute
|
||||
jar("cfep", jarfile, "Foo", "compact1", entry.toString());
|
||||
checkMainAttribute(jarfile, MAIN_CLASS, "Foo");
|
||||
checkMainAttribute(jarfile, PROFILE, "compact1");
|
||||
|
||||
// update value of Profile attribute
|
||||
jar("ufp", jarfile, "compact2");
|
||||
checkMainAttribute(jarfile, PROFILE, "compact2");
|
||||
|
||||
// create JAR file without Profile attribute
|
||||
jar("cf", jarfile, entry.toString());
|
||||
checkMainAttribute(jarfile, PROFILE, null);
|
||||
|
||||
// update value of Profile attribute
|
||||
jar("ufp", jarfile, "compact3");
|
||||
checkMainAttribute(jarfile, PROFILE, "compact3");
|
||||
|
||||
} finally {
|
||||
Files.deleteIfExists(Paths.get(jarfile));
|
||||
Files.delete(entry);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* 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 8003255
|
||||
* @compile -XDignore.symbol.file Basic.java Main.java Logging.java
|
||||
* @run main Basic
|
||||
* @summary Test the launcher checks the Profile attribute of executable JAR
|
||||
* files. Also checks that libraries that specify the Profile attribute
|
||||
* are not loaded if the runtime does not support the required profile.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.jar.*;
|
||||
import static java.util.jar.JarFile.MANIFEST_NAME;
|
||||
import java.util.zip.*;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
public class Basic {
|
||||
|
||||
static final String MANIFEST_DIR = "META-INF/";
|
||||
|
||||
static final String JAVA_HOME = System.getProperty("java.home");
|
||||
static final String OS_NAME = System.getProperty("os.name");
|
||||
static final String OS_ARCH = System.getProperty("os.arch");
|
||||
|
||||
static final String JAVA_CMD =
|
||||
OS_NAME.startsWith("Windows") ? "java.exe" : "java";
|
||||
|
||||
static final boolean NEED_D64 =
|
||||
OS_NAME.equals("SunOS") &&
|
||||
(OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64"));
|
||||
|
||||
/**
|
||||
* Creates a JAR file with the given attributes and the given entries.
|
||||
* Class files are assumed to be in ${test.classes}. Note that this this
|
||||
* method cannot use the "jar" tool as it may not be present in the image.
|
||||
*/
|
||||
static void createJarFile(String jarfile,
|
||||
String mainAttributes,
|
||||
String... entries)
|
||||
throws IOException
|
||||
{
|
||||
// create Manifest
|
||||
Manifest manifest = new Manifest();
|
||||
Attributes jarAttrs = manifest.getMainAttributes();
|
||||
jarAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
if (mainAttributes.length() > 0) {
|
||||
for (String attr: mainAttributes.split(",")) {
|
||||
String[] s = attr.split("=");
|
||||
jarAttrs.put(new Attributes.Name(s[0]), s[1]);
|
||||
}
|
||||
}
|
||||
|
||||
try (OutputStream out = Files.newOutputStream(Paths.get(jarfile));
|
||||
ZipOutputStream zos = new JarOutputStream(out))
|
||||
{
|
||||
// add manifest directory and manifest file
|
||||
ZipEntry e = new JarEntry(MANIFEST_DIR);
|
||||
e.setTime(System.currentTimeMillis());
|
||||
e.setSize(0);
|
||||
e.setCrc(0);
|
||||
zos.putNextEntry(e);
|
||||
e = new ZipEntry(MANIFEST_NAME);
|
||||
e.setTime(System.currentTimeMillis());
|
||||
zos.putNextEntry(e);
|
||||
manifest.write(zos);
|
||||
zos.closeEntry();
|
||||
|
||||
// entries in JAR file
|
||||
for (String entry: entries) {
|
||||
e = new JarEntry(entry);
|
||||
Path path;
|
||||
if (entry.endsWith(".class")) {
|
||||
path = Paths.get(System.getProperty("test.classes"), entry);
|
||||
} else {
|
||||
path = Paths.get(entry);
|
||||
}
|
||||
BasicFileAttributes attrs =
|
||||
Files.readAttributes(path, BasicFileAttributes.class);
|
||||
e.setTime(attrs.lastModifiedTime().toMillis());
|
||||
if (attrs.size() == 0) {
|
||||
e.setMethod(ZipEntry.STORED);
|
||||
e.setSize(0);
|
||||
e.setCrc(0);
|
||||
}
|
||||
zos.putNextEntry(e);
|
||||
if (attrs.isRegularFile())
|
||||
Files.copy(path, zos);
|
||||
zos.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given executable JAR file with the given arguments. This
|
||||
* method blocks until the launched VM terminates. Any output or error
|
||||
* message from the launched VM are printed to System.out. Returns the
|
||||
* exit value.
|
||||
*/
|
||||
static int exec(String jf, String... args) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString());
|
||||
if (NEED_D64)
|
||||
sb.append(" -d64");
|
||||
sb.append(" -jar ");
|
||||
sb.append(Paths.get(jf).toAbsolutePath());
|
||||
for (String arg: args) {
|
||||
sb.append(' ');
|
||||
sb.append(arg);
|
||||
}
|
||||
String[] cmd = sb.toString().split(" ");
|
||||
ProcessBuilder pb = new ProcessBuilder(cmd);
|
||||
pb.redirectErrorStream(true);
|
||||
Process p = pb.start();
|
||||
BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
System.out.println(line);
|
||||
}
|
||||
try {
|
||||
return p.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException("Should not happen");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkRun(String jf, String... args) throws IOException {
|
||||
if (exec(jf) != 0)
|
||||
throw new RuntimeException(jf + " failed!!!");
|
||||
}
|
||||
|
||||
static void checkRunFail(String jf, String... args) throws IOException {
|
||||
if (exec(jf) == 0)
|
||||
throw new RuntimeException(jf + " did not fail!!!");
|
||||
System.out.println("Failed as expected");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// ## replace this if there is a standard way to determine the profile
|
||||
String profile = sun.misc.Version.profileName();
|
||||
|
||||
int thisProfile = 4;
|
||||
if ("compact1".equals(profile)) thisProfile = 1;
|
||||
if ("compact2".equals(profile)) thisProfile = 2;
|
||||
if ("compact3".equals(profile)) thisProfile = 3;
|
||||
|
||||
// "library" JAR file used by the test
|
||||
createJarFile("Logging.jar", "", "Logging.class");
|
||||
|
||||
// Executable JAR file without the Profile attribute
|
||||
if (thisProfile <= 3) {
|
||||
createJarFile("Main.jar",
|
||||
"Main-Class=Main,Class-Path=Logging.jar",
|
||||
"Main.class");
|
||||
checkRunFail("Main.jar");
|
||||
}
|
||||
|
||||
// Executable JAR file with Profile attribute, Library JAR file without
|
||||
for (int p=1; p<=3; p++) {
|
||||
String attrs = "Main-Class=Main,Class-Path=Logging.jar" +
|
||||
",Profile=compact" + p;
|
||||
createJarFile("Main.jar", attrs, "Main.class");
|
||||
if (p <= thisProfile) {
|
||||
checkRun("Main.jar");
|
||||
} else {
|
||||
checkRunFail("Main.jar");
|
||||
}
|
||||
}
|
||||
|
||||
// Executable JAR file with Profile attribute that has invalid profile
|
||||
// name, including incorrect case.
|
||||
createJarFile("Main.jar",
|
||||
"Main-Class=Main,Class-Path=Logging.jar,Profile=BadName",
|
||||
"Main.class");
|
||||
checkRunFail("Main.jar");
|
||||
|
||||
createJarFile("Main.jar",
|
||||
"Main-Class=Main,Class-Path=Logging.jar,Profile=Compact1",
|
||||
"Main.class");
|
||||
checkRunFail("Main.jar");
|
||||
|
||||
// Executable JAR file and Librrary JAR file with Profile attribute
|
||||
createJarFile("Main.jar",
|
||||
"Main-Class=Main,Class-Path=Logging.jar,Profile=compact1",
|
||||
"Main.class");
|
||||
for (int p=1; p<=3; p++) {
|
||||
String attrs = "Profile=compact" + p;
|
||||
createJarFile("Logging.jar", attrs, "Logging.class");
|
||||
if (p <= thisProfile) {
|
||||
checkRun("Main.jar");
|
||||
} else {
|
||||
checkRunFail("Main.jar");
|
||||
}
|
||||
}
|
||||
|
||||
// Executable JAR file and Library JAR with Profile attribute, value
|
||||
// of Profile not recognized
|
||||
createJarFile("Logging.jar", "Profile=BadName", "Logging.class");
|
||||
createJarFile("Main.jar",
|
||||
"Main-Class=Main,Class-Path=Logging.jar,Profile=compact1",
|
||||
"Main.class");
|
||||
checkRunFail("Main.jar");
|
||||
|
||||
System.out.println("TEST PASSED.");
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
public class Logging {
|
||||
private Logging() { }
|
||||
|
||||
public static void log(String msg) {
|
||||
System.out.println(msg);
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
public class Main {
|
||||
private Main() { }
|
||||
|
||||
public static void main(String[] args) {
|
||||
Logging.log("main running");
|
||||
}
|
||||
}
|
||||
@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* 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 8003256
|
||||
* @compile -XDignore.symbol.file VersionCheck.java
|
||||
* @run main VersionCheck
|
||||
* @summary Tests that "java -version" includes the name of the profile and that
|
||||
* it matches the name in the release file
|
||||
*/
|
||||
|
||||
import java.nio.file.*;
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class VersionCheck {
|
||||
|
||||
static final String JAVA_HOME = System.getProperty("java.home");
|
||||
static final String OS_NAME = System.getProperty("os.name");
|
||||
static final String OS_ARCH = System.getProperty("os.arch");
|
||||
|
||||
static final String JAVA_CMD =
|
||||
OS_NAME.startsWith("Windows") ? "java.exe" : "java";
|
||||
|
||||
static final boolean NEED_D64 =
|
||||
OS_NAME.equals("SunOS") &&
|
||||
(OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64"));
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the given class is present.
|
||||
*/
|
||||
static boolean isPresent(String cn) {
|
||||
try {
|
||||
Class.forName(cn);
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the profile by checking whether specific classes are present.
|
||||
* Returns the empty string if this runtime does not appear to be a profile
|
||||
* of Java SE.
|
||||
*/
|
||||
static String probeProfile() {
|
||||
if (isPresent("java.awt.Window"))
|
||||
return "";
|
||||
if (isPresent("java.lang.management.ManagementFactory"))
|
||||
return "compact3";
|
||||
if (isPresent("java.sql.DriverManager"))
|
||||
return "compact2";
|
||||
return "compact1";
|
||||
}
|
||||
|
||||
/**
|
||||
* Execs java with the given parameters. The method blocks until the
|
||||
* process terminates. Returns a {@code ByteArrayOutputStream} with any
|
||||
* stdout or stderr from the process.
|
||||
*/
|
||||
static ByteArrayOutputStream execJava(String... args)
|
||||
throws IOException
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString());
|
||||
if (NEED_D64)
|
||||
sb.append(" -d64");
|
||||
for (String arg: args) {
|
||||
sb.append(' ');
|
||||
sb.append(arg);
|
||||
}
|
||||
String[] cmd = sb.toString().split(" ");
|
||||
ProcessBuilder pb = new ProcessBuilder(cmd);
|
||||
pb.redirectErrorStream(true);
|
||||
Process p = pb.start();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[1024];
|
||||
int n;
|
||||
do {
|
||||
n = p.getInputStream().read(buf);
|
||||
if (n > 0)
|
||||
baos.write(buf, 0, n);
|
||||
} while (n > 0);
|
||||
try {
|
||||
int exitCode = p.waitFor();
|
||||
if (exitCode != 0)
|
||||
throw new RuntimeException("Exit code: " + exitCode);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException("Should not happen");
|
||||
}
|
||||
return baos;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String reported = sun.misc.Version.profileName();
|
||||
String probed = probeProfile();
|
||||
if (!reported.equals(probed)) {
|
||||
throw new RuntimeException("sun.misc.Version reports: " + reported
|
||||
+ ", but probing reports: " + probed);
|
||||
}
|
||||
|
||||
String profile = probed;
|
||||
boolean isFullJre = (profile.length() == 0);
|
||||
|
||||
// check that java -version includes "profile compactN"
|
||||
String expected = "profile " + profile;
|
||||
System.out.println("Checking java -version ...");
|
||||
ByteArrayOutputStream baos = execJava("-version");
|
||||
ByteArrayInputStream bain = new ByteArrayInputStream(baos.toByteArray());
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(bain));
|
||||
boolean found = false;
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.contains(expected)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found && isFullJre)
|
||||
throw new RuntimeException(expected + " found in java -version output");
|
||||
if (!found && !isFullJre)
|
||||
throw new RuntimeException("java -version did not include " + expected);
|
||||
|
||||
// check that the profile name matches the release file
|
||||
System.out.println("Checking release file ...");
|
||||
Properties props = new Properties();
|
||||
|
||||
Path home = Paths.get(JAVA_HOME);
|
||||
if (home.getFileName().toString().equals("jre"))
|
||||
home = home.getParent();
|
||||
Path release = home.resolve("release");
|
||||
try (InputStream in = Files.newInputStream(release)) {
|
||||
props.load(in);
|
||||
}
|
||||
String value = props.getProperty("JAVA_PROFILE");
|
||||
if (isFullJre) {
|
||||
if (value != null)
|
||||
throw new RuntimeException("JAVA_PROFILE should not be present");
|
||||
} else {
|
||||
if (value == null)
|
||||
throw new RuntimeException("JAVA_PROFILE not present in release file");
|
||||
if (!value.equals("\"" + profile + "\""))
|
||||
throw new RuntimeException("Unexpected value of JAVA_PROFILE: " + value);
|
||||
}
|
||||
|
||||
System.out.println("Test passed.");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user