提交 130dc864 编写于 作者: L lana

Merge

......@@ -89,7 +89,7 @@ define FullPath
$(shell $(CYGPATH_CMD) $1 2> $(DEV_NULL))
endef
define OptFullPath
$(shell if [ "$1" != "" -a -d "$1" ]; then $(CYGPATH_CMD) "$1"; else echo "$1"; fi)
$(shell if [ "$1" != "" -a -d "$1" ]; then $(CYGPATH_CMD) "$1" 2> $(DEV_NULL); else echo "$1"; fi)
endef
else
# Temporary until we upgrade to MKS 8.7, MKS pwd returns mixed mode path
......
......@@ -136,15 +136,20 @@ define GetVersion
$(shell echo $1 | sed -e 's@[^0-9]*\([0-9][0-9]*\.[0-9][.0-9]*\).*@\1@' )
endef
# Return one part of the version numbers, watch out for non digits.
define VersionWord # Number Version
$(word $1,$(subst ., ,$(subst -, ,$2)))
endef
# Given a major.minor.micro version, return the major, minor, or micro number
define MajorVersion
$(if $(word 1, $(subst ., ,$1)),$(word 1, $(subst ., ,$1)),0)
$(if $(call VersionWord,1,$1),$(call VersionWord,1,$1),0)
endef
define MinorVersion
$(if $(word 2, $(subst ., ,$1)),$(word 2, $(subst ., ,$1)),0)
$(if $(call VersionWord,2,$1),$(call VersionWord,2,$1),0)
endef
define MicroVersion
$(if $(word 3, $(subst ., ,$1)),$(word 3, $(subst ., ,$1)),0)
$(if $(call VersionWord,3,$1),$(call VersionWord,3,$1),0)
endef
# Macro that returns missing, same, newer, or older $1=version $2=required
......
......@@ -340,6 +340,10 @@ PATH="${path4sdk}"
export PATH
# Export variables required for Zero
if [ "${SHARK_BUILD}" = true ] ; then
ZERO_BUILD=true
export ZERO_BUILD
fi
if [ "${ZERO_BUILD}" = true ] ; then
# ZERO_LIBARCH is the name of the architecture-specific
# subdirectory under $JAVA_HOME/jre/lib
......@@ -417,4 +421,55 @@ if [ "${ZERO_BUILD}" = true ] ; then
fi
export LIBFFI_CFLAGS
export LIBFFI_LIBS
# LLVM_CFLAGS, LLVM_LDFLAGS and LLVM_LIBS tell the compiler how to
# compile and link against LLVM
if [ "${SHARK_BUILD}" = true ] ; then
if [ "${LLVM_CONFIG}" = "" ] ; then
LLVM_CONFIG=$(which llvm-config 2>/dev/null)
fi
if [ ! -x "${LLVM_CONFIG}" ] ; then
echo "ERROR: Unable to locate llvm-config"
exit 1
fi
llvm_components="jit engine nativecodegen"
unset LLVM_CFLAGS
for flag in $("${LLVM_CONFIG}" --cxxflags $llvm_components); do
if echo "${flag}" | grep -q '^-[ID]'; then
if [ "${flag}" != "-D_DEBUG" ] ; then
if [ "${LLVM_CFLAGS}" != "" ] ; then
LLVM_CFLAGS="${LLVM_CFLAGS} "
fi
LLVM_CFLAGS="${LLVM_CFLAGS}${flag}"
fi
fi
done
llvm_version=$("${LLVM_CONFIG}" --version | sed 's/\.//; s/svn.*//')
LLVM_CFLAGS="${LLVM_CFLAGS} -DSHARK_LLVM_VERSION=${llvm_version}"
unset LLVM_LDFLAGS
for flag in $("${LLVM_CONFIG}" --ldflags $llvm_components); do
if echo "${flag}" | grep -q '^-L'; then
if [ "${LLVM_LDFLAGS}" != "" ] ; then
LLVM_LDFLAGS="${LLVM_LDFLAGS} "
fi
LLVM_LDFLAGS="${LLVM_LDFLAGS}${flag}"
fi
done
unset LLVM_LIBS
for flag in $("${LLVM_CONFIG}" --libs $llvm_components); do
if echo "${flag}" | grep -q '^-l'; then
if [ "${LLVM_LIBS}" != "" ] ; then
LLVM_LIBS="${LLVM_LIBS} "
fi
LLVM_LIBS="${LLVM_LIBS}${flag}"
fi
done
export LLVM_CFLAGS
export LLVM_LDFLAGS
export LLVM_LIBS
fi
fi
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -27,7 +27,6 @@ package com.sun.java.util.jar.pack;
import java.io.*;
import java.util.*;
import com.sun.java.util.jar.pack.Package.Class;
import com.sun.java.util.jar.pack.ConstantPool.*;
/**
......@@ -96,20 +95,20 @@ class Attribute implements Comparable, Constants {
return this.def.compareTo(that.def);
}
static private final byte[] noBytes = {};
static private final HashMap canonLists = new HashMap();
static private final HashMap attributes = new HashMap();
static private final HashMap standardDefs = new HashMap();
private static final byte[] noBytes = {};
private static final Map<List<Attribute>, List<Attribute>> canonLists = new HashMap<>();
private static final Map<Layout, Attribute> attributes = new HashMap<>();
private static final Map<Layout, Attribute> standardDefs = new HashMap<>();
// Canonicalized lists of trivial attrs (Deprecated, etc.)
// are used by trimToSize, in order to reduce footprint
// of some common cases. (Note that Code attributes are
// always zero size.)
public static List getCanonList(List al) {
public static List getCanonList(List<Attribute> al) {
synchronized (canonLists) {
List cl = (List) canonLists.get(al);
List<Attribute> cl = canonLists.get(al);
if (cl == null) {
cl = new ArrayList(al.size());
cl = new ArrayList<>(al.size());
cl.addAll(al);
cl = Collections.unmodifiableList(cl);
canonLists.put(al, cl);
......@@ -122,7 +121,7 @@ class Attribute implements Comparable, Constants {
public static Attribute find(int ctype, String name, String layout) {
Layout key = Layout.makeKey(ctype, name, layout);
synchronized (attributes) {
Attribute a = (Attribute) attributes.get(key);
Attribute a = attributes.get(key);
if (a == null) {
a = new Layout(ctype, name, layout).canonicalInstance();
attributes.put(key, a);
......@@ -131,24 +130,29 @@ class Attribute implements Comparable, Constants {
}
}
public static Object keyForLookup(int ctype, String name) {
public static Layout keyForLookup(int ctype, String name) {
return Layout.makeKey(ctype, name);
}
// Find canonical empty attribute with given ctype and name,
// and with the standard layout.
public static Attribute lookup(Map defs, int ctype, String name) {
if (defs == null) defs = standardDefs;
return (Attribute) defs.get(Layout.makeKey(ctype, name));
public static Attribute lookup(Map<Layout, Attribute> defs, int ctype,
String name) {
if (defs == null) {
defs = standardDefs;
}
return defs.get(Layout.makeKey(ctype, name));
}
public static Attribute define(Map defs, int ctype, String name, String layout) {
public static Attribute define(Map<Layout, Attribute> defs, int ctype,
String name, String layout) {
Attribute a = find(ctype, name, layout);
defs.put(Layout.makeKey(ctype, name), a);
return a;
}
static {
Map sd = standardDefs;
Map<Layout, Attribute> sd = standardDefs;
define(sd, ATTR_CONTEXT_CLASS, "Signature", "RSH");
define(sd, ATTR_CONTEXT_CLASS, "Synthetic", "");
define(sd, ATTR_CONTEXT_CLASS, "Deprecated", "");
......@@ -244,7 +248,7 @@ class Attribute implements Comparable, Constants {
+"\n ()[] ]"
)
};
Map sd = standardDefs;
Map<Layout, Attribute> sd = standardDefs;
String defaultLayout = mdLayouts[2];
String annotationsLayout = mdLayouts[1] + mdLayouts[2];
String paramsLayout = mdLayouts[0] + annotationsLayout;
......@@ -275,10 +279,6 @@ class Attribute implements Comparable, Constants {
return null;
}
public static Map getStandardDefs() {
return new HashMap(standardDefs);
}
/** Base class for any attributed object (Class, Field, Method, Code).
* Flags are included because they are used to help transmit the
* presence of attributes. That is, flags are a mix of modifier
......@@ -291,7 +291,7 @@ class Attribute implements Comparable, Constants {
protected abstract Entry[] getCPMap();
protected int flags; // defined here for convenience
protected List attributes;
protected List<Attribute> attributes;
public int attributeSize() {
return (attributes == null) ? 0 : attributes.size();
......@@ -301,16 +301,15 @@ class Attribute implements Comparable, Constants {
if (attributes == null) {
return;
}
if (attributes.size() == 0) {
if (attributes.isEmpty()) {
attributes = null;
return;
}
if (attributes instanceof ArrayList) {
ArrayList al = (ArrayList) attributes;
ArrayList<Attribute> al = (ArrayList<Attribute>)attributes;
al.trimToSize();
boolean allCanon = true;
for (Iterator i = al.iterator(); i.hasNext(); ) {
Attribute a = (Attribute) i.next();
for (Attribute a : al) {
if (!a.isCanonical()) {
allCanon = false;
}
......@@ -330,9 +329,9 @@ class Attribute implements Comparable, Constants {
public void addAttribute(Attribute a) {
if (attributes == null)
attributes = new ArrayList(3);
attributes = new ArrayList<>(3);
else if (!(attributes instanceof ArrayList))
attributes = new ArrayList(attributes); // unfreeze it
attributes = new ArrayList<>(attributes); // unfreeze it
attributes.add(a);
}
......@@ -340,32 +339,31 @@ class Attribute implements Comparable, Constants {
if (attributes == null) return null;
if (!attributes.contains(a)) return null;
if (!(attributes instanceof ArrayList))
attributes = new ArrayList(attributes); // unfreeze it
attributes = new ArrayList<>(attributes); // unfreeze it
attributes.remove(a);
return a;
}
public Attribute getAttribute(int n) {
return (Attribute) attributes.get(n);
return attributes.get(n);
}
protected void visitRefs(int mode, Collection refs) {
protected void visitRefs(int mode, Collection<Entry> refs) {
if (attributes == null) return;
for (Iterator i = attributes.iterator(); i.hasNext(); ) {
Attribute a = (Attribute) i.next();
for (Attribute a : attributes) {
a.visitRefs(this, mode, refs);
}
}
static final List noAttributes = Arrays.asList(new Object[0]);
static final List<Attribute> noAttributes = Arrays.asList(new Attribute[0]);
public List getAttributes() {
public List<Attribute> getAttributes() {
if (attributes == null)
return noAttributes;
return attributes;
}
public void setAttributes(List attrList) {
public void setAttributes(List<Attribute> attrList) {
if (attrList.isEmpty())
attributes = null;
else
......@@ -374,8 +372,7 @@ class Attribute implements Comparable, Constants {
public Attribute getAttribute(String attrName) {
if (attributes == null) return null;
for (Iterator i = attributes.iterator(); i.hasNext(); ) {
Attribute a = (Attribute) i.next();
for (Attribute a : attributes) {
if (a.name().equals(attrName))
return a;
}
......@@ -384,8 +381,7 @@ class Attribute implements Comparable, Constants {
public Attribute getAttribute(Layout attrDef) {
if (attributes == null) return null;
for (Iterator i = attributes.iterator(); i.hasNext(); ) {
Attribute a = (Attribute) i.next();
for (Attribute a : attributes) {
if (a.layout() == attrDef)
return a;
}
......@@ -457,14 +453,8 @@ class Attribute implements Comparable, Constants {
public String layout() { return layout; }
public Attribute canonicalInstance() { return canon; }
// Cache of name reference.
private Entry nameRef; // name, for use by visitRefs
public Entry getNameRef() {
Entry nameRef = this.nameRef;
if (nameRef == null) {
this.nameRef = nameRef = ConstantPool.getUtf8Entry(name());
}
return nameRef;
return ConstantPool.getUtf8Entry(name());
}
public boolean isEmpty() { return layout == ""; }
......@@ -834,14 +824,14 @@ class Attribute implements Comparable, Constants {
*/
static //private
Layout.Element[] tokenizeLayout(Layout self, int curCble, String layout) {
ArrayList col = new ArrayList(layout.length());
ArrayList<Layout.Element> col = new ArrayList<>(layout.length());
tokenizeLayout(self, curCble, layout, col);
Layout.Element[] res = new Layout.Element[col.size()];
col.toArray(res);
return res;
}
static //private
void tokenizeLayout(Layout self, int curCble, String layout, ArrayList col) {
void tokenizeLayout(Layout self, int curCble, String layout, ArrayList<Layout.Element> col) {
boolean prevBCI = false;
for (int len = layout.length(), i = 0; i < len; ) {
int start = i;
......@@ -899,7 +889,7 @@ class Attribute implements Comparable, Constants {
case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']'
kind = EK_UN;
i = tokenizeSInt(e, layout, i);
ArrayList cases = new ArrayList();
ArrayList<Layout.Element> cases = new ArrayList<>();
for (;;) {
// Keep parsing cases until we hit the default case.
if (layout.charAt(i++) != '(')
......@@ -1053,7 +1043,7 @@ class Attribute implements Comparable, Constants {
}
static //private
String[] splitBodies(String layout) {
ArrayList bodies = new ArrayList();
ArrayList<String> bodies = new ArrayList<>();
// Parse several independent layout bodies: "[foo][bar]...[baz]"
for (int i = 0; i < layout.length(); i++) {
if (layout.charAt(i++) != '[')
......@@ -1132,7 +1122,9 @@ class Attribute implements Comparable, Constants {
int parseIntBefore(String layout, int dash) {
int end = dash;
int beg = end;
while (beg > 0 && isDigit(layout.charAt(beg-1))) --beg;
while (beg > 0 && isDigit(layout.charAt(beg-1))) {
--beg;
}
if (beg == end) return Integer.parseInt("empty");
// skip backward over a sign
if (beg >= 1 && layout.charAt(beg-1) == '-') --beg;
......@@ -1145,7 +1137,9 @@ class Attribute implements Comparable, Constants {
int end = beg;
int limit = layout.length();
if (end < limit && layout.charAt(end) == '-') ++end;
while (end < limit && isDigit(layout.charAt(end))) ++end;
while (end < limit && isDigit(layout.charAt(end))) {
++end;
}
if (beg == end) return Integer.parseInt("empty");
return Integer.parseInt(layout.substring(beg, end));
}
......
/*
* Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,7 +25,6 @@
package com.sun.java.util.jar.pack;
import java.io.*;
import java.util.*;
/**
......@@ -40,20 +39,13 @@ class ConstantPool implements Constants {
return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
}
// Uniquification tables for factory methods:
private static final HashMap utf8Entries = new HashMap();
private static final HashMap classEntries = new HashMap();
private static final HashMap literalEntries = new HashMap();
private static final HashMap signatureEntries = new HashMap();
private static final HashMap descriptorEntries = new HashMap();
private static final HashMap memberEntries = new HashMap();
/** Factory for Utf8 string constants.
* Used for well-known strings like "SourceFile", "<init>", etc.
* Also used to back up more complex constant pool entries, like Class.
*/
public static synchronized Utf8Entry getUtf8Entry(String value) {
Utf8Entry e = (Utf8Entry) utf8Entries.get(value);
Map<String, Utf8Entry> utf8Entries = Utils.getUtf8Entries();
Utf8Entry e = utf8Entries.get(value);
if (e == null) {
e = new Utf8Entry(value);
utf8Entries.put(e.stringValue(), e);
......@@ -62,9 +54,10 @@ class ConstantPool implements Constants {
}
/** Factory for Class constants. */
public static synchronized ClassEntry getClassEntry(String name) {
ClassEntry e = (ClassEntry) classEntries.get(name);
Map<String, ClassEntry> classEntries = Utils.getClassEntries();
ClassEntry e = classEntries.get(name);
if (e == null) {
e = (ClassEntry) new ClassEntry(getUtf8Entry(name));
e = new ClassEntry(getUtf8Entry(name));
assert(name.equals(e.stringValue()));
classEntries.put(e.stringValue(), e);
}
......@@ -72,7 +65,8 @@ class ConstantPool implements Constants {
}
/** Factory for literal constants (String, Integer, etc.). */
public static synchronized LiteralEntry getLiteralEntry(Comparable value) {
LiteralEntry e = (LiteralEntry) literalEntries.get(value);
Map<Object, LiteralEntry> literalEntries = Utils.getLiteralEntries();
LiteralEntry e = literalEntries.get(value);
if (e == null) {
if (value instanceof String)
e = new StringEntry(getUtf8Entry((String)value));
......@@ -89,7 +83,8 @@ class ConstantPool implements Constants {
/** Factory for signature (type) constants. */
public static synchronized SignatureEntry getSignatureEntry(String type) {
SignatureEntry e = (SignatureEntry) signatureEntries.get(type);
Map<String, SignatureEntry> signatureEntries = Utils.getSignatureEntries();
SignatureEntry e = signatureEntries.get(type);
if (e == null) {
e = new SignatureEntry(type);
assert(e.stringValue().equals(type));
......@@ -104,8 +99,9 @@ class ConstantPool implements Constants {
/** Factory for descriptor (name-and-type) constants. */
public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) {
Map<String, DescriptorEntry> descriptorEntries = Utils.getDescriptorEntries();
String key = DescriptorEntry.stringValueOf(nameRef, typeRef);
DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key);
DescriptorEntry e = descriptorEntries.get(key);
if (e == null) {
e = new DescriptorEntry(nameRef, typeRef);
assert(e.stringValue().equals(key))
......@@ -121,8 +117,9 @@ class ConstantPool implements Constants {
/** Factory for member reference constants. */
public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
Map<String, MemberEntry> memberEntries = Utils.getMemberEntries();
String key = MemberEntry.stringValueOf(tag, classRef, descRef);
MemberEntry e = (MemberEntry) memberEntries.get(key);
MemberEntry e = memberEntries.get(key);
if (e == null) {
e = new MemberEntry(tag, classRef, descRef);
assert(e.stringValue().equals(key))
......@@ -489,8 +486,9 @@ class ConstantPool implements Constants {
String[] parts = structureSignature(value);
formRef = getUtf8Entry(parts[0]);
classRefs = new ClassEntry[parts.length-1];
for (int i = 1; i < parts.length; i++)
classRefs[i-1] = getClassEntry(parts[i]);
for (int i = 1; i < parts.length; i++) {
classRefs[i - 1] = getClassEntry(parts[i]);
}
hashCode(); // force computation of valueHash
}
protected int computeValueHash() {
......@@ -527,8 +525,9 @@ class ConstantPool implements Constants {
String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) {
String[] parts = new String[1+classRefs.length];
parts[0] = formRef.stringValue();
for (int i = 1; i < parts.length; i++)
parts[i] = classRefs[i-1].stringValue();
for (int i = 1; i < parts.length; i++) {
parts[i] = classRefs[i - 1].stringValue();
}
return flattenSignature(parts).intern();
}
......@@ -543,19 +542,23 @@ class ConstantPool implements Constants {
int size = 0;
for (int i = min; i < max; i++) {
switch (form.charAt(i)) {
case 'D':
case 'J':
if (countDoublesTwice) size++;
break;
case '[':
// Skip rest of array info.
while (form.charAt(i) == '[') ++i;
break;
case ';':
continue;
default:
assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
break;
case 'D':
case 'J':
if (countDoublesTwice) {
size++;
}
break;
case '[':
// Skip rest of array info.
while (form.charAt(i) == '[') {
++i;
}
break;
case ';':
continue;
default:
assert (0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
break;
}
size++;
}
......@@ -586,8 +589,9 @@ class ConstantPool implements Constants {
s = "/" + formRef.stringValue();
}
int i;
while ((i = s.indexOf(';')) >= 0)
s = s.substring(0,i) + s.substring(i+1);
while ((i = s.indexOf(';')) >= 0) {
s = s.substring(0, i) + s.substring(i + 1);
}
return s;
}
}
......@@ -732,11 +736,11 @@ class ConstantPool implements Constants {
clearIndex();
this.cpMap = cpMap;
}
protected Index(String debugName, Collection cpMapList) {
protected Index(String debugName, Collection<Entry> cpMapList) {
this(debugName);
setMap(cpMapList);
}
protected void setMap(Collection cpMapList) {
protected void setMap(Collection<Entry> cpMapList) {
cpMap = new Entry[cpMapList.size()];
cpMapList.toArray(cpMap);
setMap(cpMap);
......@@ -756,11 +760,13 @@ class ConstantPool implements Constants {
//
// As a special hack, if flattenSigs, signatures are
// treated as equivalent entries of cpMap. This is wrong
// fron a Collection point of view, because contains()
// from a Collection point of view, because contains()
// reports true for signatures, but the iterator()
// never produces them!
private int findIndexOf(Entry e) {
if (indexKey == null) initializeIndex();
if (indexKey == null) {
initializeIndex();
}
int probe = findIndexLocation(e);
if (indexKey[probe] != e) {
if (flattenSigs && e.tag == CONSTANT_Signature) {
......@@ -832,7 +838,9 @@ class ConstantPool implements Constants {
System.out.println("initialize Index "+debugName+" ["+size()+"]");
int hsize0 = (int)((cpMap.length + 10) * 1.5);
int hsize = 1;
while (hsize < hsize0) hsize <<= 1;
while (hsize < hsize0) {
hsize <<= 1;
}
indexKey = new Entry[hsize];
indexValue = new int[hsize];
for (int i = 0; i < cpMap.length; i++) {
......@@ -855,7 +863,7 @@ class ConstantPool implements Constants {
return toArray(new Entry[size()]);
}
public Object clone() {
return new Index(debugName, (Entry[]) cpMap.clone());
return new Index(debugName, cpMap.clone());
}
public String toString() {
return "Index "+debugName+" ["+size()+"]";
......@@ -901,22 +909,24 @@ class ConstantPool implements Constants {
public static
Index[] partition(Index ix, int[] keys) {
// %%% Should move this into class Index.
ArrayList parts = new ArrayList();
ArrayList<List<Entry>> parts = new ArrayList<>();
Entry[] cpMap = ix.cpMap;
assert(keys.length == cpMap.length);
for (int i = 0; i < keys.length; i++) {
int key = keys[i];
if (key < 0) continue;
while (key >= parts.size()) parts.add(null);
ArrayList part = (ArrayList) parts.get(key);
while (key >= parts.size()) {
parts.add(null);
}
List<Entry> part = parts.get(key);
if (part == null) {
parts.set(key, part = new ArrayList());
parts.set(key, part = new ArrayList<>());
}
part.add(cpMap[i]);
}
Index[] indexes = new Index[parts.size()];
for (int key = 0; key < indexes.length; key++) {
ArrayList part = (ArrayList) parts.get(key);
List<Entry> part = parts.get(key);
if (part == null) continue;
indexes[key] = new Index(ix.debugName+"/part#"+key, part);
assert(indexes[key].indexOf(part.get(0)) == 0);
......@@ -1048,9 +1058,10 @@ class ConstantPool implements Constants {
whichClasses[i] = whichClass;
}
perClassIndexes = partition(allMembers, whichClasses);
for (int i = 0; i < perClassIndexes.length; i++)
assert(perClassIndexes[i]==null
|| perClassIndexes[i].assertIsSorted());
for (int i = 0; i < perClassIndexes.length; i++) {
assert (perClassIndexes[i] == null ||
perClassIndexes[i].assertIsSorted());
}
indexByTagAndClass[tag] = perClassIndexes;
}
int whichClass = allClasses.indexOf(classRef);
......@@ -1113,7 +1124,7 @@ class ConstantPool implements Constants {
* Also, discard null from cpRefs.
*/
public static
void completeReferencesIn(Set cpRefs, boolean flattenSigs) {
void completeReferencesIn(Set<Entry> cpRefs, boolean flattenSigs) {
cpRefs.remove(null);
for (ListIterator work =
new ArrayList(cpRefs).listIterator(cpRefs.size());
......
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,7 +25,6 @@
package com.sun.java.util.jar.pack;
import java.lang.Error;
import java.io.*;
import java.text.MessageFormat;
import java.util.*;
......@@ -35,10 +34,11 @@ import java.util.zip.*;
/** Command line interface for Pack200.
*/
class Driver {
private static final ResourceBundle RESOURCE= ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
private static final ResourceBundle RESOURCE =
ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
public static void main(String[] ava) throws IOException {
ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava));
ArrayList<String> av = new ArrayList<>(Arrays.asList(ava));
boolean doPack = true;
boolean doUnpack = false;
......@@ -61,7 +61,7 @@ class Driver {
}
// Collect engine properties here:
HashMap<String,String> engProps = new HashMap<String,String>();
HashMap<String,String> engProps = new HashMap<>();
engProps.put(verboseProp, System.getProperty(verboseProp));
String optionMap;
......@@ -75,7 +75,7 @@ class Driver {
}
// Collect argument properties here:
HashMap<String,String> avProps = new HashMap<String,String>();
HashMap<String,String> avProps = new HashMap<>();
try {
for (;;) {
String state = parseCommandOptions(av, optionMap, avProps);
......@@ -133,8 +133,9 @@ class Driver {
if (engProps.get(verboseProp) != null)
fileProps.list(System.out);
propIn.close();
for (Map.Entry<Object,Object> me : fileProps.entrySet())
engProps.put((String)me.getKey(), (String)me.getValue());
for (Map.Entry<Object,Object> me : fileProps.entrySet()) {
engProps.put((String) me.getKey(), (String) me.getValue());
}
} else if (state == "--version") {
System.out.println(MessageFormat.format(RESOURCE.getString(DriverResource.VERSION), Driver.class.getName(), "1.31, 07/05/05"));
return;
......@@ -493,7 +494,7 @@ class Driver {
String resultString = null;
// Convert options string into optLines dictionary.
TreeMap<String,String[]> optmap = new TreeMap<String,String[]>();
TreeMap<String,String[]> optmap = new TreeMap<>();
loadOptmap:
for (String optline : options.split("\n")) {
String[] words = optline.split("\\p{Space}+");
......@@ -687,7 +688,9 @@ class Driver {
// Report number of arguments consumed.
args.subList(0, argp.nextIndex()).clear();
// Report any unconsumed partial argument.
while (pbp.hasPrevious()) args.add(0, pbp.previous());
while (pbp.hasPrevious()) {
args.add(0, pbp.previous());
}
//System.out.println(args+" // "+properties+" -> "+resultString);
return resultString;
}
......
/*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -28,13 +28,8 @@ package com.sun.java.util.jar.pack;
import java.nio.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Date;
import java.util.jar.*;
import java.util.zip.*;
import java.util.*;
//import com.sun.java.util.jar.pack.Pack200;
class NativeUnpack {
// Pointer to the native unpacker obj
......@@ -91,13 +86,13 @@ class NativeUnpack {
NativeUnpack(UnpackerImpl p200) {
super();
_p200 = p200;
_props = p200._props;
_props = p200.props;
p200._nunp = this;
}
// for JNI callbacks
static private Object currentInstance() {
UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get();
UnpackerImpl p200 = (UnpackerImpl) Utils.getTLGlobals();
return (p200 == null)? null: p200._nunp;
}
......@@ -216,10 +211,10 @@ class NativeUnpack {
++_fileCount;
updateProgress();
}
presetInput = getUnusedInput();
long consumed = finish();
if (_verbose > 0)
Utils.log.info("bytes consumed = "+consumed);
presetInput = getUnusedInput();
if (presetInput == null &&
!Utils.isPackMagic(Utils.readMagic(in))) {
break;
......
......@@ -25,9 +25,9 @@
package com.sun.java.util.jar.pack;
import com.sun.java.util.jar.pack.Attribute.Layout;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.zip.*;
import java.util.jar.*;
import java.io.*;
import com.sun.java.util.jar.pack.ConstantPool.*;
......@@ -77,10 +77,11 @@ class Package implements Constants {
cp = new ConstantPool.IndexGroup();
classes.clear();
files.clear();
BandStructure.nextSeqForDebug = 0;
}
int getPackageVersion() {
return (package_majver << 16) + (int)package_minver;
return (package_majver << 16) + package_minver;
}
// Special empty versions of Code and InnerClasses, used for markers.
......@@ -89,7 +90,7 @@ class Package implements Constants {
public static final Attribute.Layout attrSourceFileSpecial;
public static final Map attrDefs;
static {
HashMap ad = new HashMap(2);
HashMap<Layout, Attribute> ad = new HashMap<>(3);
attrCodeEmpty = Attribute.define(ad, ATTR_CONTEXT_METHOD,
"Code", "").layout();
attrInnerClassesEmpty = Attribute.define(ad, ATTR_CONTEXT_CLASS,
......@@ -159,9 +160,9 @@ class Package implements Constants {
}
}
ArrayList classes = new ArrayList();
ArrayList<Package.Class> classes = new ArrayList<>();
public List getClasses() {
public List<Package.Class> getClasses() {
return classes;
}
......@@ -186,11 +187,11 @@ class Package implements Constants {
ClassEntry[] interfaces;
// Class parts
ArrayList fields;
ArrayList methods;
ArrayList<Field> fields;
ArrayList<Method> methods;
//ArrayList attributes; // in Attribute.Holder.this.attributes
// Note that InnerClasses may be collected at the package level.
ArrayList innerClasses;
ArrayList<InnerClass> innerClasses;
Class(int flags, ClassEntry thisClass, ClassEntry superClass, ClassEntry[] interfaces) {
this.magic = JAVA_MAGIC;
......@@ -270,7 +271,7 @@ class Package implements Constants {
if (a != olda) {
if (verbose > 2)
Utils.log.fine("recoding obvious SourceFile="+obvious);
List newAttrs = new ArrayList(getAttributes());
List<Attribute> newAttrs = new ArrayList<>(getAttributes());
int where = newAttrs.indexOf(olda);
newAttrs.set(where, a);
setAttributes(newAttrs);
......@@ -295,12 +296,12 @@ class Package implements Constants {
boolean hasInnerClasses() {
return innerClasses != null;
}
List getInnerClasses() {
List<InnerClass> getInnerClasses() {
return innerClasses;
}
public void setInnerClasses(Collection ics) {
innerClasses = (ics == null) ? null : new ArrayList(ics);
public void setInnerClasses(Collection<InnerClass> ics) {
innerClasses = (ics == null) ? null : new ArrayList<InnerClass>(ics);
// Edit the attribute list, if necessary.
Attribute a = getAttribute(attrInnerClassesEmpty);
if (innerClasses != null && a == null)
......@@ -318,19 +319,18 @@ class Package implements Constants {
* The order of the resulting list is consistent
* with that of Package.this.allInnerClasses.
*/
public List computeGloballyImpliedICs() {
HashSet cpRefs = new HashSet();
public List<InnerClass> computeGloballyImpliedICs() {
HashSet<Entry> cpRefs = new HashSet<>();
{ // This block temporarily displaces this.innerClasses.
ArrayList innerClassesSaved = innerClasses;
ArrayList<InnerClass> innerClassesSaved = innerClasses;
innerClasses = null; // ignore for the moment
visitRefs(VRM_CLASSIC, cpRefs);
innerClasses = innerClassesSaved;
}
ConstantPool.completeReferencesIn(cpRefs, true);
HashSet icRefs = new HashSet();
for (Iterator i = cpRefs.iterator(); i.hasNext(); ) {
Entry e = (Entry) i.next();
HashSet<Entry> icRefs = new HashSet<>();
for (Entry e : cpRefs) {
// Restrict cpRefs to InnerClasses entries only.
if (!(e instanceof ClassEntry)) continue;
// For every IC reference, add its outers also.
......@@ -345,9 +345,8 @@ class Package implements Constants {
// This loop is structured this way so as to accumulate
// entries into impliedICs in an order which reflects
// the order of allInnerClasses.
ArrayList impliedICs = new ArrayList();
for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) {
InnerClass ic = (InnerClass) i.next();
ArrayList<InnerClass> impliedICs = new ArrayList<>();
for (InnerClass ic : allInnerClasses) {
// This one is locally relevant if it describes
// a member of the current class, or if the current
// class uses it somehow. In the particular case
......@@ -366,10 +365,11 @@ class Package implements Constants {
// Helper for both minimizing and expanding.
// Computes a symmetric difference.
private List computeICdiff() {
List impliedICs = computeGloballyImpliedICs();
List actualICs = getInnerClasses();
if (actualICs == null) actualICs = Collections.EMPTY_LIST;
private List<InnerClass> computeICdiff() {
List<InnerClass> impliedICs = computeGloballyImpliedICs();
List<InnerClass> actualICs = getInnerClasses();
if (actualICs == null)
actualICs = Collections.EMPTY_LIST;
// Symmetric difference is calculated from I, A like this:
// diff = (I+A) - (I*A)
......@@ -388,8 +388,8 @@ class Package implements Constants {
// Diff is A since I is empty.
}
// (I*A) is non-trivial
HashSet center = new HashSet(actualICs);
center.retainAll(new HashSet(impliedICs));
HashSet<InnerClass> center = new HashSet<>(actualICs);
center.retainAll(new HashSet<>(impliedICs));
impliedICs.addAll(actualICs);
impliedICs.removeAll(center);
// Diff is now I^A = (I+A)-(I*A).
......@@ -407,9 +407,9 @@ class Package implements Constants {
* to use the globally implied ICs changed.
*/
void minimizeLocalICs() {
List diff = computeICdiff();
List actualICs = innerClasses;
List localICs; // will be the diff, modulo edge cases
List<InnerClass> diff = computeICdiff();
List<InnerClass> actualICs = innerClasses;
List<InnerClass> localICs; // will be the diff, modulo edge cases
if (diff.isEmpty()) {
// No diff, so transmit no attribute.
localICs = null;
......@@ -439,12 +439,12 @@ class Package implements Constants {
* Otherwise, return positive if any IC tuples were added.
*/
int expandLocalICs() {
List localICs = innerClasses;
List actualICs;
List<InnerClass> localICs = innerClasses;
List<InnerClass> actualICs;
int changed;
if (localICs == null) {
// Diff was empty. (Common case.)
List impliedICs = computeGloballyImpliedICs();
List<InnerClass> impliedICs = computeGloballyImpliedICs();
if (impliedICs.isEmpty()) {
actualICs = null;
changed = 0;
......@@ -490,7 +490,7 @@ class Package implements Constants {
protected Entry[] getCPMap() {
return cpMap;
}
protected void visitRefs(int mode, Collection refs) {
protected void visitRefs(int mode, Collection<Entry> refs) {
if (verbose > 2) Utils.log.fine("visitRefs "+this);
// Careful: The descriptor is used by the package,
// but the classfile breaks it into component refs.
......@@ -518,7 +518,7 @@ class Package implements Constants {
super(flags, descriptor);
assert(!descriptor.isMethod());
if (fields == null)
fields = new ArrayList();
fields = new ArrayList<>();
boolean added = fields.add(this);
assert(added);
order = fields.size();
......@@ -543,7 +543,7 @@ class Package implements Constants {
super(flags, descriptor);
assert(descriptor.isMethod());
if (methods == null)
methods = new ArrayList();
methods = new ArrayList<>();
boolean added = methods.add(this);
assert(added);
}
......@@ -573,7 +573,7 @@ class Package implements Constants {
code.strip(attrName);
super.strip(attrName);
}
protected void visitRefs(int mode, Collection refs) {
protected void visitRefs(int mode, Collection<Entry> refs) {
super.visitRefs(mode, refs);
if (code != null) {
if (mode == VRM_CLASSIC) {
......@@ -614,7 +614,7 @@ class Package implements Constants {
super.strip(attrName);
}
protected void visitRefs(int mode, Collection refs) {
protected void visitRefs(int mode, Collection<Entry> refs) {
if (verbose > 2) Utils.log.fine("visitRefs "+this);
refs.add(thisClass);
refs.add(superClass);
......@@ -641,7 +641,7 @@ class Package implements Constants {
super.visitRefs(mode, refs);
}
protected void visitInnerClassRefs(int mode, Collection refs) {
protected void visitInnerClassRefs(int mode, Collection<Entry> refs) {
Package.visitInnerClassRefs(innerClasses, mode, refs);
}
......@@ -713,16 +713,15 @@ class Package implements Constants {
}
// What non-class files are in this unit?
ArrayList files = new ArrayList();
ArrayList<File> files = new ArrayList<>();
public List getFiles() {
public List<File> getFiles() {
return files;
}
public List getClassStubs() {
ArrayList classStubs = new ArrayList(classes.size());
for (Iterator i = classes.iterator(); i.hasNext(); ) {
Class cls = (Class) i.next();
public List<File> getClassStubs() {
ArrayList<File> classStubs = new ArrayList<>(classes.size());
for (Class cls : classes) {
assert(cls.file.isClassStub());
classStubs.add(cls.file);
}
......@@ -840,7 +839,7 @@ class Package implements Constants {
public InputStream getInputStream() {
InputStream in = new ByteArrayInputStream(append.toByteArray());
if (prepend.size() == 0) return in;
ArrayList isa = new ArrayList(prepend.size()+1);
ArrayList<InputStream> isa = new ArrayList<>(prepend.size()+1);
for (Iterator i = prepend.iterator(); i.hasNext(); ) {
byte[] bytes = (byte[]) i.next();
isa.add(new ByteArrayInputStream(bytes));
......@@ -849,7 +848,7 @@ class Package implements Constants {
return new SequenceInputStream(Collections.enumeration(isa));
}
protected void visitRefs(int mode, Collection refs) {
protected void visitRefs(int mode, Collection<Entry> refs) {
assert(name != null);
refs.add(name);
}
......@@ -877,8 +876,8 @@ class Package implements Constants {
}
// Is there a globally declared table of inner classes?
ArrayList allInnerClasses = new ArrayList();
HashMap allInnerClassesByThis;
ArrayList<InnerClass> allInnerClasses = new ArrayList<>();
HashMap<ClassEntry, InnerClass> allInnerClassesByThis;
public
List getAllInnerClasses() {
......@@ -886,15 +885,14 @@ class Package implements Constants {
}
public
void setAllInnerClasses(Collection ics) {
void setAllInnerClasses(Collection<InnerClass> ics) {
assert(ics != allInnerClasses);
allInnerClasses.clear();
allInnerClasses.addAll(ics);
// Make an index:
allInnerClassesByThis = new HashMap(allInnerClasses.size());
for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) {
InnerClass ic = (InnerClass) i.next();
allInnerClassesByThis = new HashMap<>(allInnerClasses.size());
for (InnerClass ic : allInnerClasses) {
Object pic = allInnerClassesByThis.put(ic.thisClass, ic);
assert(pic == null); // caller must ensure key uniqueness!
}
......@@ -904,7 +902,7 @@ class Package implements Constants {
public
InnerClass getGlobalInnerClass(Entry thisClass) {
assert(thisClass instanceof ClassEntry);
return (InnerClass) allInnerClassesByThis.get(thisClass);
return allInnerClassesByThis.get(thisClass);
}
static
......@@ -963,7 +961,7 @@ class Package implements Constants {
return this.thisClass.compareTo(that.thisClass);
}
protected void visitRefs(int mode, Collection refs) {
protected void visitRefs(int mode, Collection<Entry> refs) {
refs.add(thisClass);
if (mode == VRM_CLASSIC || !predictable) {
// If the name can be demangled, the package omits
......@@ -980,7 +978,7 @@ class Package implements Constants {
// Helper for building InnerClasses attributes.
static private
void visitInnerClassRefs(Collection innerClasses, int mode, Collection refs) {
void visitInnerClassRefs(Collection innerClasses, int mode, Collection<Entry> refs) {
if (innerClasses == null) {
return; // no attribute; nothing to do
}
......@@ -1165,9 +1163,8 @@ class Package implements Constants {
}
}
protected void visitRefs(int mode, Collection refs) {
for (Iterator i = classes.iterator(); i.hasNext(); ) {
Class c = (Class)i.next();
protected void visitRefs(int mode, Collection<Entry> refs) {
for ( Class c : classes) {
c.visitRefs(mode, refs);
}
if (mode != VRM_CLASSIC) {
......@@ -1259,7 +1256,7 @@ class Package implements Constants {
}
// Use this before writing the package file.
void buildGlobalConstantPool(Set requiredEntries) {
void buildGlobalConstantPool(Set<Entry> requiredEntries) {
if (verbose > 1)
Utils.log.fine("Checking for unused CP entries");
requiredEntries.add(getRefString("")); // uconditionally present
......@@ -1291,9 +1288,8 @@ class Package implements Constants {
// Use this before writing the class files.
void ensureAllClassFiles() {
HashSet fileSet = new HashSet(files);
for (Iterator i = classes.iterator(); i.hasNext(); ) {
Class cls = (Class) i.next();
HashSet<File> fileSet = new HashSet<>(files);
for (Class cls : classes) {
// Add to the end of ths list:
if (!fileSet.contains(cls.file))
files.add(cls.file);
......
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,12 +25,11 @@
package com.sun.java.util.jar.pack;
import com.sun.java.util.jar.pack.Attribute.Layout;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
import java.io.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
/*
......@@ -41,31 +40,22 @@ import java.beans.PropertyChangeEvent;
*/
public class PackerImpl implements Pack200.Packer {
public class PackerImpl extends TLGlobals implements Pack200.Packer {
/**
* Constructs a Packer object and sets the initial state of
* the packer engines.
*/
public PackerImpl() {
_props = new PropMap();
//_props.getProperty() consults defaultProps invisibly.
//_props.putAll(defaultProps);
}
// Private stuff.
final PropMap _props;
public PackerImpl() {}
/**
* Get the set of options for the pack and unpack engines.
* @return A sorted association of option key strings to option values.
*/
public SortedMap properties() {
return _props;
public SortedMap<String, String> properties() {
return props;
}
//Driver routines
/**
......@@ -78,21 +68,22 @@ public class PackerImpl implements Pack200.Packer {
*/
public void pack(JarFile in, OutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null);
TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
TimeZone.getDefault();
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
? null
: TimeZone.getDefault();
try {
Utils.currentInstance.set(this);
if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) {
Utils.copyJarFile(in, out);
} else {
(new DoPack()).run(in, out);
in.close();
}
} finally {
Utils.currentInstance.set(null);
if (tz != null) TimeZone.setDefault(tz);
in.close();
}
}
......@@ -112,21 +103,20 @@ public class PackerImpl implements Pack200.Packer {
*/
public void pack(JarInputStream in, OutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null);
TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
TimeZone.getDefault();
try {
Utils.currentInstance.set(this);
if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) {
Utils.copyJarFile(in, out);
} else {
(new DoPack()).run(in, out);
in.close();
}
} finally {
Utils.currentInstance.set(null);
if (tz != null) TimeZone.setDefault(tz);
in.close();
}
}
/**
......@@ -134,7 +124,7 @@ public class PackerImpl implements Pack200.Packer {
* @param listener An object to be invoked when a property is changed.
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
_props.addListener(listener);
props.addListener(listener);
}
/**
......@@ -142,7 +132,7 @@ public class PackerImpl implements Pack200.Packer {
* @param listener The PropertyChange listener to be removed.
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
_props.removeListener(listener);
props.removeListener(listener);
}
......@@ -151,11 +141,11 @@ public class PackerImpl implements Pack200.Packer {
// The packer worker.
private class DoPack {
final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
{
_props.setInteger(Pack200.Packer.PROGRESS, 0);
if (verbose > 0) Utils.log.info(_props.toString());
props.setInteger(Pack200.Packer.PROGRESS, 0);
if (verbose > 0) Utils.log.info(props.toString());
}
// Here's where the bits are collected before getting packed:
......@@ -163,7 +153,7 @@ public class PackerImpl implements Pack200.Packer {
final String unknownAttrCommand;
{
String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
String uaMode = props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
if (!(Pack200.Packer.STRIP.equals(uaMode) ||
Pack200.Packer.PASS.equals(uaMode) ||
Pack200.Packer.ERROR.equals(uaMode))) {
......@@ -191,13 +181,12 @@ public class PackerImpl implements Pack200.Packer {
};
for (int i = 0; i < ctypes.length; i++) {
String pfx = keys[i];
Map map = _props.prefixMap(pfx);
for (Iterator j = map.keySet().iterator(); j.hasNext(); ) {
String key = (String) j.next();
Map<String, String> map = props.prefixMap(pfx);
for (String key : map.keySet()) {
assert(key.startsWith(pfx));
String name = key.substring(pfx.length());
String layout = _props.getProperty(key);
Object lkey = Attribute.keyForLookup(ctypes[i], name);
String layout = props.getProperty(key);
Layout lkey = Attribute.keyForLookup(ctypes[i], name);
if (Pack200.Packer.STRIP.equals(layout) ||
Pack200.Packer.PASS.equals(layout) ||
Pack200.Packer.ERROR.equals(layout)) {
......@@ -222,25 +211,25 @@ public class PackerImpl implements Pack200.Packer {
}
final boolean keepFileOrder
= _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
= props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
final boolean keepClassOrder
= _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
= props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
final boolean keepModtime
= Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
= Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME));
final boolean latestModtime
= Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
= Pack200.Packer.LATEST.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME));
final boolean keepDeflateHint
= Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT));
= Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.DEFLATE_HINT));
{
if (!keepModtime && !latestModtime) {
int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME);
int modtime = props.getTime(Pack200.Packer.MODIFICATION_TIME);
if (modtime != Constants.NO_MODTIME) {
pkg.default_modtime = modtime;
}
}
if (!keepDeflateHint) {
boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT);
boolean deflate_hint = props.getBoolean(Pack200.Packer.DEFLATE_HINT);
if (deflate_hint) {
pkg.default_options |= Constants.AO_DEFLATE_HINT;
}
......@@ -254,10 +243,10 @@ public class PackerImpl implements Pack200.Packer {
final long segmentLimit;
{
long limit;
if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
if (props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
limit = -1;
else
limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT);
limit = props.getLong(Pack200.Packer.SEGMENT_LIMIT);
limit = Math.min(Integer.MAX_VALUE, limit);
limit = Math.max(-1, limit);
if (limit == -1)
......@@ -265,10 +254,10 @@ public class PackerImpl implements Pack200.Packer {
segmentLimit = limit;
}
final List passFiles; // parsed pack.pass.file options
final List<String> passFiles; // parsed pack.pass.file options
{
// Which class files will be passed through?
passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX);
passFiles = props.getProperties(Pack200.Packer.PASS_FILE_PFX);
for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) {
String file = (String) i.next();
if (file == null) { i.remove(); continue; }
......@@ -283,28 +272,28 @@ public class PackerImpl implements Pack200.Packer {
{
// Fill in permitted range of major/minor version numbers.
int ver;
if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
pkg.min_class_majver = (short) ver;
if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
pkg.min_class_minver = (short) ver;
if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
pkg.max_class_majver = (short) ver;
if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
pkg.max_class_minver = (short) ver;
if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
if ((ver = props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
pkg.package_minver = (short) ver;
if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
if ((ver = props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
pkg.package_majver = (short) ver;
}
{
// Hook for testing: Forces use of special archive modes.
int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options");
int opt = props.getInteger(Utils.COM_PREFIX+"archive.options");
if (opt != 0)
pkg.default_options |= opt;
}
// (Done collecting options from _props.)
// (Done collecting options from props.)
boolean isClassFile(String name) {
if (!name.endsWith(".class")) return false;
......@@ -423,16 +412,18 @@ public class PackerImpl implements Pack200.Packer {
Package.File file = null;
// (5078608) : discount the resource files in META-INF
// from segment computation.
long inflen = (isMetaInfFile(name)) ? 0L :
inFile.getInputLength();
long inflen = (isMetaInfFile(name))
? 0L
: inFile.getInputLength();
if ((segmentSize += inflen) > segmentLimit) {
segmentSize -= inflen;
int nextCount = -1; // don't know; it's a stream
flushPartial(out, nextCount);
}
if (verbose > 1)
if (verbose > 1) {
Utils.log.fine("Reading " + name);
}
assert(je.isDirectory() == name.endsWith("/"));
......@@ -450,18 +441,18 @@ public class PackerImpl implements Pack200.Packer {
}
void run(JarFile in, OutputStream out) throws IOException {
List inFiles = scanJar(in);
List<InFile> inFiles = scanJar(in);
if (verbose > 0)
Utils.log.info("Reading " + inFiles.size() + " files...");
int numDone = 0;
for (Iterator i = inFiles.iterator(); i.hasNext(); ) {
InFile inFile = (InFile) i.next();
for (InFile inFile : inFiles) {
String name = inFile.name;
// (5078608) : discount the resource files completely from segmenting
long inflen = (isMetaInfFile(name)) ? 0L :
inFile.getInputLength() ;
long inflen = (isMetaInfFile(name))
? 0L
: inFile.getInputLength() ;
if ((segmentSize += inflen) > segmentLimit) {
segmentSize -= inflen;
// Estimate number of remaining segments:
......@@ -530,11 +521,11 @@ public class PackerImpl implements Pack200.Packer {
}
void flushPartial(OutputStream out, int nextCount) throws IOException {
if (pkg.files.size() == 0 && pkg.classes.size() == 0) {
if (pkg.files.isEmpty() && pkg.classes.isEmpty()) {
return; // do not flush an empty segment
}
flushPackage(out, Math.max(1, nextCount));
_props.setInteger(Pack200.Packer.PROGRESS, 25);
props.setInteger(Pack200.Packer.PROGRESS, 25);
// In case there will be another segment:
makeNextPackage();
segmentCount += 1;
......@@ -543,10 +534,10 @@ public class PackerImpl implements Pack200.Packer {
}
void flushAll(OutputStream out) throws IOException {
_props.setInteger(Pack200.Packer.PROGRESS, 50);
props.setInteger(Pack200.Packer.PROGRESS, 50);
flushPackage(out, 0);
out.flush();
_props.setInteger(Pack200.Packer.PROGRESS, 100);
props.setInteger(Pack200.Packer.PROGRESS, 100);
segmentCount += 1;
segmentTotalSize += segmentSize;
segmentSize = 0;
......@@ -582,11 +573,11 @@ public class PackerImpl implements Pack200.Packer {
pkg.trimStubs();
// Do some stripping, maybe.
if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug");
if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile");
if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant");
if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions");
if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
if (props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug");
if (props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile");
if (props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant");
if (props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions");
if (props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
// Must choose an archive version; PackageWriter does not.
if (pkg.package_majver <= 0) pkg.choosePackageVersion();
......@@ -606,11 +597,10 @@ public class PackerImpl implements Pack200.Packer {
}
}
List scanJar(JarFile jf) throws IOException {
List<InFile> scanJar(JarFile jf) throws IOException {
// Collect jar entries, preserving order.
List inFiles = new ArrayList();
for (Enumeration e = jf.entries(); e.hasMoreElements(); ) {
JarEntry je = (JarEntry) e.nextElement();
List<InFile> inFiles = new ArrayList<>();
for (JarEntry je : Collections.list(jf.entries())) {
InFile inFile = new InFile(jf, je);
assert(je.isDirectory() == inFile.name.endsWith("/"));
inFiles.add(inFile);
......
......@@ -91,7 +91,7 @@ class PropMap extends TreeMap {
String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)));
// The segment size is unlimited
props.put(Pack200.Packer.SEGMENT_LIMIT, "");
props.put(Pack200.Packer.SEGMENT_LIMIT, "-1");
// Preserve file ordering by default.
props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE);
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.java.util.jar.pack;
import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
/*
* @author ksrini
*/
/*
* This class provides a container to hold the global variables, for packer
* and unpacker instances. This is typically stashed away in a ThreadLocal,
* and the storage is destroyed upon completion. Therefore any local
* references to these members must be eliminated appropriately to prevent a
* memory leak.
*/
class TLGlobals {
// Global environment
final PropMap props;
// Needed by ConstantPool.java
private final Map<String, Utf8Entry> utf8Entries;
private final Map<String, ClassEntry> classEntries;
private final Map<Object, LiteralEntry> literalEntries;
private final Map<String, SignatureEntry> signatureEntries;
private final Map<String, DescriptorEntry> descriptorEntries;
private final Map<String, MemberEntry> memberEntries;
TLGlobals() {
utf8Entries = new HashMap<>();
classEntries = new HashMap<>();
literalEntries = new HashMap<>();
signatureEntries = new HashMap<>();
descriptorEntries = new HashMap<>();
memberEntries = new HashMap<>();
props = new PropMap();
}
SortedMap<Object, Object> getPropMap() {
return props;
}
Map<String, Utf8Entry> getUtf8Entries() {
return utf8Entries;
}
Map<String, ClassEntry> getClassEntries() {
return classEntries;
}
Map<Object, LiteralEntry> getLiteralEntries() {
return literalEntries;
}
Map<String, DescriptorEntry> getDescriptorEntries() {
return descriptorEntries;
}
Map<String, SignatureEntry> getSignatureEntries() {
return signatureEntries;
}
Map<String, MemberEntry> getMemberEntries() {
return memberEntries;
}
}
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -30,7 +30,6 @@ import java.util.jar.*;
import java.util.zip.*;
import java.io.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
/*
* Implementation of the Pack provider.
......@@ -40,7 +39,7 @@ import java.beans.PropertyChangeEvent;
*/
public class UnpackerImpl implements Pack200.Unpacker {
public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
/**
......@@ -48,7 +47,7 @@ public class UnpackerImpl implements Pack200.Unpacker {
* @param listener An object to be invoked when a property is changed.
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
_props.addListener(listener);
props.addListener(listener);
}
......@@ -57,25 +56,19 @@ public class UnpackerImpl implements Pack200.Unpacker {
* @param listener The PropertyChange listener to be removed.
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
_props.removeListener(listener);
props.removeListener(listener);
}
public UnpackerImpl() {
_props = new PropMap();
//_props.getProperty() consults defaultProps invisibly.
//_props.putAll(defaultProps);
}
public UnpackerImpl() {}
// Private stuff.
final PropMap _props;
/**
* Get the set of options for the pack and unpack engines.
* @return A sorted association of option key strings to option values.
*/
public SortedMap properties() {
return _props;
public SortedMap<String, String> properties() {
return props;
}
// Back-pointer to NativeUnpacker, when active.
......@@ -101,19 +94,20 @@ public class UnpackerImpl implements Pack200.Unpacker {
*/
public void unpack(InputStream in0, JarOutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null);
TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
TimeZone.getDefault();
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
? null
: TimeZone.getDefault();
try {
Utils.currentInstance.set(this);
if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
BufferedInputStream in = new BufferedInputStream(in0);
if (Utils.isJarMagic(Utils.readMagic(in))) {
if (verbose > 0)
Utils.log.info("Copying unpacked JAR file...");
Utils.copyJarFile(new JarInputStream(in), out);
} else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
} else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
(new DoUnpack()).run(in, out);
in.close();
Utils.markJarFile(out);
......@@ -142,36 +136,38 @@ public class UnpackerImpl implements Pack200.Unpacker {
// %%% Reconsider if native unpacker learns to memory-map the file.
FileInputStream instr = new FileInputStream(in);
unpack(instr, out);
if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
in.delete();
}
}
private class DoUnpack {
final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
{
_props.setInteger(Pack200.Unpacker.PROGRESS, 0);
props.setInteger(Pack200.Unpacker.PROGRESS, 0);
}
// Here's where the bits are read from disk:
final Package pkg = new Package();
final boolean keepModtime
= Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
= Pack200.Packer.KEEP.equals(
props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
final boolean keepDeflateHint
= Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
= Pack200.Packer.KEEP.equals(
props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
final int modtime;
final boolean deflateHint;
{
if (!keepModtime) {
modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
modtime = props.getTime(Utils.UNPACK_MODIFICATION_TIME);
} else {
modtime = pkg.default_modtime;
}
deflateHint = (keepDeflateHint) ? false :
_props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
}
// Checksum apparatus.
......@@ -181,7 +177,7 @@ public class UnpackerImpl implements Pack200.Unpacker {
public void run(BufferedInputStream in, JarOutputStream out) throws IOException {
if (verbose > 0) {
_props.list(System.out);
props.list(System.out);
}
for (int seg = 1; ; seg++) {
unpackSegment(in, out);
......@@ -194,25 +190,26 @@ public class UnpackerImpl implements Pack200.Unpacker {
}
private void unpackSegment(InputStream in, JarOutputStream out) throws IOException {
_props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
// Process the output directory or jar output.
new PackageReader(pkg, in).read();
if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug");
if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile");
_props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
if (props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug");
if (props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile");
props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
pkg.ensureAllClassFiles();
// Now write out the files.
HashSet classesToWrite = new HashSet(pkg.getClasses());
HashSet<Package.Class> classesToWrite = new HashSet<>(pkg.getClasses());
for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) {
Package.File file = (Package.File) i.next();
String name = file.nameString;
JarEntry je = new JarEntry(Utils.getJarEntryName(name));
boolean deflate;
deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) :
deflateHint;
deflate = (keepDeflateHint)
? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0))
: deflateHint;
boolean needCRC = !deflate; // STORE mode requires CRC
......@@ -250,7 +247,7 @@ public class UnpackerImpl implements Pack200.Unpacker {
Utils.log.info("Writing "+Utils.zeString((ZipEntry)je));
}
assert(classesToWrite.isEmpty());
_props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
pkg.reset(); // reset for the next segment, if any
}
}
......
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,6 +25,13 @@
package com.sun.java.util.jar.pack;
import com.sun.java.util.jar.pack.Attribute.Layout;
import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
......@@ -113,17 +120,46 @@ class Utils {
*/
static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200";
// Keep a TLS point to the current Packer or Unpacker.
// This makes it simpler to supply environmental options
// Keep a TLS point to the global data and environment.
// This makes it simpler to supply environmental options
// to the engine code, especially the native code.
static final ThreadLocal currentInstance = new ThreadLocal();
static final ThreadLocal<TLGlobals> currentInstance = new ThreadLocal<>();
// convenience methods to access the TL globals
static TLGlobals getTLGlobals() {
return currentInstance.get();
}
static Map<String, Utf8Entry> getUtf8Entries() {
return getTLGlobals().getUtf8Entries();
}
static Map<String, ClassEntry> getClassEntries() {
return getTLGlobals().getClassEntries();
}
static Map<Object, LiteralEntry> getLiteralEntries() {
return getTLGlobals().getLiteralEntries();
}
static Map<String, DescriptorEntry> getDescriptorEntries() {
return getTLGlobals().getDescriptorEntries();
}
static Map<String, SignatureEntry> getSignatureEntries() {
return getTLGlobals().getSignatureEntries();
}
static Map<String, MemberEntry> getMemberEntries() {
return getTLGlobals().getMemberEntries();
}
static PropMap currentPropMap() {
Object obj = currentInstance.get();
if (obj instanceof PackerImpl)
return ((PackerImpl)obj)._props;
return ((PackerImpl)obj).props;
if (obj instanceof UnpackerImpl)
return ((UnpackerImpl)obj)._props;
return ((UnpackerImpl)obj).props;
return null;
}
......
......@@ -813,7 +813,8 @@ public final class Connection implements Runnable {
try {
while (true) {
try {
inbuf = new byte[10];
// type and length (at most 128 octets for long form)
inbuf = new byte[129];
offset = 0;
seqlen = 0;
......
......@@ -470,7 +470,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
public AbstractStringBuilder append(CharSequence s, int start, int end) {
if (s == null)
s = "null";
if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
if ((start < 0) || (start > end) || (end > s.length()))
throw new IndexOutOfBoundsException(
"start " + start + ", end " + end + ", s.length() "
+ s.length());
......@@ -529,7 +529,8 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* or {@code offset+len > str.length}
*/
public AbstractStringBuilder append(char str[], int offset, int len) {
ensureCapacityInternal(count + len);
if (len > 0) // let arraycopy report AIOOBE for len < 0
ensureCapacityInternal(count + len);
System.arraycopy(str, offset, value, count, len);
count += len;
return this;
......
......@@ -413,6 +413,18 @@ class Thread implements Runnable {
tid = nextThreadID();
}
/**
* Throws CloneNotSupportedException as a Thread can not be meaningfully
* cloned. Construct a new Thread instead.
*
* @throws CloneNotSupportedException
* always
*/
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
/**
* Allocates a new {@code Thread} object. This constructor has the same
* effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
......
......@@ -200,7 +200,16 @@ public class Throwable implements Serializable {
* @serial
* @since 1.7
*/
private List<Throwable> suppressedExceptions = Collections.emptyList();
private List<Throwable> suppressedExceptions = null;
/*
* This field is lazily initialized when the first suppressed
* exception is added.
*
* OutOfMemoryError is preallocated in the VM for better OOM
* diagnosability during VM initialization. Constructor can't
* be not invoked. If a new field to be added in the future must
* be initialized to non-null, it requires a synchronized VM change.
*/
/** Message for trying to suppress a null exception. */
private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
......@@ -329,7 +338,7 @@ public class Throwable implements Serializable {
* cause is nonexistent or unknown.
* @since 1.4
*/
public Throwable getCause() {
public synchronized Throwable getCause() {
return (cause==this ? null : cause);
}
......@@ -563,7 +572,7 @@ public class Throwable implements Serializable {
s.println("\tat " + traceElement);
// Print suppressed exceptions, if any
for (Throwable se : suppressedExceptions)
for (Throwable se : getSuppressedExceptions())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
// Print cause, if any
......@@ -604,7 +613,7 @@ public class Throwable implements Serializable {
s.println(prefix + "\t... " + framesInCommon + " more");
// Print suppressed exceptions, if any
for (Throwable se : suppressedExceptions)
for (Throwable se : getSuppressedExceptions())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
prefix +"\t", dejaVu);
......@@ -747,7 +756,9 @@ public class Throwable implements Serializable {
if (defensiveCopy[i] == null)
throw new NullPointerException("stackTrace[" + i + "]");
this.stackTrace = defensiveCopy;
synchronized (this) {
this.stackTrace = defensiveCopy;
}
}
/**
......@@ -772,11 +783,11 @@ public class Throwable implements Serializable {
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields
List<Throwable> suppressed = Collections.emptyList();
List<Throwable> suppressed = null;
if (suppressedExceptions != null &&
!suppressedExceptions.isEmpty()) { // Copy Throwables to new list
suppressed = new ArrayList<Throwable>();
for(Throwable t : suppressedExceptions) {
for (Throwable t : suppressedExceptions) {
if (t == null)
throw new NullPointerException(NULL_CAUSE_MESSAGE);
suppressed.add(t);
......@@ -819,7 +830,7 @@ public class Throwable implements Serializable {
if (exception == this)
throw new IllegalArgumentException("Self-suppression not permitted");
if (suppressedExceptions.size() == 0)
if (suppressedExceptions == null)
suppressedExceptions = new ArrayList<Throwable>();
suppressedExceptions.add(exception);
}
......@@ -835,7 +846,10 @@ public class Throwable implements Serializable {
* suppressed to deliver this exception.
* @since 1.7
*/
public Throwable[] getSuppressedExceptions() {
return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
public synchronized Throwable[] getSuppressedExceptions() {
if (suppressedExceptions == null)
return EMPTY_THROWABLE_ARRAY;
else
return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
}
}
......@@ -1093,14 +1093,8 @@ public final class HttpCookie implements Cloneable {
return sb.toString();
}
private static SimpleDateFormat[] cDateFormats = null;
static {
cDateFormats = new SimpleDateFormat[COOKIE_DATE_FORMATS.length];
for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
cDateFormats[i] = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US);
cDateFormats[i].setTimeZone(TimeZone.getTimeZone("GMT"));
}
}
static final TimeZone GMT = TimeZone.getTimeZone("GMT");
/*
* @param dateString a date string in one of the formats
* defined in Netscape cookie spec
......@@ -1109,12 +1103,14 @@ public final class HttpCookie implements Cloneable {
* time and the time specified by dateString
*/
private long expiryDate2DeltaSeconds(String dateString) {
for (SimpleDateFormat df : cDateFormats) {
for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US);
df.setTimeZone(GMT);
try {
Date date = df.parse(dateString);
return (date.getTime() - whenCreated) / 1000;
} catch (Exception e) {
// Ignore, try the next date format
}
}
return 0;
......
......@@ -856,9 +856,7 @@ public final class URI
try {
return new URI(str);
} catch (URISyntaxException x) {
IllegalArgumentException y = new IllegalArgumentException();
y.initCause(x);
throw y;
throw new IllegalArgumentException(x.getMessage(), x);
}
}
......
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2010, 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
......@@ -131,17 +131,19 @@ import javax.security.auth.callback.*;
* to read existing entries from the keystore, or to write new entries
* into the keystore:
* <pre>
* KeyStore.ProtectionParameter protParam =
* new KeyStore.PasswordProtection(password);
*
* // get my private key
* KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
* ks.getEntry("privateKeyAlias", password);
* ks.getEntry("privateKeyAlias", protParam);
* PrivateKey myPrivateKey = pkEntry.getPrivateKey();
*
* // save my secret key
* javax.crypto.SecretKey mySecretKey;
* KeyStore.SecretKeyEntry skEntry =
* new KeyStore.SecretKeyEntry(mySecretKey);
* ks.setEntry("secretKeyAlias", skEntry,
* new KeyStore.PasswordProtection(password));
* ks.setEntry("secretKeyAlias", skEntry, protParam);
*
* // store away the keystore
* java.io.FileOutputStream fos = null;
......
......@@ -103,27 +103,46 @@ public class Date extends java.util.Date {
* JDBC date escape format (yyyy-mm-dd)
*/
public static Date valueOf(String s) {
int year;
int month;
int day;
final int YEAR_LENGTH = 4;
final int MONTH_LENGTH = 2;
final int DAY_LENGTH = 2;
final int MAX_MONTH = 12;
final int MAX_DAY = 31;
int firstDash;
int secondDash;
Date d = null;
if (s == null) throw new java.lang.IllegalArgumentException();
if (s == null) {
throw new java.lang.IllegalArgumentException();
}
firstDash = s.indexOf('-');
secondDash = s.indexOf('-', firstDash+1);
if ((firstDash > 0) & (secondDash > 0) & (secondDash < s.length()-1)) {
year = Integer.parseInt(s.substring(0, firstDash)) - 1900;
month = Integer.parseInt(s.substring(firstDash+1, secondDash)) - 1;
day = Integer.parseInt(s.substring(secondDash+1));
} else {
secondDash = s.indexOf('-', firstDash + 1);
if ((firstDash > 0) && (secondDash > 0) && (secondDash < s.length() - 1)) {
String yyyy = s.substring(0, firstDash);
String mm = s.substring(firstDash + 1, secondDash);
String dd = s.substring(secondDash + 1);
if (yyyy.length() == YEAR_LENGTH && mm.length() == MONTH_LENGTH &&
dd.length() == DAY_LENGTH) {
int year = Integer.parseInt(yyyy);
int month = Integer.parseInt(mm);
int day = Integer.parseInt(dd);
if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
d = new Date(year - 1900, month - 1, day);
}
}
}
if (d == null) {
throw new java.lang.IllegalArgumentException();
}
return new Date(year, month, day);
return d;
}
/**
* Formats a date in the date escape format yyyy-mm-dd.
* <P>
......
......@@ -59,7 +59,7 @@ public class FileURLConnection extends URLConnection {
String filename;
boolean isDirectory = false;
boolean exists = false;
List files;
List<String> files;
long length = -1;
long lastModified = 0;
......@@ -81,7 +81,10 @@ public class FileURLConnection extends URLConnection {
filename = file.toString();
isDirectory = file.isDirectory();
if (isDirectory) {
files = (List) Arrays.asList(file.list());
String[] fileList = file.list();
if (fileList == null)
throw new FileNotFoundException(filename + " exists, but is not accessible");
files = Arrays.<String>asList(fileList);
} else {
is = new BufferedInputStream(new FileInputStream(filename));
......@@ -197,7 +200,7 @@ public class FileURLConnection extends URLConnection {
Collections.sort(files, Collator.getInstance());
for (int i = 0 ; i < files.size() ; i++) {
String fileName = (String)files.get(i);
String fileName = files.get(i);
buf.append(fileName);
buf.append("\n");
}
......
......@@ -1768,6 +1768,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
// Not really necessary for a tunnel, but can't hurt
requests.setIfNotSet("Accept", acceptString);
if (http.getHttpKeepAliveSet()) {
requests.setIfNotSet("Proxy-Connection", "keep-alive");
}
setPreemptiveProxyAuthentication(requests);
/* Log the CONNECT request */
......
......@@ -536,9 +536,11 @@ class DatagramChannelImpl
}
}
private long read0(ByteBuffer[] bufs) throws IOException {
if (bufs == null)
throw new NullPointerException();
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
synchronized (readLock) {
synchronized (stateLock) {
ensureOpen();
......@@ -552,7 +554,7 @@ class DatagramChannelImpl
return 0;
readerThread = NativeThread.current();
do {
n = IOUtil.read(fd, bufs, nd);
n = IOUtil.read(fd, dsts, offset, length, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
......@@ -563,15 +565,6 @@ class DatagramChannelImpl
}
}
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
// ## Fix IOUtil.write so that we can avoid this array copy
return read0(Util.subsequence(dsts, offset, length));
}
public int write(ByteBuffer buf) throws IOException {
if (buf == null)
throw new NullPointerException();
......@@ -599,9 +592,11 @@ class DatagramChannelImpl
}
}
private long write0(ByteBuffer[] bufs) throws IOException {
if (bufs == null)
throw new NullPointerException();
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
synchronized (writeLock) {
synchronized (stateLock) {
ensureOpen();
......@@ -615,7 +610,7 @@ class DatagramChannelImpl
return 0;
writerThread = NativeThread.current();
do {
n = IOUtil.write(fd, bufs, nd);
n = IOUtil.write(fd, srcs, offset, length, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
......@@ -626,15 +621,6 @@ class DatagramChannelImpl
}
}
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
// ## Fix IOUtil.write so that we can avoid this array copy
return write0(Util.subsequence(srcs, offset, length));
}
protected void implConfigureBlocking(boolean block) throws IOException {
IOUtil.configureBlocking(fd, block);
}
......
......@@ -143,7 +143,11 @@ public class FileChannelImpl
}
}
private long read0(ByteBuffer[] dsts) throws IOException {
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
ensureOpen();
if (!readable)
throw new NonReadableChannelException();
......@@ -156,7 +160,7 @@ public class FileChannelImpl
if (!isOpen())
return 0;
do {
n = IOUtil.read(fd, dsts, nd);
n = IOUtil.read(fd, dsts, offset, length, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
......@@ -167,15 +171,6 @@ public class FileChannelImpl
}
}
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
// ## Fix IOUtil.write so that we can avoid this array copy
return read0(Util.subsequence(dsts, offset, length));
}
public int write(ByteBuffer src) throws IOException {
ensureOpen();
if (!writable)
......@@ -200,7 +195,11 @@ public class FileChannelImpl
}
}
private long write0(ByteBuffer[] srcs) throws IOException {
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
ensureOpen();
if (!writable)
throw new NonWritableChannelException();
......@@ -213,7 +212,7 @@ public class FileChannelImpl
if (!isOpen())
return 0;
do {
n = IOUtil.write(fd, srcs, nd);
n = IOUtil.write(fd, srcs, offset, length, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
......@@ -224,16 +223,6 @@ public class FileChannelImpl
}
}
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
// ## Fix IOUtil.write so that we can avoid this array copy
return write0(Util.subsequence(srcs, offset, length));
}
// -- Other operations --
public long position() throws IOException {
......@@ -440,24 +429,45 @@ public class FileChannelImpl
}
}
private long transferToTrustedChannel(long position, int icount,
// Maximum size to map when using a mapped buffer
private static final long MAPPED_TRANSFER_SIZE = 8L*1024L*1024L;
private long transferToTrustedChannel(long position, long count,
WritableByteChannel target)
throws IOException
{
if ( !((target instanceof FileChannelImpl)
|| (target instanceof SelChImpl)))
boolean isSelChImpl = (target instanceof SelChImpl);
if (!((target instanceof FileChannelImpl) || isSelChImpl))
return IOStatus.UNSUPPORTED;
// Trusted target: Use a mapped buffer
MappedByteBuffer dbb = null;
try {
dbb = map(MapMode.READ_ONLY, position, icount);
// ## Bug: Closing this channel will not terminate the write
return target.write(dbb);
} finally {
if (dbb != null)
unmap(dbb);
long remaining = count;
while (remaining > 0L) {
long size = Math.min(remaining, MAPPED_TRANSFER_SIZE);
try {
MappedByteBuffer dbb = map(MapMode.READ_ONLY, position, size);
try {
// ## Bug: Closing this channel will not terminate the write
int n = target.write(dbb);
assert n >= 0;
remaining -= n;
if (isSelChImpl) {
// one attempt to write to selectable channel
break;
}
assert n > 0;
position += n;
} finally {
unmap(dbb);
}
} catch (IOException ioe) {
// Only throw exception if no bytes have been written
if (remaining == count)
throw ioe;
break;
}
}
return count - remaining;
}
private long transferToArbitraryChannel(long position, int icount,
......@@ -535,20 +545,34 @@ public class FileChannelImpl
long position, long count)
throws IOException
{
// Note we could loop here to accumulate more at once
synchronized (src.positionLock) {
long p = src.position();
int icount = (int)Math.min(Math.min(count, Integer.MAX_VALUE),
src.size() - p);
// ## Bug: Closing this channel will not terminate the write
MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, icount);
try {
long n = write(bb, position);
src.position(p + n);
return n;
} finally {
unmap(bb);
long pos = src.position();
long max = Math.min(count, src.size() - pos);
long remaining = max;
long p = pos;
while (remaining > 0L) {
long size = Math.min(remaining, MAPPED_TRANSFER_SIZE);
// ## Bug: Closing this channel will not terminate the write
MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, size);
try {
long n = write(bb, position);
assert n > 0;
p += n;
position += n;
remaining -= n;
} catch (IOException ioe) {
// Only throw exception if no bytes have been written
if (remaining == max)
throw ioe;
break;
} finally {
unmap(bb);
}
}
long nwritten = max - remaining;
src.position(pos + nwritten);
return nwritten;
}
}
......
......@@ -38,34 +38,6 @@ class IOUtil {
private IOUtil() { } // No instantiation
/*
* Returns the index of first buffer in bufs with remaining,
* or -1 if there is nothing left
*/
private static int remaining(ByteBuffer[] bufs) {
int numBufs = bufs.length;
for (int i=0; i<numBufs; i++) {
if (bufs[i].hasRemaining()) {
return i;
}
}
return -1;
}
/*
* Returns a new ByteBuffer array with only unfinished buffers in it
*/
private static ByteBuffer[] skipBufs(ByteBuffer[] bufs,
int nextWithRemaining)
{
int newSize = bufs.length - nextWithRemaining;
ByteBuffer[] temp = new ByteBuffer[newSize];
for (int i=0; i<newSize; i++) {
temp[i] = bufs[i + nextWithRemaining];
}
return temp;
}
static int write(FileDescriptor fd, ByteBuffer src, long position,
NativeDispatcher nd, Object lock)
throws IOException
......@@ -93,7 +65,7 @@ class IOUtil {
}
return n;
} finally {
Util.releaseTemporaryDirectBuffer(bb);
Util.offerFirstTemporaryDirectBuffer(bb);
}
}
......@@ -125,88 +97,81 @@ class IOUtil {
static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
throws IOException
{
int nextWithRemaining = remaining(bufs);
// if all bufs are empty we should return immediately
if (nextWithRemaining < 0)
return 0;
// If some bufs are empty we should skip them
if (nextWithRemaining > 0)
bufs = skipBufs(bufs, nextWithRemaining);
return write(fd, bufs, 0, bufs.length, nd);
}
int numBufs = bufs.length;
static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
NativeDispatcher nd)
throws IOException
{
IOVecWrapper vec = IOVecWrapper.get(length);
// Create shadow to ensure DirectByteBuffers are used
ByteBuffer[] shadow = new ByteBuffer[numBufs];
boolean completed = false;
int iov_len = 0;
try {
for (int i=0; i<numBufs; i++) {
if (!(bufs[i] instanceof DirectBuffer)) {
int pos = bufs[i].position();
int lim = bufs[i].limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
shadow[i] = bb;
// Leave slow buffer position untouched; it will be updated
// after we see how many bytes were really written out
bb.put(bufs[i]);
bufs[i].position(pos);
bb.flip();
} else {
shadow[i] = bufs[i];
}
}
IOVecWrapper vec = null;
long bytesWritten = 0;
try {
// Create a native iovec array
vec= new IOVecWrapper(numBufs);
// Fill in the iovec array with appropriate data
for (int i=0; i<numBufs; i++) {
ByteBuffer nextBuffer = shadow[i];
// put in the buffer addresses
long pos = nextBuffer.position();
long len = nextBuffer.limit() - pos;
vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
vec.putLen(i, len);
}
// Iterate over buffers to populate native iovec array.
int count = offset + length;
for (int i=offset; i<count; i++) {
ByteBuffer buf = bufs[i];
int pos = buf.position();
int lim = buf.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
if (rem > 0) {
vec.setBuffer(iov_len, buf, pos, rem);
// allocate shadow buffer to ensure I/O is done with direct buffer
if (!(buf instanceof DirectBuffer)) {
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
shadow.put(buf);
shadow.flip();
vec.setShadow(iov_len, shadow);
buf.position(pos); // temporarily restore position in user buffer
buf = shadow;
pos = shadow.position();
}
// Invoke native call to fill the buffers
bytesWritten = nd.writev(fd, vec.address, numBufs);
} finally {
vec.free();
vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos);
vec.putLen(iov_len, rem);
iov_len++;
}
}
long returnVal = bytesWritten;
if (iov_len == 0)
return 0L;
long bytesWritten = nd.writev(fd, vec.address, iov_len);
// Notify the buffers how many bytes were taken
for (int i=0; i<numBufs; i++) {
ByteBuffer nextBuffer = bufs[i];
int pos = nextBuffer.position();
int lim = nextBuffer.limit();
assert (pos <= lim);
int len = (pos <= lim ? lim - pos : lim);
if (bytesWritten >= len) {
bytesWritten -= len;
int newPosition = pos + len;
nextBuffer.position(newPosition);
} else { // Buffers not completely filled
if (bytesWritten > 0) {
assert(pos + bytesWritten < (long)Integer.MAX_VALUE);
int newPosition = (int)(pos + bytesWritten);
nextBuffer.position(newPosition);
}
break;
long left = bytesWritten;
for (int j=0; j<iov_len; j++) {
if (left > 0) {
ByteBuffer buf = vec.getBuffer(j);
int pos = vec.getPosition(j);
int rem = vec.getRemaining(j);
int n = (left > rem) ? rem : (int)left;
buf.position(pos + n);
left -= n;
}
// return shadow buffers to buffer pool
ByteBuffer shadow = vec.getShadow(j);
if (shadow != null)
Util.offerLastTemporaryDirectBuffer(shadow);
vec.clearRefs(j);
}
return returnVal;
completed = true;
return bytesWritten;
} finally {
// return any substituted buffers to cache
for (int i=0; i<numBufs; i++) {
ByteBuffer bb = shadow[i];
if (bb != null && bb != bufs[i]) {
Util.releaseTemporaryDirectBuffer(bb);
// if an error occurred then clear refs to buffers and return any shadow
// buffers to cache
if (!completed) {
for (int j=0; j<iov_len; j++) {
ByteBuffer shadow = vec.getShadow(j);
if (shadow != null)
Util.offerLastTemporaryDirectBuffer(shadow);
vec.clearRefs(j);
}
}
}
......@@ -231,7 +196,7 @@ class IOUtil {
dst.put(bb);
return n;
} finally {
Util.releaseTemporaryDirectBuffer(bb);
Util.offerFirstTemporaryDirectBuffer(bb);
}
}
......@@ -262,92 +227,85 @@ class IOUtil {
static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
throws IOException
{
int nextWithRemaining = remaining(bufs);
// if all bufs are empty we should return immediately
if (nextWithRemaining < 0)
return 0;
// If some bufs are empty we should skip them
if (nextWithRemaining > 0)
bufs = skipBufs(bufs, nextWithRemaining);
return read(fd, bufs, 0, bufs.length, nd);
}
int numBufs = bufs.length;
static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
NativeDispatcher nd)
throws IOException
{
IOVecWrapper vec = IOVecWrapper.get(length);
// Read into the shadow to ensure DirectByteBuffers are used
ByteBuffer[] shadow = new ByteBuffer[numBufs];
boolean usingSlowBuffers = false;
boolean completed = false;
int iov_len = 0;
try {
for (int i=0; i<numBufs; i++) {
if (bufs[i].isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
if (!(bufs[i] instanceof DirectBuffer)) {
shadow[i] = Util.getTemporaryDirectBuffer(bufs[i].remaining());
usingSlowBuffers = true;
} else {
shadow[i] = bufs[i];
}
}
IOVecWrapper vec = null;
long bytesRead = 0;
try {
// Create a native iovec array
vec = new IOVecWrapper(numBufs);
// Fill in the iovec array with appropriate data
for (int i=0; i<numBufs; i++) {
ByteBuffer nextBuffer = shadow[i];
// put in the buffer addresses
long pos = nextBuffer.position();
long len = nextBuffer.remaining();
vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
vec.putLen(i, len);
}
// Iterate over buffers to populate native iovec array.
int count = offset + length;
for (int i=offset; i<count; i++) {
ByteBuffer buf = bufs[i];
if (buf.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
int pos = buf.position();
int lim = buf.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
// Invoke native call to fill the buffers
bytesRead = nd.readv(fd, vec.address, numBufs);
} finally {
vec.free();
}
long returnVal = bytesRead;
if (rem > 0) {
vec.setBuffer(iov_len, buf, pos, rem);
// Notify the buffers how many bytes were read
for (int i=0; i<numBufs; i++) {
ByteBuffer nextBuffer = shadow[i];
// Note: should this have been cached from above?
int pos = nextBuffer.position();
int len = nextBuffer.remaining();
if (bytesRead >= len) {
bytesRead -= len;
int newPosition = pos + len;
nextBuffer.position(newPosition);
} else { // Buffers not completely filled
if (bytesRead > 0) {
assert(pos + bytesRead < (long)Integer.MAX_VALUE);
int newPosition = (int)(pos + bytesRead);
nextBuffer.position(newPosition);
// allocate shadow buffer to ensure I/O is done with direct buffer
if (!(buf instanceof DirectBuffer)) {
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
vec.setShadow(iov_len, shadow);
buf = shadow;
pos = shadow.position();
}
break;
vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos);
vec.putLen(iov_len, rem);
iov_len++;
}
}
if (iov_len == 0)
return 0L;
// Put results from shadow into the slow buffers
if (usingSlowBuffers) {
for (int i=0; i<numBufs; i++) {
if (!(bufs[i] instanceof DirectBuffer)) {
shadow[i].flip();
bufs[i].put(shadow[i]);
long bytesRead = nd.readv(fd, vec.address, iov_len);
// Notify the buffers how many bytes were read
long left = bytesRead;
for (int j=0; j<iov_len; j++) {
ByteBuffer shadow = vec.getShadow(j);
if (left > 0) {
ByteBuffer buf = vec.getBuffer(j);
int rem = vec.getRemaining(j);
int n = (left > rem) ? rem : (int)left;
if (shadow == null) {
int pos = vec.getPosition(j);
buf.position(pos + n);
} else {
shadow.limit(shadow.position() + n);
buf.put(shadow);
}
left -= n;
}
if (shadow != null)
Util.offerLastTemporaryDirectBuffer(shadow);
vec.clearRefs(j);
}
return returnVal;
completed = true;
return bytesRead;
} finally {
// return any substituted buffers to cache
if (usingSlowBuffers) {
for (int i=0; i<numBufs; i++) {
ByteBuffer bb = shadow[i];
if (bb != null && bb != bufs[i]) {
Util.releaseTemporaryDirectBuffer(bb);
}
// if an error occurred then clear refs to buffers and return any shadow
// buffers to cache
if (!completed) {
for (int j=0; j<iov_len; j++) {
ByteBuffer shadow = vec.getShadow(j);
if (shadow != null)
Util.offerLastTemporaryDirectBuffer(shadow);
vec.clearRefs(j);
}
}
}
......
......@@ -25,6 +25,7 @@
package sun.nio.ch;
import java.nio.ByteBuffer;
import sun.misc.*;
......@@ -43,23 +44,98 @@ import sun.misc.*;
class IOVecWrapper {
// Miscellaneous constants
static int BASE_OFFSET = 0;
static int LEN_OFFSET;
static int SIZE_IOVEC;
private static final int BASE_OFFSET = 0;
private static final int LEN_OFFSET;
private static final int SIZE_IOVEC;
// The iovec array
private AllocatedNativeObject vecArray;
private final AllocatedNativeObject vecArray;
// Number of elements in iovec array
private final int size;
// Buffers and position/remaining corresponding to elements in iovec array
private final ByteBuffer[] buf;
private final int[] position;
private final int[] remaining;
// Shadow buffers for cases when original buffer is substituted
private final ByteBuffer[] shadow;
// Base address of this array
long address;
final long address;
// Address size in bytes
static int addressSize;
IOVecWrapper(int newSize) {
newSize = (newSize + 1) * SIZE_IOVEC;
vecArray = new AllocatedNativeObject(newSize, false);
address = vecArray.address();
private static class Deallocator implements Runnable {
private final AllocatedNativeObject obj;
Deallocator(AllocatedNativeObject obj) {
this.obj = obj;
}
public void run() {
obj.free();
}
}
// per thread IOVecWrapper
private static final ThreadLocal<IOVecWrapper> cached =
new ThreadLocal<IOVecWrapper>();
private IOVecWrapper(int size) {
this.size = size;
this.buf = new ByteBuffer[size];
this.position = new int[size];
this.remaining = new int[size];
this.shadow = new ByteBuffer[size];
this.vecArray = new AllocatedNativeObject(size * SIZE_IOVEC, false);
this.address = vecArray.address();
}
static IOVecWrapper get(int size) {
IOVecWrapper wrapper = cached.get();
if (wrapper != null && wrapper.size < size) {
// not big enough; eagerly release memory
wrapper.vecArray.free();
wrapper = null;
}
if (wrapper == null) {
wrapper = new IOVecWrapper(size);
Cleaner.create(wrapper, new Deallocator(wrapper.vecArray));
cached.set(wrapper);
}
return wrapper;
}
void setBuffer(int i, ByteBuffer buf, int pos, int rem) {
this.buf[i] = buf;
this.position[i] = pos;
this.remaining[i] = rem;
}
void setShadow(int i, ByteBuffer buf) {
shadow[i] = buf;
}
ByteBuffer getBuffer(int i) {
return buf[i];
}
int getPosition(int i) {
return position[i];
}
int getRemaining(int i) {
return remaining[i];
}
ByteBuffer getShadow(int i) {
return shadow[i];
}
void clearRefs(int i) {
buf[i] = null;
shadow[i] = null;
}
void putBase(int i, long base) {
......@@ -78,10 +154,6 @@ class IOVecWrapper {
vecArray.putLong(offset, len);
}
void free() {
vecArray.free();
}
static {
addressSize = Util.unsafe().addressSize();
LEN_OFFSET = addressSize;
......
......@@ -385,9 +385,11 @@ class SocketChannelImpl
}
}
private long read0(ByteBuffer[] bufs) throws IOException {
if (bufs == null)
throw new NullPointerException();
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
synchronized (readLock) {
if (!ensureReadOpen())
return -1;
......@@ -401,7 +403,7 @@ class SocketChannelImpl
}
for (;;) {
n = IOUtil.read(fd, bufs, nd);
n = IOUtil.read(fd, dsts, offset, length, nd);
if ((n == IOStatus.INTERRUPTED) && isOpen())
continue;
return IOStatus.normalize(n);
......@@ -418,15 +420,6 @@ class SocketChannelImpl
}
}
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
// ## Fix IOUtil.write so that we can avoid this array copy
return read0(Util.subsequence(dsts, offset, length));
}
public int write(ByteBuffer buf) throws IOException {
if (buf == null)
throw new NullPointerException();
......@@ -458,9 +451,11 @@ class SocketChannelImpl
}
}
public long write0(ByteBuffer[] bufs) throws IOException {
if (bufs == null)
throw new NullPointerException();
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
synchronized (writeLock) {
ensureWriteOpen();
long n = 0;
......@@ -472,7 +467,7 @@ class SocketChannelImpl
writerThread = NativeThread.current();
}
for (;;) {
n = IOUtil.write(fd, bufs, nd);
n = IOUtil.write(fd, srcs, offset, length, nd);
if ((n == IOStatus.INTERRUPTED) && isOpen())
continue;
return IOStatus.normalize(n);
......@@ -489,15 +484,6 @@ class SocketChannelImpl
}
}
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
// ## Fix IOUtil.write so that we can avoid this array copy
return write0(Util.subsequence(srcs, offset, length));
}
// package-private
int sendOutOfBandData(byte b) throws IOException {
synchronized (writeLock) {
......
......@@ -41,67 +41,180 @@ import sun.security.action.GetPropertyAction;
class Util {
// -- Caches --
// The number of temp buffers in our pool
private static final int TEMP_BUF_POOL_SIZE = 3;
private static final int TEMP_BUF_POOL_SIZE = 8;
// Per-thread soft cache of the last temporary direct buffer
private static ThreadLocal<SoftReference<ByteBuffer>>[] bufferPool;
// Per-thread cache of temporary direct buffers
private static ThreadLocal<BufferCache> bufferCache =
new ThreadLocal<BufferCache>()
{
@Override
protected BufferCache initialValue() {
return new BufferCache();
}
};
@SuppressWarnings("unchecked")
static ThreadLocal<SoftReference<ByteBuffer>>[] createThreadLocalBufferPool() {
return new ThreadLocal[TEMP_BUF_POOL_SIZE];
}
/**
* A simple cache of direct buffers.
*/
private static class BufferCache {
// the array of buffers
private ByteBuffer[] buffers;
// the number of buffers in the cache
private int count;
// the index of the first valid buffer (undefined if count == 0)
private int start;
private int next(int i) {
return (i + 1) % TEMP_BUF_POOL_SIZE;
}
BufferCache() {
buffers = new ByteBuffer[TEMP_BUF_POOL_SIZE];
}
static {
bufferPool = createThreadLocalBufferPool();
for (int i=0; i<TEMP_BUF_POOL_SIZE; i++)
bufferPool[i] = new ThreadLocal<SoftReference<ByteBuffer>>();
/**
* Removes and returns a buffer from the cache of at least the given
* size (or null if no suitable buffer is found).
*/
ByteBuffer get(int size) {
if (count == 0)
return null; // cache is empty
ByteBuffer[] buffers = this.buffers;
// search for suitable buffer (often the first buffer will do)
ByteBuffer buf = buffers[start];
if (buf.capacity() < size) {
buf = null;
int i = start;
while ((i = next(i)) != start) {
ByteBuffer bb = buffers[i];
if (bb == null)
break;
if (bb.capacity() >= size) {
buf = bb;
break;
}
}
if (buf == null)
return null;
// move first element to here to avoid re-packing
buffers[i] = buffers[start];
}
// remove first element
buffers[start] = null;
start = next(start);
count--;
// prepare the buffer and return it
buf.rewind();
buf.limit(size);
return buf;
}
boolean offerFirst(ByteBuffer buf) {
if (count >= TEMP_BUF_POOL_SIZE) {
return false;
} else {
start = (start + TEMP_BUF_POOL_SIZE - 1) % TEMP_BUF_POOL_SIZE;
buffers[start] = buf;
count++;
return true;
}
}
boolean offerLast(ByteBuffer buf) {
if (count >= TEMP_BUF_POOL_SIZE) {
return false;
} else {
int next = (start + count) % TEMP_BUF_POOL_SIZE;
buffers[next] = buf;
count++;
return true;
}
}
boolean isEmpty() {
return count == 0;
}
ByteBuffer removeFirst() {
assert count > 0;
ByteBuffer buf = buffers[start];
buffers[start] = null;
start = next(start);
count--;
return buf;
}
}
/**
* Returns a temporary buffer of at least the given size
*/
static ByteBuffer getTemporaryDirectBuffer(int size) {
ByteBuffer buf = null;
// Grab a buffer if available
for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
SoftReference<ByteBuffer> ref = bufferPool[i].get();
if ((ref != null) && ((buf = ref.get()) != null) &&
(buf.capacity() >= size)) {
buf.rewind();
buf.limit(size);
bufferPool[i].set(null);
return buf;
BufferCache cache = bufferCache.get();
ByteBuffer buf = cache.get(size);
if (buf != null) {
return buf;
} else {
// No suitable buffer in the cache so we need to allocate a new
// one. To avoid the cache growing then we remove the first
// buffer from the cache and free it.
if (!cache.isEmpty()) {
buf = cache.removeFirst();
free(buf);
}
return ByteBuffer.allocateDirect(size);
}
// Make a new one
return ByteBuffer.allocateDirect(size);
}
/**
* Releases a temporary buffer by returning to the cache or freeing it.
*/
static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
if (buf == null)
return;
// Put it in an empty slot if such exists
for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
SoftReference<ByteBuffer> ref = bufferPool[i].get();
if ((ref == null) || (ref.get() == null)) {
bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
return;
}
offerFirstTemporaryDirectBuffer(buf);
}
/**
* Releases a temporary buffer by returning to the cache or freeing it. If
* returning to the cache then insert it at the start so that it is
* likely to be returned by a subsequent call to getTemporaryDirectBuffer.
*/
static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) {
assert buf != null;
BufferCache cache = bufferCache.get();
if (!cache.offerFirst(buf)) {
// cache is full
free(buf);
}
// Otherwise replace a smaller one in the cache if such exists
for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
SoftReference<ByteBuffer> ref = bufferPool[i].get();
ByteBuffer inCacheBuf = ref.get();
if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) {
bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
return;
}
}
/**
* Releases a temporary buffer by returning to the cache or freeing it. If
* returning to the cache then insert it at the end. This makes it
* suitable for scatter/gather operations where the buffers are returned to
* cache in same order that they were obtained.
*/
static void offerLastTemporaryDirectBuffer(ByteBuffer buf) {
assert buf != null;
BufferCache cache = bufferCache.get();
if (!cache.offerLast(buf)) {
// cache is full
free(buf);
}
}
// release memory
((DirectBuffer)buf).cleaner().clean();
/**
* Frees the memory for the given direct buffer
*/
private static void free(ByteBuffer buf) {
((DirectBuffer)buf).cleaner().clean();
}
private static class SelectorWrapper {
......
......@@ -260,3 +260,30 @@ networkaddress.cache.negative.ttl=10
# Example,
# ocsp.responderCertSerialNumber=2A:FF:00
#
# Policy for failed Kerberos KDC lookups:
#
# When a KDC is unavailable (network error, service failure, etc), it is
# put inside a blacklist and accessed less often for future requests. The
# value (case-insensitive) for this policy can be:
#
# tryLast
# KDCs in the blacklist are always tried after those not on the list.
#
# tryLess[:max_retries,timeout]
# KDCs in the blacklist are still tried by their order in the configuration,
# but with smaller max_retries and timeout values. max_retries and timeout
# are optional numerical parameters (default 1 and 5000, which means once
# and 5 seconds). Please notes that if any of the values defined here is
# more than what is defined in krb5.conf, it will be ignored.
#
# Whenever a KDC is detected as available, it is removed from the blacklist.
# The blacklist is reset when krb5.conf is reloaded. You can add
# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
# reloaded whenever a JAAS authentication is attempted.
#
# Example,
# krb5.kdc.bad.policy = tryLast
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
......@@ -260,3 +260,30 @@ networkaddress.cache.negative.ttl=10
# Example,
# ocsp.responderCertSerialNumber=2A:FF:00
#
# Policy for failed Kerberos KDC lookups:
#
# When a KDC is unavailable (network error, service failure, etc), it is
# put inside a blacklist and accessed less often for future requests. The
# value (case-insensitive) for this policy can be:
#
# tryLast
# KDCs in the blacklist are always tried after those not on the list.
#
# tryLess[:max_retries,timeout]
# KDCs in the blacklist are still tried by their order in the configuration,
# but with smaller max_retries and timeout values. max_retries and timeout
# are optional numerical parameters (default 1 and 5000, which means once
# and 5 seconds). Please notes that if any of the values defined here is
# more than what is defined in krb5.conf, it will be ignored.
#
# Whenever a KDC is detected as available, it is removed from the blacklist.
# The blacklist is reset when krb5.conf is reloaded. You can add
# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
# reloaded whenever a JAAS authentication is attempted.
#
# Example,
# krb5.kdc.bad.policy = tryLast
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
......@@ -2730,7 +2730,10 @@ push_stack(context_type *context, unsigned int inumber, stack_info_type *new_sta
operand);
const char *result_signature;
check_and_push(context, signature, VM_STRING_UTF);
result_signature = strchr(signature, JVM_SIGNATURE_ENDFUNC) + 1;
result_signature = strchr(signature, JVM_SIGNATURE_ENDFUNC);
if (result_signature++ == NULL) {
CCerror(context, "Illegal signature %s", signature);
}
if (result_signature[0] == JVM_SIGNATURE_VOID) {
stack_results = "";
} else {
......@@ -3654,14 +3657,13 @@ signature_to_fieldtype(context_type *context,
const char **signature_p, fullinfo_type *full_info_p)
{
const char *p = *signature_p;
fullinfo_type full_info = MAKE_FULLINFO(0, 0, 0);
fullinfo_type full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
char result;
int array_depth = 0;
for (;;) {
switch(*p++) {
default:
full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
result = 0;
break;
......@@ -3714,7 +3716,14 @@ signature_to_fieldtype(context_type *context,
char buffer_space[256];
char *buffer = buffer_space;
char *finish = strchr(p, JVM_SIGNATURE_ENDCLASS);
int length = finish - p;
int length;
if (finish == NULL) {
/* Signature must have ';' after the class name.
* If it does not, return 0 and ITEM_Bogus in full_info. */
result = 0;
break;
}
length = finish - p;
if (length + 1 > (int)sizeof(buffer_space)) {
buffer = malloc(length + 1);
check_and_push(context, buffer, VM_MALLOC_BLK);
......
......@@ -187,7 +187,6 @@ class UnixFileSystem extends FileSystem {
}
}
}
assert canonicalize0(path).equals(res) || path.startsWith(javaHome);
return res;
}
}
......
......@@ -1141,6 +1141,13 @@ class UnixPath
}
result = result.resolve(element);
}
// check file exists (without following links)
try {
UnixFileAttributes.get(result, false);
} catch (UnixException x) {
x.rethrowAsIOException(result);
}
return result;
}
......
......@@ -1052,30 +1052,38 @@ JNIEXPORT void JNICALL
Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
jobject this) {
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
int fd;
int t = 1;
int fd, t = 1;
#ifdef AF_INET6
int domain = ipv6_available() ? AF_INET6 : AF_INET;
#else
int domain = AF_INET;
#endif
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
} else {
#ifdef AF_INET6
if (ipv6_available()) {
fd = JVM_Socket(AF_INET6, SOCK_DGRAM, 0);
} else
#endif /* AF_INET6 */
{
fd = JVM_Socket(AF_INET, SOCK_DGRAM, 0);
}
}
if (fd == JVM_IO_ERR) {
if ((fd = JVM_Socket(domain, SOCK_DGRAM, 0)) == JVM_IO_ERR) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"Error creating socket");
return;
}
#ifdef AF_INET6
/* Disable IPV6_V6ONLY to ensure dual-socket support */
if (domain == AF_INET6) {
int arg = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
sizeof(int)) < 0) {
NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
close(fd);
return;
}
}
#endif /* AF_INET6 */
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int));
#ifdef __linux__
......@@ -1088,7 +1096,7 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
* On Linux for IPv6 sockets we must set the hop limit
* to 1 to be compatible with default ttl of 1 for IPv4 sockets.
*/
if (ipv6_available()) {
if (domain == AF_INET6) {
int ttl = 1;
setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl,
sizeof(ttl));
......
......@@ -181,6 +181,12 @@ Java_java_net_PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
jboolean stream) {
jobject fdObj, ssObj;
int fd;
int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
#ifdef AF_INET6
int domain = ipv6_available() ? AF_INET6 : AF_INET;
#else
int domain = AF_INET;
#endif
if (socketExceptionCls == NULL) {
jclass c = (*env)->FindClass(env, "java/net/SocketException");
......@@ -194,25 +200,29 @@ Java_java_net_PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
(*env)->ThrowNew(env, socketExceptionCls, "null fd object");
return;
}
#ifdef AF_INET6
if (ipv6_available()) {
fd = JVM_Socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
} else
#endif /* AF_INET6 */
{
fd = JVM_Socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
}
if (fd == JVM_IO_ERR) {
if ((fd = JVM_Socket(domain, type, 0)) == JVM_IO_ERR) {
/* note: if you run out of fds, you may not be able to load
* the exception class, and get a NoClassDefFoundError
* instead.
*/
NET_ThrowNew(env, errno, "can't create socket");
return;
} else {
(*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
}
#ifdef AF_INET6
/* Disable IPV6_V6ONLY to ensure dual-socket support */
if (domain == AF_INET6) {
int arg = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
sizeof(int)) < 0) {
NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
close(fd);
return;
}
}
#endif /* AF_INET6 */
/*
* If this is a server socket then enable SO_REUSEADDR
* automatically and set to non blocking.
......@@ -221,9 +231,15 @@ Java_java_net_PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
if (ssObj != NULL) {
int arg = 1;
SET_NONBLOCKING(fd);
JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
sizeof(arg));
if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
sizeof(arg)) < 0) {
NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
close(fd);
return;
}
}
(*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
}
/*
......
......@@ -170,6 +170,22 @@ Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
if (fd < 0) {
return handleSocketError(env, errno);
}
#ifdef AF_INET6
/* Disable IPV6_V6ONLY to ensure dual-socket support */
if (domain == AF_INET6) {
int arg = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
sizeof(int)) < 0) {
JNU_ThrowByNameWithLastError(env,
JNU_JAVANETPKG "SocketException",
"sun.nio.ch.Net.setIntOption");
close(fd);
return -1;
}
}
#endif
if (reuse) {
int arg = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
......
......@@ -424,7 +424,6 @@ class Win32FileSystem extends FileSystem {
}
}
}
assert canonicalize0(path).equalsIgnoreCase(res);
return res;
}
}
......
......@@ -55,7 +55,7 @@ case "$OS" in
Linux )
FS="/"
;;
Windows* )
Windows* | CYGWIN* )
FS="\\"
;;
esac
......
......@@ -1536,6 +1536,7 @@ public class Test {
serial();
urls();
npes();
bugs();
}
......@@ -1572,6 +1573,19 @@ public class Test {
}
// miscellaneous bugs/rfes that don't fit in with the test framework
static void bugs() {
// 6339649 - include detail message from nested exception
try {
URI uri = URI.create("http://nowhere.net/should not be permitted");
} catch (IllegalArgumentException e) {
if ("".equals(e.getMessage()) || e.getMessage() == null) {
throw new RuntimeException ("No detail message");
}
}
}
public static void main(String[] args) throws Exception {
switch (args.length) {
......
......@@ -260,6 +260,21 @@ public class Misc {
*/
assertTrue(file.toRealPath(true).isSameFile(file.toRealPath(false)));
/**
* Test: toRealPath should fail if file does not exist
*/
Path doesNotExist = dir.resolve("DoesNotExist");
try {
doesNotExist.toRealPath(true);
throw new RuntimeException("IOException expected");
} catch (IOException expected) {
}
try {
doesNotExist.toRealPath(false);
throw new RuntimeException("IOException expected");
} catch (IOException expected) {
}
/**
* Test: toRealPath(true) should resolve links
*/
......
......@@ -23,6 +23,7 @@
#
# @test
# @ignore until 6543856 is fixed
# @bug 4990825
# @summary attach to external but local JVM processes
# @library ../../testlibrary
......
/*
* Copyright (c) 2010, 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.URL;
import java.net.URLConnection;
import java.io.IOException;
public class DirPermissionDenied {
public static void main(String[] args) throws Exception {
URL url = new URL("file:" + args[0]);
try {
URLConnection uc = url.openConnection();
uc.connect();
} catch (IOException e) {
// OK
} catch (Exception e) {
throw new RuntimeException("Failed " + e);
}
try {
URLConnection uc = url.openConnection();
uc.getInputStream();
} catch (IOException e) {
// OK
} catch (Exception e) {
throw new RuntimeException("Failed " + e);
}
try {
URLConnection uc = url.openConnection();
uc.getContentLengthLong();
} catch (IOException e) {
// OK
} catch (Exception e) {
throw new RuntimeException("Failed " + e);
}
}
}
#
# Copyright (c) 2010, 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 6977851
# @summary NPE from FileURLConnection.connect
# @build DirPermissionDenied
# @run shell DirPermissionDenied.sh
TESTDIR="${TESTCLASSES}/DirPermissionDeniedDirectory"
echo ${TESTDIR}
rm -rf ${TESTDIR}
mkdir -p ${TESTDIR}
chmod 333 ${TESTDIR}
$TESTJAVA/bin/java -classpath $TESTCLASSES DirPermissionDenied ${TESTDIR}
result=$?
rm -rf ${TESTDIR}
exit $result
/*
* Copyright (c) 2010, 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 6976536
* @summary Solaris JREs do not have the krb5.kdc.bad.policy configured by default.
* @run main/othervm BadKdcDefaultValue
*/
import java.security.Security;
public class BadKdcDefaultValue {
public static void main(String[] args) throws Exception {
if (!"tryLast".equalsIgnoreCase(
Security.getProperty("krb5.kdc.bad.policy"))) {
throw new Exception("Default value not correct");
}
}
}
......@@ -23,7 +23,7 @@
/*
* @test
* @bug 6226610
* @bug 6226610 6973030
* @run main/othervm B6226610
* @summary HTTP tunnel connections send user headers to proxy
*/
......@@ -36,45 +36,23 @@
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import javax.net.ServerSocketFactory;
import sun.net.www.*;
import java.util.Enumeration;
import sun.net.www.MessageHeader;
public class B6226610 {
static HeaderCheckerProxyTunnelServer proxy;
// it seems there's no proxy ever if a url points to 'localhost',
// even if proxy related properties are set. so we need to bind
// our simple http proxy and http server to a non-loopback address
static InetAddress firstNonLoAddress = null;
public static void main(String[] args)
public static void main(String[] args) throws Exception
{
try {
proxy = new HeaderCheckerProxyTunnelServer();
proxy.start();
} catch (Exception e) {
System.out.println("Cannot create proxy: " + e);
}
try {
firstNonLoAddress = getNonLoAddress();
if (firstNonLoAddress == null) {
System.out.println("The test needs at least one non-loopback address to run. Quit now.");
System.exit(0);
}
} catch (Exception e) {
e.printStackTrace();
}
proxy = new HeaderCheckerProxyTunnelServer();
proxy.start();
System.setProperty( "https.proxyHost", firstNonLoAddress.getHostAddress());
System.setProperty( "https.proxyPort", (new Integer(proxy.getLocalPort())).toString() );
String hostname = InetAddress.getLocalHost().getHostName();
try {
URL u = new URL("https://" + firstNonLoAddress.getHostAddress());
java.net.URLConnection c = u.openConnection();
URL u = new URL("https://" + hostname + "/");
System.out.println("Connecting to " + u);
InetSocketAddress proxyAddr = new InetSocketAddress(hostname, proxy.getLocalPort());
java.net.URLConnection c = u.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddr));
/* I want this header to go to the destination server only, protected
* by SSL
......@@ -89,33 +67,15 @@ public class B6226610 {
}
else
System.out.println(e);
} finally {
if (proxy != null) proxy.shutdown();
}
if (HeaderCheckerProxyTunnelServer.failed)
throw new RuntimeException("Test failed: Proxy should not receive user defined headers for tunneled requests");
}
public static InetAddress getNonLoAddress() throws Exception {
NetworkInterface loNIC = NetworkInterface.getByInetAddress(InetAddress.getByName("localhost"));
Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces();
while (nics.hasMoreElements()) {
NetworkInterface nic = nics.nextElement();
if (!nic.getName().equalsIgnoreCase(loNIC.getName())) {
Enumeration<InetAddress> addrs = nic.getInetAddresses();
while (addrs.hasMoreElements()) {
InetAddress addr = addrs.nextElement();
if (!addr.isLoopbackAddress())
return addr;
}
}
}
return null;
throw new RuntimeException("Test failed; see output");
}
}
class HeaderCheckerProxyTunnelServer extends Thread
{
public static boolean failed = false;
......@@ -139,6 +99,10 @@ class HeaderCheckerProxyTunnelServer extends Thread
}
}
void shutdown() {
try { ss.close(); } catch (IOException e) {}
}
public void run()
{
try {
......@@ -178,6 +142,15 @@ class HeaderCheckerProxyTunnelServer extends Thread
retrieveConnectInfo(statusLine);
if (mheader.findValue("X-TestHeader") != null) {
System.out.println("Proxy should not receive user defined headers for tunneled requests");
failed = true;
}
// 6973030
String value;
if ((value = mheader.findValue("Proxy-Connection")) == null ||
!value.equals("keep-alive")) {
System.out.println("Proxy-Connection:keep-alive not being sent");
failed = true;
}
......
......@@ -23,7 +23,7 @@
/**
* @test
* @bug 4225317
* @bug 4225317 6969651
* @summary Check extracted files have date as per those in the .jar file
*/
......@@ -68,17 +68,9 @@ public class JarEntryTime {
}
public static void realMain(String[] args) throws Throwable {
final long now = System.currentTimeMillis();
final long earlier = now - (60L * 60L * 6L * 1000L);
final long yesterday = now - (60L * 60L * 24L * 1000L);
// ZipEntry's mod date has 2 seconds precision: give extra time to
// allow for e.g. rounding/truncation and networked/samba drives.
final long PRECISION = 10000L;
File dirOuter = new File("outer");
File dirInner = new File(dirOuter, "inner");
File jarFile = new File("JarEntryTime.jar");
// Remove any leftovers from prior run
......@@ -99,6 +91,17 @@ public class JarEntryTime {
PrintWriter pw = new PrintWriter(fileInner);
pw.println("hello, world");
pw.close();
// Get the "now" from the "last-modified-time" of the last file we
// just created, instead of the "System.currentTimeMillis()", to
// workaround the possible "time difference" due to nfs.
final long now = fileInner.lastModified();
final long earlier = now - (60L * 60L * 6L * 1000L);
final long yesterday = now - (60L * 60L * 24L * 1000L);
// ZipEntry's mod date has 2 seconds precision: give extra time to
// allow for e.g. rounding/truncation and networked/samba drives.
final long PRECISION = 10000L;
dirOuter.setLastModified(now);
dirInner.setLastModified(yesterday);
fileInner.setLastModified(earlier);
......
/*
* Copyright (c) 2007, 2010 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 CommandLineTests.sh
* @bug 6521334 6965836 6965836
* @compile -XDignore.symbol.file CommandLineTests.java Pack200Test.java
* @run main/timeout=1200 CommandLineTests
* @summary An ad hoc test to verify the behavior of pack200/unpack200 CLIs,
* and a simulation of pack/unpacking in the install repo.
* @author ksrini
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
/*
* We try a potpouri of things ie. we have pack.conf to setup some
* options as well as a couple of command line options. We also test
* the packing and unpacking mechanism using the Java APIs. This also
* simulates pack200 the install workspace, noting that this is a simulation
* and can only test jars that are guaranteed to be available, also the
* configuration may not be in sync with the installer workspace.
*/
public class CommandLineTests {
private static final File CWD = new File(".");
private static final File EXP_SDK = new File(CWD, "exp-sdk-image");
private static final File EXP_SDK_LIB_DIR = new File(EXP_SDK, "lib");
private static final File EXP_SDK_BIN_DIR = new File(EXP_SDK, "bin");
private static final File EXP_JRE_DIR = new File(EXP_SDK, "jre");
private static final File EXP_JRE_LIB_DIR = new File(EXP_JRE_DIR, "lib");
private static final File RtJar = new File(EXP_JRE_LIB_DIR, "rt.jar");
private static final File CharsetsJar = new File(EXP_JRE_LIB_DIR, "charsets.jar");
private static final File JsseJar = new File(EXP_JRE_LIB_DIR, "jsse.jar");
private static final File ToolsJar = new File(EXP_SDK_LIB_DIR, "tools.jar");
private static final File javaCmd;
private static final File javacCmd;
private static final File ConfigFile = new File("pack.conf");
private static final List<File> jarList;
static {
javaCmd = Utils.IsWindows
? new File(EXP_SDK_BIN_DIR, "java.exe")
: new File(EXP_SDK_BIN_DIR, "java");
javacCmd = Utils.IsWindows
? new File(EXP_SDK_BIN_DIR, "javac.exe")
: new File(EXP_SDK_BIN_DIR, "javac");
jarList = new ArrayList<File>();
jarList.add(RtJar);
jarList.add(CharsetsJar);
jarList.add(JsseJar);
jarList.add(ToolsJar);
}
// init test area with a copy of the sdk
static void init() throws IOException {
Utils.recursiveCopy(Utils.JavaSDK, EXP_SDK);
creatConfigFile();
}
// Hopefully, this should be kept in sync with what the installer does.
static void creatConfigFile() throws IOException {
FileOutputStream fos = null;
PrintStream ps = null;
try {
fos = new FileOutputStream(ConfigFile);
ps = new PrintStream(fos);
ps.println("com.sun.java.util.jar.pack.debug.verbose=0");
ps.println("pack.modification.time=keep");
ps.println("pack.keep.class.order=true");
ps.println("pack.deflate.hint=false");
// Fail the build, if new or unknown attributes are introduced.
ps.println("pack.unknown.attribute=error");
ps.println("pack.segment.limit=-1");
// BugId: 6328502, These files will be passed-through as-is.
ps.println("pack.pass.file.0=java/lang/Error.class");
ps.println("pack.pass.file.1=java/lang/LinkageError.class");
ps.println("pack.pass.file.2=java/lang/Object.class");
ps.println("pack.pass.file.3=java/lang/Throwable.class");
ps.println("pack.pass.file.4=java/lang/VerifyError.class");
ps.println("pack.pass.file.5=com/sun/demo/jvmti/hprof/Tracker.class");
} finally {
Utils.close(ps);
Utils.close(fos);
}
}
static void runPack200(boolean jre) throws IOException {
List<String> cmdsList = new ArrayList<String>();
for (File f : jarList) {
if (jre && f.getName().equals("tools.jar")) {
continue; // need not worry about tools.jar for JRE
}
// make a backup copy for re-use
File bakFile = new File(f.getName() + ".bak");
if (!bakFile.exists()) { // backup
Utils.copyFile(f.getAbsoluteFile(), bakFile.getAbsoluteFile());
} else { // restore
Utils.copyFile(bakFile.getAbsoluteFile(), f.getAbsoluteFile());
}
cmdsList.clear();
cmdsList.add(Utils.getPack200Cmd());
cmdsList.add("-J-esa");
cmdsList.add("-J-ea");
cmdsList.add(Utils.Is64Bit ? "-J-Xmx1g" : "-J-Xmx512m");
cmdsList.add("--repack");
cmdsList.add("--config-file=" + ConfigFile.getAbsolutePath());
if (jre) {
cmdsList.add("--strip-debug");
}
// NOTE: commented until 6965836 is fixed
// cmdsList.add("--code-attribute=StackMapTable=strip");
cmdsList.add(f.getAbsolutePath());
Utils.runExec(cmdsList);
}
}
static void testJRE() throws IOException {
runPack200(true);
// the speciment JRE
List<String> cmdsList = new ArrayList<String>();
cmdsList.add(javaCmd.getAbsolutePath());
cmdsList.add("-verify");
cmdsList.add("-version");
Utils.runExec(cmdsList);
}
static void testJDK() throws IOException {
runPack200(false);
// test the specimen JDK
List<String> cmdsList = new ArrayList<String>();
cmdsList.add(javaCmd.getAbsolutePath());
cmdsList.add("-verify");
cmdsList.add("-version");
Utils.runExec(cmdsList);
// invoke javac to test the tools.jar
cmdsList.clear();
cmdsList.add(javacCmd.getAbsolutePath());
cmdsList.add("-J-verify");
cmdsList.add("-help");
Utils.runExec(cmdsList);
}
public static void main(String... args) {
try {
init();
testJRE();
testJDK();
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
}
......@@ -21,113 +21,107 @@
* questions.
*/
/**
/*
* @test
* @bug 6575373
* @summary verify default segment limit
* @compile SegmentLimit.java
* @run main SegmentLimit
* @bug 6575373 6969063
* @summary verify default properties of the packer/unpacker and segment limit
* @compile -XDignore.symbol.file Utils.java Pack200Props.java
* @run main Pack200Props
* @author ksrini
*/
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.Pack200;
import java.util.jar.Pack200.Packer;
/*
* Run this against a large jar file, by default the packer should generate only
* one segment, parse the output of the packer to verify if this is indeed true.
*/
public class SegmentLimit {
private static final File javaHome = new File(System.getProperty("java.home"));
public class Pack200Props {
public static void main(String... args) {
if (!javaHome.getName().endsWith("jre")) {
throw new RuntimeException("Error: requires an SDK to run");
}
File out = new File("test" + Pack200Test.PACKEXT);
verifyDefaults();
File out = new File("test" + Utils.PACK_FILE_EXT);
out.delete();
runPack200(out);
verifySegmentLimit(out);
}
static void close(Closeable c) {
if (c == null) {
return;
}
try {
c.close();
} catch (IOException ignore) {}
}
static void runPack200(File outFile) {
File binDir = new File(javaHome, "bin");
File pack200Exe = System.getProperty("os.name").startsWith("Windows")
? new File(binDir, "pack200.exe")
: new File(binDir, "pack200");
File sdkHome = javaHome.getParentFile();
static void verifySegmentLimit(File outFile) {
File sdkHome = Utils.JavaSDK;
File testJar = new File(new File(sdkHome, "lib"), "tools.jar");
System.out.println("using pack200: " + pack200Exe.getAbsolutePath());
String[] cmds = { pack200Exe.getAbsolutePath(),
"--effort=1",
"--verbose",
"--no-gzip",
outFile.getName(),
testJar.getAbsolutePath()
};
InputStream is = null;
BufferedReader br = null;
InputStreamReader ir = null;
FileOutputStream fos = null;
PrintStream ps = null;
try {
ProcessBuilder pb = new ProcessBuilder(cmds);
pb.redirectErrorStream(true);
Process p = pb.start();
is = p.getInputStream();
ir = new InputStreamReader(is);
br = new BufferedReader(ir);
File logFile = new File("pack200.log");
fos = new FileOutputStream(logFile);
ps = new PrintStream(fos);
System.out.println("using pack200: " + Utils.getPack200Cmd());
List<String> cmdsList = new ArrayList<>();
cmdsList.add(Utils.getPack200Cmd());
cmdsList.add("--effort=1");
cmdsList.add("--verbose");
cmdsList.add("--no-gzip");
cmdsList.add(outFile.getName());
cmdsList.add(testJar.getAbsolutePath());
List<String> outList = Utils.runExec(cmdsList);
int count = 0;
for (String line : outList) {
System.out.println(line);
if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) {
count++;
}
}
if (count == 0) {
throw new RuntimeException("no segments or no output ????");
} else if (count > 1) {
throw new RuntimeException("multiple segments detected, expected 1");
}
}
String line = br.readLine();
int count = 0;
while (line != null) {
line = line.trim();
if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) {
count++;
private static void verifyDefaults() {
Map<String, String> expectedDefaults = new HashMap<>();
Packer p = Pack200.newPacker();
expectedDefaults.put("com.sun.java.util.jar.pack.default.timezone",
p.FALSE);
expectedDefaults.put("com.sun.java.util.jar.pack.disable.native",
p.FALSE);
expectedDefaults.put("com.sun.java.util.jar.pack.verbose", "0");
expectedDefaults.put(p.CLASS_ATTRIBUTE_PFX + "CompilationID", "RUH");
expectedDefaults.put(p.CLASS_ATTRIBUTE_PFX + "SourceID", "RUH");
expectedDefaults.put(p.CODE_ATTRIBUTE_PFX + "CharacterRangeTable",
"NH[PHPOHIIH]");
expectedDefaults.put(p.CODE_ATTRIBUTE_PFX + "CoverageTable",
"NH[PHHII]");
expectedDefaults.put(p.DEFLATE_HINT, p.KEEP);
expectedDefaults.put(p.EFFORT, "5");
expectedDefaults.put(p.KEEP_FILE_ORDER, p.TRUE);
expectedDefaults.put(p.MODIFICATION_TIME, p.KEEP);
expectedDefaults.put(p.SEGMENT_LIMIT, "-1");
expectedDefaults.put(p.UNKNOWN_ATTRIBUTE, p.PASS);
Map<String, String> props = p.properties();
int errors = 0;
for (String key : expectedDefaults.keySet()) {
String def = expectedDefaults.get(key);
String x = props.get(key);
if (x == null) {
System.out.println("Error: key not found:" + key);
errors++;
} else {
if (!def.equals(x)) {
System.out.println("Error: key " + key
+ "\n value expected: " + def
+ "\n value obtained: " + x);
errors++;
}
ps.println(line);
line=br.readLine();
}
p.waitFor();
if (p.exitValue() != 0) {
throw new RuntimeException("pack200 failed");
}
p.destroy();
if (count > 1) {
throw new Error("test fails: check for multiple segments(" +
count + ") in: " + logFile.getAbsolutePath());
}
} catch (IOException ex) {
throw new RuntimeException(ex.getMessage());
} catch (InterruptedException ignore){
} finally {
close(is);
close(ps);
close(fos);
}
if (errors > 0) {
throw new RuntimeException(errors +
" error(s) encountered in default properties verification");
}
}
}
......
#
# Copyright (c) 2003, 2007, 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 Pack200Simple.sh
# @bug 6521334
# @build Pack200Test
# @run shell/timeout=1200 Pack200Simple.sh
# @summary An ad hoc test to verify class-file format.
# @author Kumar Srinivasan
# The goal of this test is to assist javac or other developers
# who modify class file formats, to quickly test those modifications
# without having to build the install workspace. However it must
# be noted that building the install workspace is the only know
# way to prevent build breakages.
# Pack200 developers could use this as a basic smoke-test, however
# please note, there are other more elaborate and thorough tests for
# this very purpose.
# We try a potpouri of things ie. we have pack.conf to setup some
# options as well as a couple of command line options. We also test
# the packing and unpacking mechanism using the Java APIs.
# print error and exit with a message
errorOut() {
if [ "x$1" = "x" ]; then
printf "Error: Unknown error\n"
else
printf "Error: %s\n" "$1"
fi
exit 1
}
# Verify directory context variables are set
if [ "${TESTJAVA}" = "" ]; then
errorOut "TESTJAVA not set. Test cannot execute. Failed."
fi
if [ "${TESTSRC}" = "" ]; then
errorOut "TESTSRC not set. Test cannot execute. Failed."
fi
if [ "${TESTCLASSES}" = "" ]; then
errorOut "TESTCLASSES not set. Test cannot execute. Failed."
fi
# The common java utils we need
PACK200=${TESTJAVA}/bin/pack200
UNPACK200=${TESTJAVA}/bin/unpack200
JAR=${TESTJAVA}/bin/jar
# For Windows and Linux needs the heap to be set, for others ergonomics
# will do the rest. It is important to use ea, which can expose class
# format errors much earlier than later.
OS=`uname -s`
case "$OS" in
Windows*|CYGWIN* )
PackOptions="-J-Xmx512m -J-ea"
break
;;
Linux )
PackOptions="-J-Xmx512m -J-ea"
break
;;
* )
PackOptions="-J-ea"
;;
esac
# Creates a packfile of choice expects 1 argument the filename
createConfigFile() {
# optimize for speed
printf "pack.effort=1\n" > $1
# we DO want to know about new attributes
printf "pack.unknown.attribute=error\n" >> $1
# optimize for speed
printf "pack.deflate.hint=false\n" >> $1
# keep the ordering for easy compare
printf "pack.keep.class.order=true\n" >> $1
}
# Tests a given jar, expects 1 argument the fully qualified
# name to a test jar, it writes all output to the current
# directory which is a scratch area.
testAJar() {
PackConf="pack.conf"
createConfigFile $PackConf
# Try some command line options
CLIPackOptions="$PackOptions -v --no-gzip --segment-limit=10000 --config-file=$PackConf"
jfName=`basename $1`
${PACK200} $CLIPackOptions ${jfName}.pack $1 > ${jfName}.pack.log 2>&1
if [ $? != 0 ]; then
errorOut "$jfName packing failed"
fi
# We want to test unpack200, therefore we dont use -r with pack
${UNPACK200} -v ${jfName}.pack $jfName > ${jfName}.unpack.log 2>&1
if [ $? != 0 ]; then
errorOut "$jfName unpacking failed"
fi
# A quick crc compare test to ensure a well formed zip
# archive, this is a critical unpack200 behaviour.
unzip -t $jfName > ${jfName}.unzip.log 2>&1
if [ $? != 0 ]; then
errorOut "$jfName unzip -t test failed"
fi
# The PACK200 signature should be at the top of the log
# this tag is critical for deployment related tools.
head -5 ${jfName}.unzip.log | grep PACK200 > /dev/null 2>&1
if [ $? != 0 ]; then
errorOut "$jfName PACK200 signature missing"
fi
# we know the size fields don't match, strip 'em out, its
# extremely important to ensure that the date stamps match up.
# Don't EVER sort the output we are checking for correct ordering.
${JAR} -tvf $1 | sed -e 's/^ *[0-9]* //g'> ${jfName}.ref.txt
${JAR} -tvf $jfName | sed -e 's/^ *[0-9]* //g'> ${jfName}.cmp.txt
diff ${jfName}.ref.txt ${jfName}.cmp.txt > ${jfName}.diff.log 2>&1
if [ $? != 0 ]; then
errorOut "$jfName files missing"
fi
}
# These JARs are the largest and also the most likely specimens to
# expose class format issues and stress the packer as well.
JLIST="${TESTJAVA}/lib/tools.jar ${TESTJAVA}/jre/lib/rt.jar"
# Test the Command Line Interfaces (CLI).
mkdir cliTestDir
_pwd=`pwd`
cd cliTestDir
for jarfile in $JLIST ; do
if [ -f $jarfile ]; then
testAJar $jarfile
else
errorOut "Error: '$jarFile' does not exist\nTest requires a j2sdk-image\n"
fi
done
cd $_pwd
# Test the Java APIs.
mkdir apiTestDir
_pwd=`pwd`
cd apiTestDir
# Strip out the -J prefixes.
JavaPackOptions=`printf %s "$PackOptions" | sed -e 's/-J//g'`
# Test the Java APIs now.
$TESTJAVA/bin/java $JavaPackOptions -cp $TESTCLASSES Pack200Test $JLIST || exit 1
cd $_pwd
exit 0
......@@ -24,111 +24,97 @@
import java.util.*;
import java.io.*;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.util.jar.*;
import java.util.zip.*;
/*
* Pack200Test.java
*
* @author ksrini
*/
/*
* @test
* @bug 6521334 6712743
* @summary check for memory leaks, test general packer/unpacker functionality\
* using native and java unpackers
* @compile -XDignore.symbol.file Utils.java Pack200Test.java
* @run main/othervm/timeout=1200 -Xmx512m Pack200Test
* @author ksrini
*/
/**
* These tests are very rudimentary smoke tests to ensure that the packing
* unpacking process works on a select set of JARs.
* Tests the packing/unpacking via the APIs.
*/
public class Pack200Test {
private static ArrayList <File> jarList = new ArrayList<File>();
static final String PACKEXT = ".pack";
static final MemoryMXBean mmxbean = ManagementFactory.getMemoryMXBean();
static final long m0 = getUsedMemory();
static final int LEAK_TOLERANCE = 20000; // OS and GC related variations.
/** Creates a new instance of Pack200Test */
private Pack200Test() {}
static long getUsedMemory() {
mmxbean.gc();
mmxbean.gc();
mmxbean.gc();
return mmxbean.getHeapMemoryUsage().getUsed()/1024;
}
private static void leakCheck() throws Exception {
long diff = getUsedMemory() - m0;
System.out.println(" Info: memory diff = " + diff + "K");
if ( diff > LEAK_TOLERANCE) {
throw new Exception("memory leak detected " + diff);
}
}
private static void doPackUnpack() {
for (File in : jarList) {
Pack200.Packer packer = Pack200.newPacker();
Map<String, String> p = packer.properties();
// Take the time optimization vs. space
p.put(packer.EFFORT, "1"); // CAUTION: do not use 0.
// Make the memory consumption as effective as possible
p.put(packer.SEGMENT_LIMIT,"10000");
// throw an error if an attribute is unrecognized
p.put(packer.UNKNOWN_ATTRIBUTE, packer.ERROR);
// ignore all JAR deflation requests to save time
p.put(packer.DEFLATE_HINT, packer.FALSE);
// save the file ordering of the original JAR
p.put(packer.KEEP_FILE_ORDER, packer.TRUE);
JarOutputStream javaUnpackerStream = null;
JarOutputStream nativeUnpackerStream = null;
JarFile jarFile = null;
try {
JarFile jarFile = new JarFile(in);
jarFile = new JarFile(in);
// Write out to a jtreg scratch area
FileOutputStream fos = new FileOutputStream(in.getName() + PACKEXT);
File packFile = new File(in.getName() + Utils.PACK_FILE_EXT);
System.out.print("Packing [" + in.toString() + "]...");
System.out.println("Packing [" + in.toString() + "]");
// Call the packer
packer.pack(jarFile, fos);
Utils.pack(jarFile, packFile);
jarFile.close();
fos.close();
System.out.print("Unpacking...");
File f = new File(in.getName() + PACKEXT);
leakCheck();
System.out.println(" Unpacking using java unpacker");
File javaUnpackedJar = new File("java-" + in.getName());
// Write out to current directory, jtreg will setup a scratch area
JarOutputStream jostream = new JarOutputStream(new FileOutputStream(in.getName()));
// Unpack the files
Pack200.Unpacker unpacker = Pack200.newUnpacker();
// Call the unpacker
unpacker.unpack(f, jostream);
// Must explicitly close the output.
jostream.close();
System.out.print("Testing...");
javaUnpackerStream = new JarOutputStream(
new FileOutputStream(javaUnpackedJar));
Utils.unpackj(packFile, javaUnpackerStream);
javaUnpackerStream.close();
System.out.println(" Testing...java unpacker");
leakCheck();
// Ok we have unpacked the file, lets test it.
doTest(in);
Utils.doCompareVerify(in.getAbsoluteFile(), javaUnpackedJar);
System.out.println(" Unpacking using native unpacker");
// Write out to current directory
File nativeUnpackedJar = new File("native-" + in.getName());
nativeUnpackerStream = new JarOutputStream(
new FileOutputStream(nativeUnpackedJar));
Utils.unpackn(packFile, nativeUnpackerStream);
nativeUnpackerStream.close();
System.out.println(" Testing...native unpacker");
leakCheck();
// the unpackers (native and java) should produce identical bits
// so we use use bit wise compare, the verification compare is
// very expensive wrt. time.
Utils.doCompareBitWise(javaUnpackedJar, nativeUnpackedJar);
System.out.println("Done.");
} catch (Exception e) {
System.out.println("ERROR: " + e.getMessage());
System.exit(1);
}
}
}
private static ArrayList <String> getZipFileEntryNames(ZipFile z) {
ArrayList <String> out = new ArrayList<String>();
for (ZipEntry ze : Collections.list(z.entries())) {
out.add(ze.getName());
}
return out;
}
private static void doTest(File in) throws Exception {
// make sure all the files in the original jar exists in the other
ArrayList <String> refList = getZipFileEntryNames(new ZipFile(in));
ArrayList <String> cmpList = getZipFileEntryNames(new ZipFile(in.getName()));
System.out.print(refList.size() + "/" + cmpList.size() + " entries...");
if (refList.size() != cmpList.size()) {
throw new Exception("Missing: files ?, entries don't match");
}
for (String ename: refList) {
if (!cmpList.contains(ename)) {
throw new Exception("Does not contain : " + ename);
}
}
}
private static void doSanity(String[] args) {
for (String s: args) {
File f = new File(s);
if (f.exists()) {
jarList.add(f);
} else {
System.out.println("Warning: The JAR file " + f.toString() + " does not exist,");
System.out.println(" this test requires a JDK image, this file will be skipped.");
throw new RuntimeException(e);
} finally {
Utils.close(nativeUnpackerStream);
Utils.close(javaUnpackerStream);
Utils.close((Closeable) jarFile);
}
}
}
......@@ -137,11 +123,12 @@ public class Pack200Test {
* @param args the command line arguments
*/
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Usage: jar1 jar2 jar3 .....");
System.exit(1);
}
doSanity(args);
// select the jars carefully, adding more jars will increase the
// testing time, especially for jprt.
jarList.add(Utils.locateJar("tools.jar"));
jarList.add(Utils.locateJar("rt.jar"));
jarList.add(Utils.locateJar("golden.jar"));
System.out.println(jarList);
doPackUnpack();
}
}
......@@ -22,13 +22,14 @@
* questions.
*/
/**
* @test
* @bug 6712743
* @summary verify package versioning
* @compile -XDignore.symbol.file PackageVersionTest.java
* @run main PackageVersionTest
*/
/*
* @test
* @bug 6712743
* @summary verify package versions
* @compile -XDignore.symbol.file Utils.java PackageVersionTest.java
* @run main PackageVersionTest
* @author ksrini
*/
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
......@@ -74,14 +75,6 @@ public class PackageVersionTest {
JAVA5_PACKAGE_MINOR_VERSION);
}
static void close(Closeable c) {
if (c == null) {
return;
}
try {
c.close();
} catch (IOException ignore) {}
}
static void createClassFile(String name) {
createJavaFile(name);
......@@ -93,7 +86,7 @@ public class PackageVersionTest {
name.substring(name.length() - 1),
name + ".java"
};
compileJava(javacCmds);
Utils.compiler(javacCmds);
}
static void createJavaFile(String name) {
......@@ -108,22 +101,8 @@ public class PackageVersionTest {
} catch (IOException ioe) {
throw new RuntimeException("creation of test file failed");
} finally {
close(ps);
close(fos);
}
}
static void compileJava(String... javacCmds) {
if (com.sun.tools.javac.Main.compile(javacCmds) != 0) {
throw new RuntimeException("compilation failed");
}
}
static void makeJar(String... jargs) {
sun.tools.jar.Main jarTool =
new sun.tools.jar.Main(System.out, System.err, "jartool");
if (!jarTool.run(jargs)) {
throw new RuntimeException("jar command failed");
Utils.close(ps);
Utils.close(fos);
}
}
......@@ -136,7 +115,7 @@ public class PackageVersionTest {
jarFileName.getName(),
filename
};
makeJar(jargs);
Utils.jar(jargs);
JarFile jfin = null;
try {
......@@ -163,7 +142,7 @@ public class PackageVersionTest {
} catch (IOException ioe) {
throw new RuntimeException(ioe.getMessage());
} finally {
close(jfin);
Utils.close((Closeable) jfin);
}
}
}
/*
* Copyright (c) 2010, 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.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
/*
* @test
* @bug 6966740
* @summary verify identical timestamps, unpacked in any timezone
* @compile -XDignore.symbol.file Utils.java TimeStamp.java
* @run main/othervm TimeStamp
* @author ksrini
*/
/**
* First we pack the file in some time zone say India, then we unpack the file
* in the current time zone, and ensure the timestamp recorded in the unpacked
* jar are the same.
*/
public class TimeStamp {
static final TimeZone tz = TimeZone.getDefault();
public static void main(String... args) throws IOException {
// make a local copy of our test file
File srcFile = Utils.locateJar("golden.jar");
File goldenFile = new File("golden.jar");
Utils.copyFile(srcFile, goldenFile.getAbsoluteFile());
JarFile goldenJarFile = new JarFile(goldenFile);
File packFile = new File("golden.pack");
// set the test timezone and pack the file
TimeZone.setDefault(TimeZone.getTimeZone("IST"));
Utils.pack(goldenJarFile, packFile);
TimeZone.setDefault(tz); // reset the timezone
// unpack in the test timezone
File istFile = new File("golden.jar.java.IST");
unpackJava(packFile, istFile);
verifyJar(goldenFile, istFile);
istFile.delete();
// unpack in some other timezone
File pstFile = new File("golden.jar.java.PST");
unpackJava(packFile, pstFile);
verifyJar(goldenFile, pstFile);
pstFile.delete();
// repeat the test for unpack200 tool.
istFile = new File("golden.jar.native.IST");
unpackNative(packFile, istFile);
verifyJar(goldenFile, istFile);
istFile.delete();
pstFile = new File("golden.jar.native.PST");
unpackNative(packFile, pstFile);
verifyJar(goldenFile, pstFile);
pstFile.delete();
}
static void unpackNative(File packFile, File outFile) {
String name = outFile.getName();
String tzname = name.substring(name.lastIndexOf(".") + 1);
HashMap<String, String> env = new HashMap<>();
switch(tzname) {
case "PST":
env.put("TZ", "US/Pacific");
break;
case "IST":
env.put("TZ", "Asia/Calcutta");
break;
default:
throw new RuntimeException("not implemented: " + tzname);
}
List<String> cmdsList = new ArrayList<>();
cmdsList.add(Utils.getUnpack200Cmd());
cmdsList.add(packFile.getName());
cmdsList.add(outFile.getName());
Utils.runExec(cmdsList, env);
}
static void unpackJava(File packFile, File outFile) throws IOException {
String name = outFile.getName();
String tzname = name.substring(name.lastIndexOf(".") + 1);
JarOutputStream jos = null;
try {
TimeZone.setDefault(TimeZone.getTimeZone(tzname));
jos = new JarOutputStream(new FileOutputStream(outFile));
System.out.println("Using timezone: " + TimeZone.getDefault());
Utils.unpackj(packFile, jos);
} finally {
Utils.close(jos);
TimeZone.setDefault(tz); // always reset
}
}
static void verifyJar(File f1, File f2) throws IOException {
int errors = 0;
JarFile jf1 = null;
JarFile jf2 = null;
try {
jf1 = new JarFile(f1);
jf2 = new JarFile(f2);
System.out.println("Verifying: " + f1 + " and " + f2);
for (JarEntry je1 : Collections.list(jf1.entries())) {
JarEntry je2 = jf2.getJarEntry(je1.getName());
if (je1.getTime() != je2.getTime()) {
System.out.println("Error:");
System.out.println(" expected:" + jf1.getName() + ":"
+ je1.getName() + ":" + je1.getTime());
System.out.println(" obtained:" + jf2.getName() + ":"
+ je2.getName() + ":" + je2.getTime());
errors++;
}
}
} finally {
Utils.close(jf1);
Utils.close(jf2);
}
if (errors > 0) {
throw new RuntimeException("FAIL:" + errors + " error(s) encounted");
}
}
}
/*
* Copyright (c) 2010, 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 6531345
* @summary check for unpacker memory leaks
* @compile -XDignore.symbol.file Utils.java UnpackerMemoryTest.java
* @run main/othervm/timeout=1200 -Xmx32m UnpackerMemoryTest
* @author ksrini
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
public class UnpackerMemoryTest {
private static void createPackFile(File packFile) throws IOException {
File tFile = new File("test.dat");
FileOutputStream fos = null;
PrintStream ps = null;
String jarFileName = Utils.baseName(packFile, Utils.PACK_FILE_EXT)
+ Utils.JAR_FILE_EXT;
JarFile jarFile = null;
try {
fos = new FileOutputStream(tFile);
ps = new PrintStream(fos);
ps.println("A quick brown fox");
Utils.jar("cvf", jarFileName, tFile.getName());
jarFile = new JarFile(jarFileName);
Utils.pack(jarFile, packFile);
} finally {
Utils.close(ps);
tFile.delete();
Utils.close(jarFile);
}
}
public static void main(String[] args) throws Exception {
String name = "foo";
File packFile = new File(name + Utils.PACK_FILE_EXT);
createPackFile(packFile);
if (!packFile.exists()) {
throw new RuntimeException(packFile + " not found");
}
File jarOut = new File(name + ".out");
for (int i = 0; i < 2000; i++) {
JarOutputStream jarOS = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(jarOut);
jarOS = new JarOutputStream(fos);
System.out.println("Unpacking[" + i + "]" + packFile);
Utils.unpackn(packFile, jarOS);
} finally {
Utils.close(jarOS);
Utils.close(fos);
}
}
}
}
此差异已折叠。
The files contained in the golden.jar have been harvested from many
different sources, some are hand-crafted invalid class files (odds directory),
or from random JDK builds.
Generally these files serve to ensure the integrity of the packer and unpacker
by,
1. maximizing the test coverage.
2. exercising all the Bands in the pack200 specification.
2. testing the behavior of the packer with invalid classes.
3. testing the archive integrity, ordering and description (date, sizes,
CRC etc.)
Build:
To rebuild this JAR follow these steps:
1. unzip the golden.jar to some directory lets call it "example"
2. now we can add any directories with files into example.
2. run the script BUILDME.sh as
% sh BUILDME.sh example
Note: the BUILDME.sh is known to work on all Unix platforms as well as Windows
using Cygwin.
The above will create two JAR files in the current directory,
example.jar and example-cls.jar, now the example.jar can be used as the
golden.jar.
To ensure the JAR has been built correctly use jar -tvf and compare the
results of the old jar and the newly built one, note that the compressed sizes
may differ, however the timestamps etc. should be consistent.
Test:
Basic:
% pack200 --repack test.jar golden.jar
Advanced:
Create a pack.conf as follows:
% cat pack.conf
com.sun.java.util.jar.pack.dump.bands=true
% pack200 --no-gzip --config-file=pack.conf \
--verbose golden.jar.pack golden.jar
This command will dump the Bands in a unique directory BD_XXXXXX,
one can inspect the directory to ensure all of the bands are being
generated. Familiarity of the Pack200 specification is suggested.
\ No newline at end of file
<project name="PackageVerify" default="dist" basedir="..">
<!-- Requires ant 1.6.1+ and JDK 1.6+-->
<!-- set global properties for this build -->
<property name="src" value="${basedir}/src"/>
<property name="build" value="${basedir}/build"/>
<property name="dist" value="${basedir}/dist"/>
<property name="make" value="${basedir}/make"/>
<property name="classes" value="${build}/classes"/>
<property name="api" value="${build}/api"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
<mkdir dir="${dist}"/>
<mkdir dir="${classes}"/>
<mkdir dir="${api}"/>
</target>
<target name="compile" depends="init">
<!-- Compile the java code from ${src} into ${build} -->
<javac
source="1.6"
srcdir="${src}"
destdir="${build}/classes"
verbose="no"
debug="on"
/>
</target>
<target name="doc" depends="init, compile">
<javadoc
source="1.6"
sourcepath="${src}"
destdir="${api}"
/>
</target>
<target name="dist" depends="compile, doc">
<!-- Put everything in jar file -->
<jar destfile="${dist}/pack200-verifier.jar">
<manifest>
<attribute name="Main-Class" value="sun.tools.pack.verify.Main"/>
</manifest>
<fileset dir="${classes}"/>
</jar>
<zip destfile="dist/pack200-verifier-doc.zip">
<fileset dir="${api}"/>
</zip>
</target>
<target name="clean">
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
/*
* Copyright (c) 2010, 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 sun.tools.pack.verify;
import java.util.*;
/*
* @author ksrini
*/
class VerifyTreeSet<K> extends java.util.TreeSet {
VerifyTreeSet() {
super();
}
public VerifyTreeSet(Comparator c) {
super(c);
}
public TreeSet<K> diff(TreeSet in) {
TreeSet<K> delta = (TreeSet<K>) this.clone();
delta.removeAll(in);
return delta;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册