This commit is contained in:
Lana Steuck 2017-06-08 23:11:21 +00:00
commit 7b7451a78f
79 changed files with 907 additions and 7886 deletions

View File

@ -77,6 +77,13 @@ ifneq ($(FREETYPE_BUNDLE_LIB_PATH), )
endif
TARGETS += $(FREETYPE_TARGET_LIB)
$(eval $(call SetupCopyFiles, COPY_FREETYPE_LICENSE, \
FILES := $(FREETYPE_LICENSE), \
DEST := $(LEGAL_DST_DIR), \
))
TARGETS += $(COPY_FREETYPE_LICENSE)
endif
################################################################################

View File

@ -10,7 +10,9 @@ java.corba \
java.transaction \
java.xml.bind \
java.xml.ws \
java.xml.ws.annotation
java.xml.ws.annotation \
jdk.xml.bind \
jdk.xml.ws
aggregator_modules=\
java.se \

View File

@ -2880,19 +2880,19 @@ public final class Class<T> implements java.io.Serializable,
static <T> boolean casReflectionData(Class<?> clazz,
SoftReference<ReflectionData<T>> oldData,
SoftReference<ReflectionData<T>> newData) {
return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
return unsafe.compareAndSetObject(clazz, reflectionDataOffset, oldData, newData);
}
static <T> boolean casAnnotationType(Class<?> clazz,
AnnotationType oldType,
AnnotationType newType) {
return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
return unsafe.compareAndSetObject(clazz, annotationTypeOffset, oldType, newType);
}
static <T> boolean casAnnotationData(Class<?> clazz,
AnnotationData oldData,
AnnotationData newData) {
return unsafe.compareAndSwapObject(clazz, annotationDataOffset, oldData, newData);
return unsafe.compareAndSetObject(clazz, annotationDataOffset, oldData, newData);
}
}

View File

@ -2146,8 +2146,6 @@ public abstract class ClassLoader {
* @revised 9
* @spec JPMS
*
* @see <a href="../../../technotes/guides/jar/jar.html#versioning">
* The JAR File Specification: Package Versioning</a>
* @see <a href="../../../technotes/guides/jar/jar.html#sealing">
* The JAR File Specification: Package Sealing</a>
*/
@ -2884,7 +2882,7 @@ public abstract class ClassLoader {
} catch (NoSuchFieldException e) {
throw new InternalError(e);
}
return unsafe.compareAndSwapObject(this, offset, null, obj);
return unsafe.compareAndSetObject(this, offset, null, obj);
}
}

View File

@ -102,9 +102,13 @@ import jdk.internal.reflect.Reflection;
* with the {@link Package#getPackages Package.getPackages()} and
* {@link ClassLoader#getDefinedPackages} methods.
*
* @implNote
* The <a href="ClassLoader.html#builtinLoaders">builtin class loaders</a>
* do not explicitly define {@code Package} objects for packages in
* <em>named modules</em>. Instead those packages are automatically defined
* and have no specification and implementation versioning information.
*
* @jvms 5.3 Run-time package
* @see <a href="../../../technotes/guides/jar/jar.html#versioning">
* The JAR File Specification: Package Versioning</a>
* @see <a href="../../../technotes/guides/jar/jar.html#sealing">
* The JAR File Specification: Package Sealing</a>
* @see ClassLoader#definePackage(String, String, String, String, String, String, String, URL)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -125,7 +125,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean compareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
return UNSAFE.compareAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -133,7 +133,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ compareAndExchange(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
return UNSAFE.compareAndExchange$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
return UNSAFE.compareAndExchange$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -157,7 +157,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetPlain(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
return UNSAFE.weakCompareAndSet$Type$Plain(Objects.requireNonNull(handle.receiverType.cast(holder)),
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -165,7 +165,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
return UNSAFE.weakCompareAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -173,7 +173,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
return UNSAFE.weakCompareAndSet$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -181,7 +181,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
return UNSAFE.weakCompareAndSet$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -275,7 +275,7 @@ final class VarHandle$Type$s {
handle.fieldOffset,
value);
}
@ForceInline
static $type$ getAndBitwiseXor(FieldInstanceReadWrite handle, Object holder, $type$ value) {
return UNSAFE.getAndBitwiseXor$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
@ -392,7 +392,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean compareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
return UNSAFE.compareAndSwap$Type$(handle.base,
return UNSAFE.compareAndSet$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -401,7 +401,7 @@ final class VarHandle$Type$s {
@ForceInline
static $type$ compareAndExchange(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
return UNSAFE.compareAndExchange$Type$Volatile(handle.base,
return UNSAFE.compareAndExchange$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -425,7 +425,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetPlain(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$(handle.base,
return UNSAFE.weakCompareAndSet$Type$Plain(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -433,7 +433,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$Volatile(handle.base,
return UNSAFE.weakCompareAndSet$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -441,7 +441,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base,
return UNSAFE.weakCompareAndSet$Type$Acquire(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -449,7 +449,7 @@ final class VarHandle$Type$s {
@ForceInline
static boolean weakCompareAndSetRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$Release(handle.base,
return UNSAFE.weakCompareAndSet$Type$Release(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
@ -689,7 +689,7 @@ final class VarHandle$Type$s {
#else[Object]
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.compareAndSwap$Type$(array,
return UNSAFE.compareAndSet$Type$(array,
(((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
@ -702,7 +702,7 @@ final class VarHandle$Type$s {
#else[Object]
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.compareAndExchange$Type$Volatile(array,
return UNSAFE.compareAndExchange$Type$(array,
(((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
@ -741,7 +741,7 @@ final class VarHandle$Type$s {
#else[Object]
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.weakCompareAndSwap$Type$(array,
return UNSAFE.weakCompareAndSet$Type$Plain(array,
(((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
@ -754,7 +754,7 @@ final class VarHandle$Type$s {
#else[Object]
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.weakCompareAndSwap$Type$Volatile(array,
return UNSAFE.weakCompareAndSet$Type$(array,
(((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
@ -767,7 +767,7 @@ final class VarHandle$Type$s {
#else[Object]
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.weakCompareAndSwap$Type$Acquire(array,
return UNSAFE.weakCompareAndSet$Type$Acquire(array,
(((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
@ -780,7 +780,7 @@ final class VarHandle$Type$s {
#else[Object]
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.weakCompareAndSwap$Type$Release(array,
return UNSAFE.weakCompareAndSet$Type$Release(array,
(((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
@ -897,7 +897,7 @@ final class VarHandle$Type$s {
(((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
value);
}
@ForceInline
static $type$ getAndBitwiseXor(Array handle, Object oarray, int index, $type$ value) {
$type$[] array = ($type$[]) oarray;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -186,7 +186,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean compareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
byte[] ba = (byte[]) oba;
return UNSAFE.compareAndSwap$RawType$(
return UNSAFE.compareAndSet$RawType$(
ba,
address(ba, index(ba, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -196,7 +196,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static $type$ compareAndExchange(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
byte[] ba = (byte[]) oba;
return convEndian(handle.be,
UNSAFE.compareAndExchange$RawType$Volatile(
UNSAFE.compareAndExchange$RawType$(
ba,
address(ba, index(ba, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)));
@ -225,7 +225,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean weakCompareAndSetPlain(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
byte[] ba = (byte[]) oba;
return UNSAFE.weakCompareAndSwap$RawType$(
return UNSAFE.weakCompareAndSet$RawType$Plain(
ba,
address(ba, index(ba, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -234,7 +234,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean weakCompareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
byte[] ba = (byte[]) oba;
return UNSAFE.weakCompareAndSwap$RawType$Volatile(
return UNSAFE.weakCompareAndSet$RawType$(
ba,
address(ba, index(ba, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -243,7 +243,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
byte[] ba = (byte[]) oba;
return UNSAFE.weakCompareAndSwap$RawType$Acquire(
return UNSAFE.weakCompareAndSet$RawType$Acquire(
ba,
address(ba, index(ba, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -252,7 +252,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean weakCompareAndSetRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
byte[] ba = (byte[]) oba;
return UNSAFE.weakCompareAndSwap$RawType$Release(
return UNSAFE.weakCompareAndSet$RawType$Release(
ba,
address(ba, index(ba, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -336,7 +336,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(ba, offset,
} while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta)));
return expectedValue;
}
@ -389,7 +389,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(ba, offset,
} while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value)));
return expectedValue;
}
@ -440,7 +440,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(ba, offset,
} while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value)));
return expectedValue;
}
@ -491,7 +491,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(ba, offset,
} while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value)));
return expectedValue;
}
@ -625,7 +625,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean compareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb;
return UNSAFE.compareAndSwap$RawType$(
return UNSAFE.compareAndSet$RawType$(
UNSAFE.getObject(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -635,7 +635,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static $type$ compareAndExchange(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb;
return convEndian(handle.be,
UNSAFE.compareAndExchange$RawType$Volatile(
UNSAFE.compareAndExchange$RawType$(
UNSAFE.getObject(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)));
@ -664,7 +664,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean weakCompareAndSetPlain(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb;
return UNSAFE.weakCompareAndSwap$RawType$(
return UNSAFE.weakCompareAndSet$RawType$Plain(
UNSAFE.getObject(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -673,7 +673,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean weakCompareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb;
return UNSAFE.weakCompareAndSwap$RawType$Volatile(
return UNSAFE.weakCompareAndSet$RawType$(
UNSAFE.getObject(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -682,7 +682,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb;
return UNSAFE.weakCompareAndSwap$RawType$Acquire(
return UNSAFE.weakCompareAndSet$RawType$Acquire(
UNSAFE.getObject(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -691,7 +691,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static boolean weakCompareAndSetRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb;
return UNSAFE.weakCompareAndSwap$RawType$Release(
return UNSAFE.weakCompareAndSet$RawType$Release(
UNSAFE.getObject(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -776,7 +776,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(base, offset,
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta)));
return expectedValue;
}
@ -830,7 +830,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(base, offset,
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value)));
return expectedValue;
}
@ -882,12 +882,12 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(base, offset,
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value)));
return expectedValue;
}
@ForceInline
static $type$ getAndBitwiseXor(ByteBufferHandle handle, Object obb, int index, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb;
@ -935,7 +935,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(base, offset,
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value)));
return expectedValue;
}

View File

@ -768,7 +768,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
Node<K,V> c, Node<K,V> v) {
return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
return U.compareAndSetObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
}
static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) {
@ -2299,7 +2299,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
while ((tab = table) == null || tab.length == 0) {
if ((sc = sizeCtl) < 0)
Thread.yield(); // lost initialization race; just spin
else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
else if (U.compareAndSetInt(this, SIZECTL, sc, -1)) {
try {
if ((tab = table) == null || tab.length == 0) {
int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
@ -2330,13 +2330,13 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
private final void addCount(long x, int check) {
CounterCell[] as; long b, s;
if ((as = counterCells) != null ||
!U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {
!U.compareAndSetLong(this, BASECOUNT, b = baseCount, s = b + x)) {
CounterCell a; long v; int m;
boolean uncontended = true;
if (as == null || (m = as.length - 1) < 0 ||
(a = as[ThreadLocalRandom.getProbe() & m]) == null ||
!(uncontended =
U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {
U.compareAndSetLong(a, CELLVALUE, v = a.value, v + x))) {
fullAddCount(x, uncontended);
return;
}
@ -2354,10 +2354,10 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
transferIndex <= 0)
break;
if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
}
else if (U.compareAndSwapInt(this, SIZECTL, sc,
else if (U.compareAndSetInt(this, SIZECTL, sc,
(rs << RESIZE_STAMP_SHIFT) + 2))
transfer(tab, null);
s = sumCount();
@ -2378,7 +2378,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || transferIndex <= 0)
break;
if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) {
if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1)) {
transfer(tab, nextTab);
break;
}
@ -2401,7 +2401,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
Node<K,V>[] tab = table; int n;
if (tab == null || (n = tab.length) == 0) {
n = (sc > c) ? sc : c;
if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
if (U.compareAndSetInt(this, SIZECTL, sc, -1)) {
try {
if (table == tab) {
@SuppressWarnings("unchecked")
@ -2418,7 +2418,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
break;
else if (tab == table) {
int rs = resizeStamp(n);
if (U.compareAndSwapInt(this, SIZECTL, sc,
if (U.compareAndSetInt(this, SIZECTL, sc,
(rs << RESIZE_STAMP_SHIFT) + 2))
transfer(tab, null);
}
@ -2459,7 +2459,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
i = -1;
advance = false;
}
else if (U.compareAndSwapInt
else if (U.compareAndSetInt
(this, TRANSFERINDEX, nextIndex,
nextBound = (nextIndex > stride ?
nextIndex - stride : 0))) {
@ -2476,7 +2476,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
sizeCtl = (n << 1) - (n >>> 1);
return;
}
if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) {
if (U.compareAndSetInt(this, SIZECTL, sc = sizeCtl, sc - 1)) {
if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT)
return;
finishing = advance = true;
@ -2601,7 +2601,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
if (cellsBusy == 0) { // Try to attach new Cell
CounterCell r = new CounterCell(x); // Optimistic create
if (cellsBusy == 0 &&
U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
U.compareAndSetInt(this, CELLSBUSY, 0, 1)) {
boolean created = false;
try { // Recheck under lock
CounterCell[] rs; int m, j;
@ -2623,14 +2623,14 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))
else if (U.compareAndSetLong(a, CELLVALUE, v = a.value, v + x))
break;
else if (counterCells != as || n >= NCPU)
collide = false; // At max size or stale
else if (!collide)
collide = true;
else if (cellsBusy == 0 &&
U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
U.compareAndSetInt(this, CELLSBUSY, 0, 1)) {
try {
if (counterCells == as) {// Expand table unless stale
CounterCell[] rs = new CounterCell[n << 1];
@ -2647,7 +2647,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
h = ThreadLocalRandom.advanceProbe(h);
}
else if (cellsBusy == 0 && counterCells == as &&
U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
U.compareAndSetInt(this, CELLSBUSY, 0, 1)) {
boolean init = false;
try { // Initialize table
if (counterCells == as) {
@ -2662,7 +2662,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
if (init)
break;
}
else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x))
else if (U.compareAndSetLong(this, BASECOUNT, v = baseCount, v + x))
break; // Fall back on using base
}
}
@ -2858,7 +2858,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
* Acquires write lock for tree restructuring.
*/
private final void lockRoot() {
if (!U.compareAndSwapInt(this, LOCKSTATE, 0, WRITER))
if (!U.compareAndSetInt(this, LOCKSTATE, 0, WRITER))
contendedLock(); // offload to separate method
}
@ -2876,14 +2876,14 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
boolean waiting = false;
for (int s;;) {
if (((s = lockState) & ~WAITER) == 0) {
if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) {
if (U.compareAndSetInt(this, LOCKSTATE, s, WRITER)) {
if (waiting)
waiter = null;
return;
}
}
else if ((s & WAITER) == 0) {
if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) {
if (U.compareAndSetInt(this, LOCKSTATE, s, s | WAITER)) {
waiting = true;
waiter = Thread.currentThread();
}
@ -2908,7 +2908,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
return e;
e = e.next;
}
else if (U.compareAndSwapInt(this, LOCKSTATE, s,
else if (U.compareAndSetInt(this, LOCKSTATE, s,
s + READER)) {
TreeNode<K,V> r, p;
try {

View File

@ -140,7 +140,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expectedValue, int newValue) {
return U.compareAndSwapInt(this, VALUE, expectedValue, newValue);
return U.compareAndSetInt(this, VALUE, expectedValue, newValue);
}
/**
@ -161,7 +161,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
*/
@Deprecated(since="9")
public final boolean weakCompareAndSet(int expectedValue, int newValue) {
return U.weakCompareAndSwapInt(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetIntPlain(this, VALUE, expectedValue, newValue);
}
/**
@ -175,7 +175,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @since 9
*/
public final boolean weakCompareAndSetPlain(int expectedValue, int newValue) {
return U.weakCompareAndSwapInt(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetIntPlain(this, VALUE, expectedValue, newValue);
}
/**
@ -473,7 +473,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @since 9
*/
public final int compareAndExchange(int expectedValue, int newValue) {
return U.compareAndExchangeIntVolatile(this, VALUE, expectedValue, newValue);
return U.compareAndExchangeInt(this, VALUE, expectedValue, newValue);
}
/**
@ -520,7 +520,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @since 9
*/
public final boolean weakCompareAndSetVolatile(int expectedValue, int newValue) {
return U.weakCompareAndSwapIntVolatile(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetInt(this, VALUE, expectedValue, newValue);
}
/**
@ -535,7 +535,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @since 9
*/
public final boolean weakCompareAndSetAcquire(int expectedValue, int newValue) {
return U.weakCompareAndSwapIntAcquire(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetIntAcquire(this, VALUE, expectedValue, newValue);
}
/**
@ -550,7 +550,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @since 9
*/
public final boolean weakCompareAndSetRelease(int expectedValue, int newValue) {
return U.weakCompareAndSwapIntRelease(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetIntRelease(this, VALUE, expectedValue, newValue);
}
}

View File

@ -481,12 +481,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
public final boolean compareAndSet(T obj, int expect, int update) {
accessCheck(obj);
return U.compareAndSwapInt(obj, offset, expect, update);
return U.compareAndSetInt(obj, offset, expect, update);
}
public final boolean weakCompareAndSet(T obj, int expect, int update) {
accessCheck(obj);
return U.compareAndSwapInt(obj, offset, expect, update);
return U.compareAndSetInt(obj, offset, expect, update);
}
public final void set(T obj, int newValue) {

View File

@ -56,7 +56,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
/**
* Records whether the underlying JVM supports lockless
* compareAndSwap for longs. While the intrinsic compareAndSwapLong
* compareAndSet for longs. While the intrinsic compareAndSetLong
* method works in either case, some constructions should be
* handled at Java level to avoid locking user-visible locks.
*/
@ -119,7 +119,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
*/
public final void set(long newValue) {
// Use putLongVolatile instead of ordinary volatile store when
// using compareAndSwapLong, for sake of some 32bit systems.
// using compareAndSetLong, for sake of some 32bit systems.
U.putLongVolatile(this, VALUE, newValue);
}
@ -156,7 +156,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(long expectedValue, long newValue) {
return U.compareAndSwapLong(this, VALUE, expectedValue, newValue);
return U.compareAndSetLong(this, VALUE, expectedValue, newValue);
}
/**
@ -177,7 +177,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
*/
@Deprecated(since="9")
public final boolean weakCompareAndSet(long expectedValue, long newValue) {
return U.weakCompareAndSwapLong(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetLongPlain(this, VALUE, expectedValue, newValue);
}
/**
@ -191,7 +191,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @since 9
*/
public final boolean weakCompareAndSetPlain(long expectedValue, long newValue) {
return U.weakCompareAndSwapLong(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetLongPlain(this, VALUE, expectedValue, newValue);
}
/**
@ -487,7 +487,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @since 9
*/
public final long compareAndExchange(long expectedValue, long newValue) {
return U.compareAndExchangeLongVolatile(this, VALUE, expectedValue, newValue);
return U.compareAndExchangeLong(this, VALUE, expectedValue, newValue);
}
/**
@ -534,7 +534,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @since 9
*/
public final boolean weakCompareAndSetVolatile(long expectedValue, long newValue) {
return U.weakCompareAndSwapLongVolatile(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetLong(this, VALUE, expectedValue, newValue);
}
/**
@ -549,7 +549,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @since 9
*/
public final boolean weakCompareAndSetAcquire(long expectedValue, long newValue) {
return U.weakCompareAndSwapLongAcquire(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetLongAcquire(this, VALUE, expectedValue, newValue);
}
/**
@ -564,7 +564,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @since 9
*/
public final boolean weakCompareAndSetRelease(long expectedValue, long newValue) {
return U.weakCompareAndSwapLongRelease(this, VALUE, expectedValue, newValue);
return U.weakCompareAndSetLongRelease(this, VALUE, expectedValue, newValue);
}
}

View File

@ -454,12 +454,12 @@ public abstract class AtomicLongFieldUpdater<T> {
public final boolean compareAndSet(T obj, long expect, long update) {
accessCheck(obj);
return U.compareAndSwapLong(obj, offset, expect, update);
return U.compareAndSetLong(obj, offset, expect, update);
}
public final boolean weakCompareAndSet(T obj, long expect, long update) {
accessCheck(obj);
return U.compareAndSwapLong(obj, offset, expect, update);
return U.compareAndSetLong(obj, offset, expect, update);
}
public final void set(T obj, long newValue) {

View File

@ -432,14 +432,14 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
public final boolean compareAndSet(T obj, V expect, V update) {
accessCheck(obj);
valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
return U.compareAndSetObject(obj, offset, expect, update);
}
public final boolean weakCompareAndSet(T obj, V expect, V update) {
// same implementation as strong form for now
accessCheck(obj);
valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
return U.compareAndSetObject(obj, offset, expect, update);
}
public final void set(T obj, V newValue) {

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,51 @@
/**
* Defines the foundational APIs of the Java SE Platform.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Providers:</dt>
* <dd> The JDK implementation of this module provides an implementation of
* the {@index jrt jrt} {@linkplain java.nio.file.spi.FileSystemProvider
* file system provider} to enumerate and read the class and resource
* files in a run-time image.
* The jrt file system can be created by calling
* {@link java.nio.file.FileSystems#newFileSystem
* FileSystems.newFileSystem(URI.create("jrt:/"))}.
* <p></dd>
* <dt class="simpleTagLabel">Tool Guides:</dt>
* <dd> {@extLink java_tool_reference java launcher},
* {@extLink keytool_tool_reference keytool}</dd>
* </dl>
*
* @provides java.nio.file.spi.FileSystemProvider
*
* @uses java.lang.System.LoggerFinder
* @uses java.net.ContentHandlerFactory
* @uses java.net.spi.URLStreamHandlerProvider
* @uses java.nio.channels.spi.AsynchronousChannelProvider
* @uses java.nio.channels.spi.SelectorProvider
* @uses java.nio.charset.spi.CharsetProvider
* @uses java.nio.file.spi.FileSystemProvider
* @uses java.nio.file.spi.FileTypeDetector
* @uses java.security.Provider
* @uses java.text.spi.BreakIteratorProvider
* @uses java.text.spi.CollatorProvider
* @uses java.text.spi.DateFormatProvider
* @uses java.text.spi.DateFormatSymbolsProvider
* @uses java.text.spi.DecimalFormatSymbolsProvider
* @uses java.text.spi.NumberFormatProvider
* @uses java.time.chrono.AbstractChronology
* @uses java.time.chrono.Chronology
* @uses java.time.zone.ZoneRulesProvider
* @uses java.util.spi.CalendarDataProvider
* @uses java.util.spi.CalendarNameProvider
* @uses java.util.spi.CurrencyNameProvider
* @uses java.util.spi.LocaleNameProvider
* @uses java.util.spi.ResourceBundleControlProvider
* @uses java.util.spi.ResourceBundleProvider
* @uses java.util.spi.TimeZoneNameProvider
* @uses java.util.spi.ToolProvider
* @uses javax.security.auth.spi.LoginModule
*
* @moduleGraph
* @since 9
*/

View File

@ -1,362 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](input.html) | [NEXT](version.html)'
include-after: '[CONTENTS](index.html) | [PREV](input.html) | [NEXT](version.html)'
title: 'Java Object Serialization Specification: 4 - Class Descriptors'
---
- [The ObjectStreamClass Class](#the-objectstreamclass-class)
- [Dynamic Proxy Class Descriptors](#dynamic-proxy-class-descriptors)
- [Serialized Form](#serialized-form)
- [The ObjectStreamField Class](#the-objectstreamfield-class)
- [Inspecting Serializable Classes](#inspecting-serializable-classes)
- [Stream Unique Identifiers](#stream-unique-identifiers)
-------------------------------------------------------------------------------
## 4.1 The ObjectStreamClass Class
The `ObjectStreamClass` provides information about classes that are saved in a
Serialization stream. The descriptor provides the fully-qualified name of the
class and its serialization version UID. A `SerialVersionUID` identifies the
unique original class version for which this class is capable of writing
streams and from which it can read.
```
package java.io;
public class ObjectStreamClass
{
public static ObjectStreamClass lookup(Class cl);
public static ObjectStreamClass lookupAny(Class cl);
public String getName();
public Class forClass();
public ObjectStreamField[] getFields();
public long getSerialVersionUID();
public String toString();
}
```
The `lookup` method returns the `ObjectStreamClass` descriptor for the
specified class in the virtual machine. If the class has defined
`serialVersionUID` it is retrieved from the class. If the `serialVersionUID` is
not defined by the class, it is computed from the definition of the class in
the virtual machine. *I*f the specified class is not serializable or
externalizable, *null* is returned.
The `lookupAny` method behaves like the `lookup` method, except that it returns
the descriptor for any class, regardless of whether it implements
`Serializable`. The `serialVersionUID` of a class that does not implement
`Serializable` is *0L.*
The `getName` method returns the name of the class, in the same format that is
used by the `Class.getName` method.
The `forClass` method returns the `Class` in the local virtual machine if one
was found by `ObjectInputStream.resolveClass` method. Otherwise, it returns
*null*.
The `getFields` method returns an array of `ObjectStreamField` objects that
represent the serializable fields of this class.
The `getSerialVersionUID` method returns the `serialVersionUID` of this class.
Refer to [Section 4.6, "Stream Unique
Identifiers"](#stream-unique-identifiers). If not specified by the class, the
value returned is a hash computed from the class's name, interfaces, methods,
and fields using the Secure Hash Algorithm (SHA) as defined by the National
Institute of Standards.
The `toString` method returns a printable representation of the class
descriptor including the name of the class and the `serialVersionUID`.
## 4.2 Dynamic Proxy Class Descriptors
ObjectStreamClass descriptors are also used to provide information about
dynamic proxy classes (e.g., classes obtained via calls to the getProxyClass
method of java.lang.reflect.Proxy) saved in a serialization stream. A dynamic
proxy class itself has no serializable fields and a serialVersionUID of 0L. In
other words, when the Class object for a dynamic proxy class is passed to the
static lookup method of ObjectStreamClass, the returned ObjectStreamClass
instance will have the following properties:
- Invoking its getSerialVersionUID method will return 0L.
- Invoking its getFields method will return an array of length zero.
- Invoking its getField method with any String argument will return null.
## 4.3 Serialized Form
The serialized form of an ObjectStreamClass instance depends on whether or not
the Class object it represents is serializable, externalizable, or a dynamic
proxy class.
When an `ObjectStreamClass` instance that does not represent a dynamic proxy
class is written to the stream, it writes the class name and
`serialVersionUID`, flags, and the number of fields. Depending on the class,
additional information may be written:
- For non-serializable classes, the number of fields is always zero. Neither
the `SC_SERIALIZABLE` nor the `SC_EXTERNALIZABLE` flag bits are set.
- For serializable classes, the `SC_SERIALIZABLE` flag is set, the number of
fields counts the number of serializable fields and is followed by a
descriptor for each serializable field. The descriptors are written in
canonical order. The descriptors for primitive typed fields are written
first sorted by field name followed by descriptors for the object typed
fields sorted by field name. The names are sorted using `String.compareTo`.
For details of the format, refer to [Section 6.4, "Grammar for the Stream
Format"](protocol.html#grammar-for-the-stream-format).
- For externalizable classes, flags includes the `SC_EXTERNALIZABLE` flag,
and the number of fields is always zero.
- For enum types, flags includes the `SC_ENUM` flag, and the number of fields
is always zero.
When an ObjectOutputStream serializes the ObjectStreamClass descriptor for a
dynamic proxy class, as determined by passing its Class object to the
isProxyClass method of java.lang.reflect.Proxy, it writes the number of
interfaces that the dynamic proxy class implements, followed by the interface
names. Interfaces are listed in the order that they are returned by invoking
the getInterfaces method on the Class object of the dynamic proxy class.
The serialized representations of ObjectStreamClass descriptors for dynamic
proxy classes and non-dynamic proxy classes are differentiated through the use
of different typecodes (`TC_PROXYCLASSDESC` and `TC_CLASSDESC`, respectively);
for a more detailed specification of the grammar, see [Section 6.4, "Grammar
for the Stream Format"](protocol.html#grammar-for-the-stream-format).
## 4.4 The ObjectStreamField Class
An `ObjectStreamField` represents a serializable field of a serializable class.
The serializable fields of a class can be retrieved from the
`ObjectStreamClass`.
The special static serializable field, `serialPersistentFields`, is an array of
`ObjectStreamField` components that is used to override the default
serializable fields.
```
package java.io;
public class ObjectStreamField implements Comparable {
public ObjectStreamField(String fieldName,
Class fieldType);
public ObjectStreamField(String fieldName,
Class fieldType,
boolean unshared);
public String getName();
public Class getType();
public String getTypeString();
public char getTypeCode();
public boolean isPrimitive();
public boolean isUnshared();
public int getOffset();
protected void setOffset(int offset);
public int compareTo(Object obj);
public String toString();
}
```
`ObjectStreamField` objects are used to specify the serializable fields of a
class or to describe the fields present in a stream. Its constructors accept
arguments describing the field to represent: a string specifying the name of
the field, a `Class` object specifying the type of the field, and a `boolean`
flag (implicitly `false` for the two-argument constructor) indicating whether
or not values of the represented field should be read and written as "unshared"
objects if default serialization/deserialization is in use (see the
descriptions of the `ObjectInputStream.readUnshared` and
`ObjectOutputStream.writeUnshared` methods in [Section 3.1, "The
ObjectInputStream Class"](input.html#the-objectinputstream-class) and [Section
2.1, "The ObjectOutputStream Class"](output.html#the-objectoutputstream-class),
respectively).
The `getName` method returns the name of the serializable field.
The `getType` method returns the type of the field.
The `getTypeString` method returns the type signature of the field.
The `getTypeCode` method returns a character encoding of the field type ('`B`'
for `byte`, '`C`' for `char`, '`D`' for `double`, '`F`' for `float`, '`I`' for
`int`, '`J`' for `long`, '`L`' for non-array object types, '`S`' for `short`,
'`Z`' for `boolean`, and '`[`' for arrays).
The `isPrimitive` method returns `true` if the field is of primitive type, or
`false` otherwise.
The `isUnshared` method returns `true` if values of the field should be written
as "unshared" objects, or `false` otherwise.
The `getOffset` method returns the offset of the field's value within instance
data of the class defining the field.
The `setOffset` method allows `ObjectStreamField` subclasses to modify the
offset value returned by the `getOffset` method.
The `compareTo` method compares `ObjectStreamFields` for use in sorting.
Primitive fields are ranked as "smaller" than non-primitive fields; fields
otherwise equal are ranked alphabetically.
The `toString` method returns a printable representation with name and type.
## 4.5 Inspecting Serializable Classes
The program *serialver* can be used to find out if a class is serializable and
to get its `serialVersionUID`.
When invoked on the command line with one or more class names, serialver prints
the `serialVersionUID` for each class in a form suitable for copying into an
evolving class. When invoked with no arguments, it prints a usage line.
## 4.6 Stream Unique Identifiers
Each versioned class must identify the original class version for which it is
capable of writing streams and from which it can read. For example, a versioned
class must declare:
```
private static final long serialVersionUID = 3487495895819393L;
```
The stream-unique identifier is a 64-bit hash of the class name, interface
class names, methods, and fields. The value must be declared in all versions of
a class except the first. It may be declared in the original class but is not
required. The value is fixed for all compatible classes. If the SUID is not
declared for a class, the value defaults to the hash for that class. The
`serialVersionUID` for dynamic proxy classes and enum types always have the
value *0L*. Array classes cannot declare an explicit `serialVersionUID`, so
they always have the default computed value, but the requirement for matching
`serialVersionUID` values is waived for array classes.
**Note:** It is strongly recommended that all serializable classes explicitly
declare `serialVersionUID` values, since the default `serialVersionUID`
computation is highly sensitive to class details that may vary depending on
compiler implementations, and can thus result in unexpected `serialVersionUID`
conflicts during deserialization, causing deserialization to fail.
The initial version of an `Externalizable` class must output a stream data
format that is extensible in the future. The initial version of the method
`readExternal` has to be able to read the output format of all future versions
of the method `writeExternal`.
The `serialVersionUID` is computed using the signature of a stream of bytes
that reflect the class definition. The National Institute of Standards and
Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a signature
for the stream. The first two 32-bit quantities are used to form a 64-bit hash.
A `java.lang.DataOutputStream` is used to convert primitive data types to a
sequence of bytes. The values input to the stream are defined by the Java
Virtual Machine (VM) specification for classes. Class modifiers may include the
`ACC_PUBLIC`, `ACC_FINAL`, `ACC_INTERFACE`, and `ACC_ABSTRACT` flags; other
flags are ignored and do not affect `serialVersionUID` computation. Similarly,
for field modifiers, only the `ACC_PUBLIC`, `ACC_PRIVATE`, `ACC_PROTECTED`,
`ACC_STATIC`, `ACC_FINAL`, `ACC_VOLATILE`, and `ACC_TRANSIENT` flags are used
when computing `serialVersionUID` values. For constructor and method modifiers,
only the `ACC_PUBLIC`, `ACC_PRIVATE`, `ACC_PROTECTED`, `ACC_STATIC`,
`ACC_FINAL`, `ACC_SYNCHRONIZED`, `ACC_NATIVE`, `ACC_ABSTRACT` and `ACC_STRICT`
flags are used. Names and descriptors are written in the format used by the
`java.io.DataOutputStream.writeUTF` method.
The sequence of items in the stream is as follows:
1. The class name.
2. The class modifiers written as a 32-bit integer.
3. The name of each interface sorted by name.
4. For each field of the class sorted by field name (except `private static`
and `private transient` fields:
a. The name of the field.
b. The modifiers of the field written as a 32-bit integer.
c. The descriptor of the field.
5. If a class initializer exists, write out the following:
a. The name of the method, `<clinit>`.
b. The modifier of the method, `java.lang.reflect.Modifier.STATIC`,
written as a 32-bit integer.
c. The descriptor of the method, `()V`.
6. For each non-`private` constructor sorted by method name and signature:
a. The name of the method, `<init>`.
b. The modifiers of the method written as a 32-bit integer.
c. The descriptor of the method.
7. For each non-`private` method sorted by method name and signature:
a. The name of the method.
b. The modifiers of the method written as a 32-bit integer.
c. The descriptor of the method.
8. The SHA-1 algorithm is executed on the stream of bytes produced by
`DataOutputStream` and produces five 32-bit values `sha[0..4]`.
9. The hash value is assembled from the first and second 32-bit values of the
SHA-1 message digest. If the result of the message digest, the five 32-bit
words `H0 H1 H2 H3 H4`, is in an array of five `int` values named `sha`,
the hash value would be computed as follows:
```
long hash = ((sha[0] >>> 24) & 0xFF) |
((sha[0] >>> 16) & 0xFF) << 8 |
((sha[0] >>> 8) & 0xFF) << 16 |
((sha[0] >>> 0) & 0xFF) << 24 |
((sha[1] >>> 24) & 0xFF) << 32 |
((sha[1] >>> 16) & 0xFF) << 40 |
((sha[1] >>> 8) & 0xFF) << 48 |
((sha[1] >>> 0) & 0xFF) << 56;
```
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -1,111 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](exceptions.html) | NEXT'
include-after: '[CONTENTS](index.html) | [PREV](exceptions.html) | NEXT'
title: 'Java Object Serialization Specification: C - Example of Serializable Fields'
---
- [Example Alternate Implementation of
java.io.File](#c.1-example-alternate-implementation-of-java.io.file)
-------------------------------------------------------------------------------
## C.1 Example Alternate Implementation of java.io.File
This appendix provides a brief example of how an existing class could be
specified and implemented to interoperate with the existing implementation but
without requiring the same assumptions about the representation of the file
name as a *String*.
The system class `java.io.File` represents a filename and has methods for
parsing, manipulating files and directories by name. It has a single private
field that contains the current file name. The semantics of the methods that
parse paths depend on the current path separator which is held in a static
field. This path separator is part of the serialized state of a file so that
file name can be adjusted when read.
The serialized state of a `File` object is defined as the serializable fields
and the sequence of data values for the file. In this case, there is one of
each.
```
Serializable Fields:
String path; // path name with embedded separators
Serializable Data:
char // path name separator for path name
```
An alternate implementation might be defined as follows:
```
class File implements java.io.Serializable {
...
private String[] pathcomponents;
// Define serializable fields with the ObjectStreamClass
/**
* @serialField path String
* Path components separated by separator.
*/
private static final ObjectStreamField[] serialPersistentFields
= { new ObjectStreamField("path", String.class) };
...
/**
* @serialData Default fields followed by separator character.
*/
private void writeObject(ObjectOutputStream s)
throws IOException
{
ObjectOutputStream.PutField fields = s.putFields();
StringBuffer str = new StringBuffer();
for(int i = 0; i < pathcomponents; i++) {
str.append(separator);
str.append(pathcomponents[i]);
}
fields.put("path", str.toString());
s.writeFields();
s.writeChar(separatorChar); // Add the separator character
}
...
private void readObject(ObjectInputStream s)
throws IOException
{
ObjectInputStream.GetField fields = s.readFields();
String path = (String)fields.get("path", null);
...
char sep = s.readChar(); // read the previous separator char
// parse path into components using the separator
// and store into pathcomponents array.
}
}
```
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -1,97 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](security.html) | [NEXT](examples.html)'
include-after: '[CONTENTS](index.html) | [PREV](security.html) | [NEXT](examples.html)'
title: 'Java Object Serialization Specification: B - Exceptions In Object Serialization'
---
-------------------------------------------------------------------------------
All exceptions thrown by serialization classes are subclasses of
`ObjectStreamException` which is a subclass of `IOException`.
### `ObjectStreamException`
Superclass of all serialization exceptions.
### `InvalidClassException`
Thrown when a class cannot be used to restore objects for any of these reasons:
- The class does not match the serial version of the class in the stream.
- The class contains fields with invalid primitive data types.
- The `Externalizable` class does not have a public no-arg constructor.
- The `Serializable` class can not access the no-arg constructor of its
closest non-Serializable superclass.
### `NotSerializableException`
Thrown by a `readObject` or `writeObject` method to terminate serialization or
deserialization.
### `StreamCorruptedException`
Thrown:
- If the stream header is invalid.
- If control information not found.
- If control information is invalid.
- JDK 1.1.5 or less attempts to call `readExternal` on a `PROTOCOL_VERSION_2`
stream.
### `NotActiveException`
Thrown if `writeObject` state is invalid within the following
`ObjectOutputStream` methods:
- `defaultWriteObject`
- `putFields`
- `writeFields`
Thrown if `readObject` state is invalid within the following
`ObjectInputStream` methods:
- `defaultReadObject`
- `readFields`
- `registerValidation`
### `InvalidObjectException`
Thrown when a restored object cannot be made valid.
### `OptionalDataException`
Thrown by `readObject` when there is primitive data in the stream and an object
is expected. The length field of the exception indicates the number of bytes
that are available in the current block.
### `WriteAbortedException`
Thrown when reading a stream terminated by an exception that occurred while the
stream was being written.
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,132 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: 'CONTENTS | PREV | [NEXT](serial-arch.html)'
include-after: 'CONTENTS | PREV | [NEXT](serial-arch.html)'
title: 'Java Object Serialization Specification: Contents'
---
-------------------------------------------------------------------------------
## Table of Contents
### 1 [System Architecture](serial-arch.html)
- 1.1 [Overview](serial-arch.html#overview)
- 1.2 [Writing to an Object
Stream](serial-arch.html#writing-to-an-object-stream)
- 1.3 [Reading from an Object
Stream](serial-arch.html#reading-from-an-object-stream)
- 1.4 [Object Streams as
Containers](serial-arch.html#object-streams-as-containers)
- 1.5 [Defining Serializable Fields for a
Class](serial-arch.html#defining-serializable-fields-for-a-class)
- 1.6 [Documenting Serializable Fields and Data for a
Class](serial-arch.html#documenting-serializable-fields-and-data-for-a-class)
- 1.7 [Accessing Serializable Fields of a
Class](serial-arch.html#accessing-serializable-fields-of-a-class)
- 1.8 [The ObjectOutput
Interface](serial-arch.html#the-objectoutput-interface)
- 1.9 [The ObjectInput Interface](serial-arch.html#the-objectinput-interface)
- 1.10 [The Serializable
Interface](serial-arch.html#the-serializable-interface)
- 1.11 [The Externalizable
Interface](serial-arch.html#the-externalizable-interface)
- 1.12 [Serialization of Enum
Constants](serial-arch.html#serialization-of-enum-constants)
- 1.13 [Protecting Sensitive
Information](serial-arch.html#protecting-sensitive-information)
### 2 [Object Output Classes](output.html)
- 2.1 [The ObjectOutputStream
Class](output.html#the-objectoutputstream-class)
- 2.2 [The ObjectOutputStream.PutField
Class](output.html#the-objectoutputstream.putfield-class)
- 2.3 [The writeObject Method](output.html#the-writeobject-method)
- 2.4 [The writeExternal Method](output.html#the-writeexternal-method)
- 2.5 [The writeReplace Method](output.html#the-writereplace-method)
- 2.6 [The useProtocolVersion
Method](output.html#the-useprotocolversion-method)
### 3 [Object Input Classes](input.html)
- 3.1 [The ObjectInputStream Class](input.html#the-objectinputstream-class)
- 3.2 [The ObjectInputStream.GetField
Class](input.html#the-objectinputstream.getfield-class)
- 3.3 [The ObjectInputValidation
Interface](input.html#the-objectinputvalidation-interface)
- 3.4 [The readObject Method](input.html#the-readobject-method)
- 3.5 [The readObjectNoData Method](input.html#the-readobjectnodata-method)
- 3.6 [The readExternal Method](input.html#the-readexternal-method)
- 3.7 [The readResolve Method](input.html#the-readresolve-method)
### 4 [Class Descriptors](class.html)
- 4.1 [The ObjectStreamClass Class](class.html#the-objectstreamclass-class)
- 4.2 [Dynamic Proxy Class
Descriptors](class.html#dynamic-proxy-class-descriptors)
- 4.3 [Serialized Form](class.html#serialized-form)
- 4.4 [The ObjectStreamField Class](class.html#the-objectstreamfield-class)
- 4.5 [Inspecting Serializable
Classes](class.html#inspecting-serializable-classes)
- 4.6 [Stream Unique Identifiers](class.html#stream-unique-identifiers)
### 5 [Versioning of Serializable Objects](version.html)
- 5.1 [Overview](version.html#overview)
- 5.2 [Goals](version.html#goals)
- 5.3 [Assumptions](version.html#assumptions)
- 5.4 [Who's Responsible for Versioning of
Streams](version.html#whos-responsible-for-versioning-of-streams)
- 5.5 [Compatible Java Type
Evolution](version.html#compatible-java-type-evolution)
- 5.6 [Type Changes Affecting
Serialization](version.html#type-changes-affecting-serialization)
- 5.6.1 [Incompatible Changes](version.html#incompatible-changes)
- 5.6.2 [Compatible Changes](version.html#compatible-changes)
### 6 [Object Serialization Stream Protocol](protocol.html)
- 6.1 [Overview](protocol.html#overview)
- 6.2 [Stream Elements](protocol.html#stream-elements)
- 6.3 [Stream Protocol Versions](protocol.html#stream-protocol-versions)
- 6.4 [Grammar for the Stream
Format](protocol.html#grammar-for-the-stream-format)
- 6.4.1 [Rules of the Grammar](protocol.html#rules-of-the-grammar)
- 6.4.2 [Terminal Symbols and
Constants](protocol.html#terminal-symbols-and-constants)
### A [Security in Object Serialization](security.html)
### B [Exceptions In Object Serialization](exceptions.html)
### C [Example of Serializable Fields](examples.html)
- [C.1 Example Alternate Implementation of
`java.io.File`](examples.html#c.1-example-alternate-implementation-of-java.io.file)
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -1,672 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](output.html) | [NEXT](class.html)'
include-after: '[CONTENTS](index.html) | [PREV](output.html) | [NEXT](class.html)'
title: 'Java Object Serialization Specification: 3 - Object Input Classes'
---
- [The ObjectInputStream Class](#the-objectinputstream-class)
- [The ObjectInputStream.GetField
Class](#the-objectinputstream.getfield-class)
- [The ObjectInputValidation Interface](#the-objectinputvalidation-interface)
- [The readObject Method](#the-readobject-method)
- [The readExternal Method](#the-readexternal-method)
- [The readResolve Method](#the-readresolve-method)
-------------------------------------------------------------------------------
## 3.1 The ObjectInputStream Class
Class `ObjectInputStream` implements object deserialization. It maintains the
state of the stream including the set of objects already deserialized. Its
methods allow primitive types and objects to be read from a stream written by
`ObjectOutputStream`. It manages restoration of the object and the objects that
it refers to from the stream.
```
package java.io;
public class ObjectInputStream
extends InputStream
implements ObjectInput, ObjectStreamConstants
{
public ObjectInputStream(InputStream in)
throws StreamCorruptedException, IOException;
public final Object readObject()
throws OptionalDataException, ClassNotFoundException,
IOException;
public Object readUnshared()
throws OptionalDataException, ClassNotFoundException,
IOException;
public void defaultReadObject()
throws IOException, ClassNotFoundException,
NotActiveException;
public GetField readFields()
throws IOException;
public synchronized void registerValidation(
ObjectInputValidation obj, int prio)
throws NotActiveException, InvalidObjectException;
protected ObjectStreamClass readClassDescriptor()
throws IOException, ClassNotFoundException;
protected Class resolveClass(ObjectStreamClass v)
throws IOException, ClassNotFoundException;
protected Object resolveObject(Object obj)
throws IOException;
protected boolean enableResolveObject(boolean enable)
throws SecurityException;
protected void readStreamHeader()
throws IOException, StreamCorruptedException;
public int read() throws IOException;
public int read(byte[] data, int offset, int length)
throws IOException
public int available() throws IOException;
public void close() throws IOException;
public boolean readBoolean() throws IOException;
public byte readByte() throws IOException;
public int readUnsignedByte() throws IOException;
public short readShort() throws IOException;
public int readUnsignedShort() throws IOException;
public char readChar() throws IOException;
public int readInt() throws IOException;
public long readLong() throws IOException;
public float readFloat() throws IOException;
public double readDouble() throws IOException;
public void readFully(byte[] data) throws IOException;
public void readFully(byte[] data, int offset, int size)
throws IOException;
public int skipBytes(int len) throws IOException;
public String readLine() throws IOException;
public String readUTF() throws IOException;
// Class to provide access to serializable fields.
static abstract public class GetField
{
public ObjectStreamClass getObjectStreamClass();
public boolean defaulted(String name)
throws IOException, IllegalArgumentException;
public char get(String name, char default)
throws IOException, IllegalArgumentException;
public boolean get(String name, boolean default)
throws IOException, IllegalArgumentException;
public byte get(String name, byte default)
throws IOException, IllegalArgumentException;
public short get(String name, short default)
throws IOException, IllegalArgumentException;
public int get(String name, int default)
throws IOException, IllegalArgumentException;
public long get(String name, long default)
throws IOException, IllegalArgumentException;
public float get(String name, float default)
throws IOException, IllegalArgumentException;
public double get(String name, double default)
throws IOException, IllegalArgumentException;
public Object get(String name, Object default)
throws IOException, IllegalArgumentException;
}
protected ObjectInputStream()
throws StreamCorruptedException, IOException;
protected readObjectOverride()
throws OptionalDataException, ClassNotFoundException,
IOException;
}
```
The single-argument `ObjectInputStream` constructor requires an `InputStream`.
The constructor calls `readStreamHeader` to read and verifies the header and
version written by the corresponding `ObjectOutputStream.writeStreamHeader`
method. If a security manager is installed, this constructor checks for the
`"enableSubclassImplementation"` `SerializablePermission` when invoked directly
or indirectly by the constructor of a subclass which overrides the `readFields`
and/or `readUnshared` methods.
**Note:** The `ObjectInputStream` constructor blocks until it completes reading
the serialization stream header. Code which waits for an `ObjectInputStream` to
be constructed before creating the corresponding `ObjectOutputStream` for that
stream will deadlock, since the `ObjectInputStream` constructor will block
until a header is written to the stream, and the header will not be written to
the stream until the `ObjectOutputStream` constructor executes. This problem
can be resolved by creating the `ObjectOutputStream` before the
`ObjectInputStream`, or otherwise removing the timing dependency between
completion of `ObjectInputStream` construction and the creation of the
`ObjectOutputStream`.
The `readObject` method is used to deserialize an object from the stream. It
reads from the stream to reconstruct an object.
1. If the `ObjectInputStream` subclass is overriding the implementation, call
the `readObjectOverride` method and return. Reimplementation is described
at the end of this section.
2. If a block data record occurs in the stream, throw a `BlockDataException`
with the number of available bytes.
3. If the object in the stream is null, return null.
4. If the object in the stream is a handle to a previous object, return the
object.
5. If the object in the stream is a `Class`, read its `ObjectStreamClass`
descriptor, add it and its handle to the set of known objects, and return
the corresponding `Class` object.
6. If the object in the stream is an `ObjectStreamClass`, read in its data
according to the formats described in [Section 4.3, "Serialized
Form"](class.html#serialized-form). Add it and its handle to the set of
known objects. In versions 1.3 and later of the Java 2 SDK, Standard
Edition, the `readClassDescriptor` method is called to read in the
`ObjectStreamClass` if it represents a class that is not a dynamic proxy
class, as indicated in the stream data. If the class descriptor represents
a dynamic proxy class, call the `resolveProxyClass` method on the stream to
get the local class for the descriptor; otherwise, call the `resolveClass`
method on the stream to get the local class. If the class cannot be
resolved, throw a ClassNotFoundException. Return the resulting
`ObjectStreamClass` object.
7. If the object in the stream is a `String`, read its length information
followed by the contents of the string encoded in modified UTF-8. For
details, refer to [Section 6.2, "Stream
Elements"](protocol.html#stream-elements). Add the `String` and its handle
to the set of known objects, and proceed to Step 12.
8. If the object in the stream is an array, read its `ObjectStreamClass` and
the length of the array. Allocate the array, and add it and its handle in
the set of known objects. Read each element using the appropriate method
for its type and assign it to the array. Proceed to Step 12.
9. If the object in the stream is an enum constant, read its
`ObjectStreamClass` and the enum constant name. If the `ObjectStreamClass`
represents a class that is not an enum type, an `InvalidClassException` is
thrown. Obtain a reference to the enum constant by calling the
`java.lang.Enum.valueOf` method, passing the enum type bound to the
received `ObjectStreamClass` along with the received name as arguments. If
the `valueOf` method throws an `IllegalArgumentException`, an
`InvalidObjectException` is thrown with the `IllegalArgumentException` as
its cause. Add the enum constant and its handle in the set of known
objects, and proceed to Step 12.
10. For all other objects, the `ObjectStreamClass` of the object is read from
the stream. The local class for that `ObjectStreamClass` is retrieved. The
class must be serializable or externalizable, and must not be an enum type.
If the class does not satisfy these criteria, an `InvalidClassException` is
thrown.
11. An instance of the class is allocated. The instance and its handle are
added to the set of known objects. The contents restored appropriately:
a. For serializable objects, the no-arg constructor for the first
non-serializable supertype is run. For serializable classes, the fields
are initialized to the default value appropriate for its type. Then the
fields of each class are restored by calling class-specific
`readObject` methods, or if these are not defined, by calling the
`defaultReadObject` method. Note that field initializers and
constructors are not executed for serializable classes during
deserialization. In the normal case, the version of the class that
wrote the stream will be the same as the class reading the stream. In
this case, all of the supertypes of the object in the stream will match
the supertypes in the currently-loaded class. If the version of the
class that wrote the stream had different supertypes than the loaded
class, the `ObjectInputStream` must be more careful about restoring or
initializing the state of the differing classes. It must step through
the classes, matching the available data in the stream with the classes
of the object being restored. Data for classes that occur in the
stream, but do not occur in the object, is discarded. For classes that
occur in the object, but not in the stream, the class fields are set to
default values by default serialization.
b. For externalizable objects, the no-arg constructor for the class is run
and then the `readExternal` method is called to restore the contents of
the object.
12. Process potential substitutions by the class of the object and/or by a
subclass of `ObjectInputStream`:
a. If the class of the object is not an enum type and defines the
appropriate `readResolve` method, the method is called to allow the
object to replace itself.
b. Then if previously enabled by `enableResolveObject,` the
`resolveObject` method is called to allow subclasses of the stream to
examine and replace the object. If the previous step did replace the
original object, the `resolveObject` method is called with the
replacement object. If a replacement took place, the table of known
objects is updated so the replacement object is associated with the
handle. The replacement object is then returned from `readObject`.
All of the methods for reading primitives types only consume bytes from the
block data records in the stream. If a read for primitive data occurs when the
next item in the stream is an object, the read methods return *-1* or the
`EOFException` as appropriate. The value of a primitive type is read by a
`DataInputStream` from the block data record.
The exceptions thrown reflect errors during the traversal or exceptions that
occur on the underlying stream. If any exception is thrown, the underlying
stream is left in an unknown and unusable state.
When the reset token occurs in the stream, all of the state of the stream is
discarded. The set of known objects is cleared.
When the exception token occurs in the stream, the exception is read and a new
`WriteAbortedException` is thrown with the terminating exception as an
argument. The stream context is reset as described earlier.
The `readUnshared` method is used to read "unshared" objects from the stream.
This method is identical to `readObject`, except that it prevents subsequent
calls to `readObject` and `readUnshared` from returning additional references
to the deserialized instance returned by the original call to `readUnshared`.
Specifically:
- If `readUnshared` is called to deserialize a back-reference (the stream
representation of an object which has been written previously to the
stream), an `ObjectStreamException` will be thrown.
- If `readUnshared` returns successfully, then any subsequent attempts to
deserialize back-references to the stream handle deserialized by
`readUnshared` will cause an `ObjectStreamException` to be thrown.
Deserializing an object via `readUnshared` invalidates the stream handle
associated with the returned object. Note that this in itself does not always
guarantee that the reference returned by `readUnshared` is unique; the
deserialized object may define a `readResolve` method which returns an object
visible to other parties, or `readUnshared` may return a `Class` object or enum
constant obtainable elsewhere in the stream or through external means. If the
deserialized object defines a `readResolve` method and the invocation of that
method returns an array, then `readUnshared` returns a shallow clone of that
array; this guarantees that the returned array object is unique and cannot be
obtained a second time from an invocation of `readObject` or `readUnshared` on
the `ObjectInputStream`, even if the underlying data stream has been
manipulated.
The `defaultReadObject` method is used to read the fields and object from the
stream. It uses the class descriptor in the stream to read the fields in the
canonical order by name and type from the stream. The values are assigned to
the matching fields by name in the current class. Details of the versioning
mechanism can be found in [Section 5.5, "Compatible Java Type
Evolution"](version.html#compatible-java-type-evolution). Any field of the
object that does not appear in the stream is set to its default value. Values
that appear in the stream, but not in the object, are discarded. This occurs
primarily when a later version of a class has written additional fields that do
not occur in the earlier version. This method may only be called from the
`readObject` method while restoring the fields of a class. When called at any
other time, the `NotActiveException` is thrown.
The `readFields` method reads the values of the serializable fields from the
stream and makes them available via the `GetField` class. The `readFields`
method is only callable from within the `readObject` method of a serializable
class. It cannot be called more than once or if `defaultReadObject` has been
called. The `GetFields` object uses the current object's `ObjectStreamClass` to
verify the fields that can be retrieved for this class. The `GetFields` object
returned by `readFields` is only valid during this call to the classes
`readObject` method. The fields may be retrieved in any order. Additional data
may only be read directly from stream after `readFields` has been called.
The `registerValidation` method can be called to request a callback when the
entire graph has been restored but before the object is returned to the
original caller of `readObject`. The order of validate callbacks can be
controlled using the priority. Callbacks registered with higher values are
called before those with lower values. The object to be validated must support
the `ObjectInputValidation` interface and implement the `validateObject`
method. It is only correct to register validations during a call to a class's
`readObject` method. Otherwise, a `NotActiveException` is thrown. If the
callback object supplied to `registerValidation` is null, an
`InvalidObjectException` is thrown.
Starting with the Java SDK, Standard Edition, v1.3, the `readClassDescriptor`
method is used to read in all `ObjectStreamClass` objects.
`readClassDescriptor` is called when the `ObjectInputStream` expects a class
descriptor as the next item in the serialization stream. Subclasses of
`ObjectInputStream` may override this method to read in class descriptors that
have been written in non-standard formats (by subclasses of
`ObjectOutputStream` which have overridden the `writeClassDescriptor` method).
By default, this method reads class descriptors according to the format
described in [Section 6.4, "Grammar for the Stream
Format"](protocol.html#grammar-for-the-stream-format).
The `resolveClass` method is called while a class is being deserialized, and
after the class descriptor has been read. Subclasses may extend this method to
read other information about the class written by the corresponding subclass of
`ObjectOutputStream`. The method must find and return the class with the given
name and `serialVersionUID`. The default implementation locates the class by
calling the class loader of the closest caller of `readObject` that has a class
loader. If the class cannot be found `ClassNotFoundException` should be thrown.
Prior to JDK 1.1.6, the `resolveClass` method was required to return the same
fully qualified class name as the class name in the stream. In order to
accommodate package renaming across releases, `method` `resolveClass` only
needs to return a class with the same base class name and `SerialVersionUID` in
JDK 1.1.6 and later versions.
The `resolveObject` method is used by trusted subclasses to monitor or
substitute one object for another during deserialization. Resolving objects
must be enabled explicitly by calling `enableResolveObject` before calling
`readObject` for the first object to be resolved. Once enabled, `resolveObject`
is called once for each serializable object just prior to the first time it is
being returned from `readObject`. Note that the `resolveObject` method is not
called for objects of the specially handled classes, `Class`,
`ObjectStreamClass`, `String`, and arrays. A subclass's implementation of
`resolveObject` may return a substitute object that will be assigned or
returned instead of the original. The object returned must be of a type that is
consistent and assignable to every reference of the original object or else a
`ClassCastException` will be thrown. All assignments are type-checked. All
references in the stream to the original object will be replaced by references
to the substitute object.
The `enableResolveObject` method is called by trusted subclasses of
`ObjectOutputStream` to enable the monitoring or substitution of one object for
another during deserialization. Replacing objects is disabled until
`enableResolveObject` is called with a `true` value. It may thereafter be
disabled by setting it to `false`. The previous setting is returned. The
`enableResolveObject` method checks if the stream has permission to request
substitution during serialization. To ensure that the private state of objects
is not unintentionally exposed, only trusted streams may use `resolveObject`.
Trusted classes are those classes with a class loader equal to null or belong
to a security protection domain that provides permission to enable
substitution.
If the subclass of `ObjectInputStream` is not considered part of the system
domain, a line has to be added to the security policy file to provide to a
subclass of `ObjectInputStream` permission to call `enableResolveObject`. The
`SerializablePermission` to add is `"enableSubstitution"`.
`AccessControlException` is thrown if the protection domain of the subclass of
`ObjectStreamClass` does not have permission to `"enableSubstitution"` by
calling `enableResolveObject`. See the document Java Security Architecture (JDK
1.2) for additional information about the security model.
The `readStreamHeader` method reads and verifies the magic number and version
of the stream. If they do not match, the `StreamCorruptedMismatch` is thrown.
To override the implementation of deserialization, a subclass of
`ObjectInputStream` should call the protected no-arg `ObjectInputStream`,
constructor. There is a security check within the no-arg constructor for
`SerializablePermission "enableSubclassImplementation"` to ensure that only
trusted classes are allowed to override the default implementation. This
constructor does not allocate any private data for `ObjectInputStream` and sets
a flag that indicates that the final `readObject` method should invoke the
`readObjectOverride` method and return. All other `ObjectInputStream` methods
are not final and can be directly overridden by the subclass.
## 3.2 The ObjectInputStream.GetField Class
The class `ObjectInputStream.GetField` provides the API for getting the values
of serializable fields. The protocol of the stream is the same as used by
`defaultReadObject.` Using `readFields` to access the serializable fields does
not change the format of the stream. It only provides an alternate API to
access the values which does not require the class to have the corresponding
non-transient and non-static fields for each named serializable field. The
serializable fields are those declared using `serialPersistentFields` or if it
is not declared the non-transient and non-static fields of the object. When the
stream is read the available serializable fields are those written to the
stream when the object was serialized. If the class that wrote the stream is a
different version not all fields will correspond to the serializable fields of
the current class. The available fields can be retrieved from the
`ObjectStreamClass` of the `GetField` object.
The `getObjectStreamClass` method returns an `ObjectStreamClass` object
representing the class in the stream. It contains the list of serializable
fields.
The `defaulted` method returns *true* if the field is not present in the
stream. An `IllegalArgumentException` is thrown if the requested field is not a
serializable field of the current class.
Each `get` method returns the specified serializable field from the stream. I/O
exceptions will be thrown if the underlying stream throws an exception. An
`IllegalArgumentException` is thrown if the name or type does not match the
name and type of an field serializable field of the current class. The default
value is returned if the stream does not contain an explicit value for the
field.
## 3.3 The ObjectInputValidation Interface
This interface allows an object to be called when a complete graph of objects
has been deserialized. If the object cannot be made valid, it should throw the
`ObjectInvalidException`. Any exception that occurs during a call to
`validateObject` will terminate the validation process, and the
`InvalidObjectException` will be thrown.
```
package java.io;
public interface ObjectInputValidation
{
public void validateObject()
throws InvalidObjectException;
}
```
## 3.4 The readObject Method
For serializable objects, the `readObject` method allows a class to control the
deserialization of its own fields. Here is its signature:
```
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException;
```
Each subclass of a serializable object may define its own `readObject` method.
If a class does not implement the method, the default serialization provided by
`defaultReadObject` will be used. When implemented, the class is only
responsible for restoring its own fields, not those of its supertypes or
subtypes.
The `readObject` method of the class, if implemented, is responsible for
restoring the state of the class. The values of every field of the object
whether transient or not, static or not are set to the default value for the
fields type. Either `ObjectInputStream`'s `defaultReadObject` or `readFields`
method must be called once (and only once) before reading any optional data
written by the corresponding `writeObject` method; even if no optional data is
read, `defaultReadObject` or `readFields` must still be invoked once. If the
`readObject` method of the class attempts to read more data than is present in
the optional part of the stream for this class, the stream will return `-1` for
bytewise reads, throw an `EOFException` for primitive data reads (e.g.,
`readInt`, `readFloat`), or throw an `OptionalDataException` with the `eof`
field set to `true` for object reads.
The responsibility for the format, structure, and versioning of the optional
data lies completely with the class. The `@serialData` javadoc tag within the
javadoc comment for the `readObject` method should be used to document the
format and structure of the optional data.
If the class being restored is not present in the stream being read, then its
`readObjectNoData` method, if defined, is invoked (instead of `readObject`);
otherwise, its fields are initialized to the appropriate default values. For
further detail, see [Section 3.5, "The readObjectNoData
Method"](#the-readobjectnodata-method).
Reading an object from the `ObjectInputStream` is analogous to creating a new
object. Just as a new object's constructors are invoked in the order from the
superclass to the subclass, an object being read from a stream is deserialized
from superclass to subclass. The `readObject` or `readObjectNoData` method is
called instead of the constructor for each `Serializable` subclass during
deserialization.
One last similarity between a constructor and a `readObject` method is that
both provide the opportunity to invoke a method on an object that is not fully
constructed. Any overridable (neither private, static nor final) method called
while an object is being constructed can potentially be overridden by a
subclass. Methods called during the construction phase of an object are
resolved by the actual type of the object, not the type currently being
initialized by either its constructor or `readObject`/`readObjectNoData`
method. Therefore, calling an overridable method from within a `readObject` or
`readObjectNoData` method may result in the unintentional invocation of a
subclass method before the superclass has been fully initialized.
## 3.5 The readObjectNoData Method
For serializable objects, the `readObjectNoData` method allows a class to
control the initialization of its own fields in the event that a subclass
instance is deserialized and the serialization stream does not list the class
in question as a superclass of the deserialized object. This may occur in cases
where the receiving party uses a different version of the deserialized
instance's class than the sending party, and the receiver's version extends
classes that are not extended by the sender's version. This may also occur if
the serialization stream has been tampered; hence, `readObjectNoData` is useful
for initializing deserialized objects properly despite a "hostile" or
incomplete source stream.
```
private void readObjectNoData() throws ObjectStreamException;
```
Each serializable class may define its own `readObjectNoData` method. If a
serializable class does not define a `readObjectNoData` method, then in the
circumstances listed above the fields of the class will be initialized to their
default values (as listed in The Java Language Specification); this behavior is
consistent with that of `ObjectInputStream` prior to version 1.4 of the Java 2
SDK, Standard Edition, when support for `readObjectNoData` methods was
introduced. If a serializable class does define a `readObjectNoData` method and
the aforementioned conditions arise, then `readObjectNoData` will be invoked at
the point during deserialization when a class-defined `readObject` method would
otherwise be called had the class in question been listed by the stream as a
superclass of the instance being deserialized.
## 3.6 The readExternal Method
Objects implementing `java.io.Externalizable` must implement the `readExternal`
method to restore the entire state of the object. It must coordinate with its
superclasses to restore their state. All of the methods of `ObjectInput` are
available to restore the object's primitive typed fields and object fields.
```
public void readExternal(ObjectInput stream)
throws IOException;
```
**Note:** The `readExternal` method is public, and it raises the risk of a
client being able to overwrite an existing object from a stream. The class may
add its own checks to insure that this is only called when appropriate.
A new stream protocol version has been introduced in JDK 1.2 to correct a
problem with `Externalizable` objects. The old definition of `Externalizable`
objects required the local virtual machine to find a `readExternal` method to
be able to properly read an `Externalizable` object from the stream. The new
format adds enough information to the stream protocol so serialization can skip
an `Externalizable` object when the local `readExternal` method is not
available. Due to class evolution rules, serialization must be able to skip an
`Externalizable` object in the input stream if there is not a mapping for the
object using the local classes.
An additional benefit of the new `Externalizable` stream format is that
`ObjectInputStream` can detect attempts to read more External data than is
available, and can also skip by any data that is left unconsumed by a
`readExternal` method. The behavior of `ObjectInputStream` in response to a
read past the end of External data is the same as the behavior when a
class-defined `readObject` method attempts to read past the end of its optional
data: bytewise reads will return `-1`, primitive reads will throw
`EOFException`s, and object reads will throw `OptionalDataException`s with the
`eof` field set to `true`.
Due to the format change, JDK 1.1.6 and earlier releases are not able to read
the new format. `StreamCorruptedException` is thrown when JDK 1.1.6 or earlier
attempts to read an `Externalizable` object from a stream written in
`PROTOCOL_VERSION_2`. Compatibility issues are discussed in more detail in
[Section 6.3, "Stream Protocol
Versions"](protocol.html#stream-protocol-versions).
## 3.7 The readResolve Method
For Serializable and Externalizable classes, the `readResolve` method allows a
class to replace/resolve the object read from the stream before it is returned
to the caller. By implementing the `readResolve` method, a class can directly
control the types and instances of its own instances being deserialized. The
method is defined as follows:
```
ANY-ACCESS-MODIFIER Object readResolve()
throws ObjectStreamException;
```
The `readResolve` method is called when `ObjectInputStream` has read an object
from the stream and is preparing to return it to the caller.
`ObjectInputStream` checks whether the class of the object defines the
`readResolve` method. If the method is defined, the `readResolve` method is
called to allow the object in the stream to designate the object to be
returned. The object returned should be of a type that is compatible with all
uses. If it is not compatible, a `ClassCastException` will be thrown when the
type mismatch is discovered.
For example, a `Symbol` class could be created for which only a single instance
of each symbol binding existed within a virtual machine. The `readResolve`
method would be implemented to determine if that symbol was already defined and
substitute the preexisting equivalent `Symbol` object to maintain the identity
constraint. In this way the uniqueness of `Symbol` objects can be maintained
across serialization.
**Note:** The `readResolve` method is not invoked on the object until the
object is fully constructed, so any references to this object in its object
graph will not be updated to the new object nominated by `readResolve`.
However, during the serialization of an object with the `writeReplace` method,
all references to the original object in the replacement object's object graph
are replaced with references to the replacement object. Therefore in cases
where an object being serialized nominates a replacement object whose object
graph has a reference to the original object, deserialization will result in an
incorrect graph of objects. Furthermore, if the reference types of the object
being read (nominated by `writeReplace`) and the original object are not
compatible, the construction of the object graph will raise a
`ClassCastException`.
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -1,514 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](serial-arch.html) | [NEXT](input.html)'
include-after: '[CONTENTS](index.html) | [PREV](serial-arch.html) | [NEXT](input.html)'
title: 'Java Object Serialization Specification: 2 - Object Output Classes'
---
- [The ObjectOutputStream Class](#the-objectoutputstream-class)
- [The ObjectOutputStream.PutField
Class](#the-objectoutputstream.putfield-class)
- [The writeObject Method](#the-writeobject-method)
- [The writeExternal Method](#the-writeexternal-method)
- [The writeReplace Method](#the-writereplace-method)
- [The useProtocolVersion Method](#the-useprotocolversion-method)
-------------------------------------------------------------------------------
## 2.1 The ObjectOutputStream Class
Class `ObjectOutputStream` implements object serialization. It maintains the
state of the stream including the set of objects already serialized. Its
methods control the traversal of objects to be serialized to save the specified
objects and the objects to which they refer.
```
package java.io;
public class ObjectOutputStream
extends OutputStream
implements ObjectOutput, ObjectStreamConstants
{
public ObjectOutputStream(OutputStream out)
throws IOException;
public final void writeObject(Object obj)
throws IOException;
public void writeUnshared(Object obj)
throws IOException;
public void defaultWriteObject()
throws IOException, NotActiveException;
public PutField putFields()
throws IOException;
public writeFields()
throws IOException;
public void reset() throws IOException;
protected void annotateClass(Class cl) throws IOException;
protected void writeClassDescriptor(ObjectStreamClass desc)
throws IOException;
protected Object replaceObject(Object obj) throws IOException;
protected boolean enableReplaceObject(boolean enable)
throws SecurityException;
protected void writeStreamHeader() throws IOException;
public void write(int data) throws IOException;
public void write(byte b[]) throws IOException;
public void write(byte b[], int off, int len) throws IOException;
public void flush() throws IOException;
protected void drain() throws IOException;
public void close() throws IOException;
public void writeBoolean(boolean data) throws IOException;
public void writeByte(int data) throws IOException;
public void writeShort(int data) throws IOException;
public void writeChar(int data) throws IOException;
public void writeInt(int data) throws IOException;
public void writeLong(long data) throws IOException;
public void writeFloat(float data) throws IOException;
public void writeDouble(double data) throws IOException;
public void writeBytes(String data) throws IOException;
public void writeChars(String data) throws IOException;
public void writeUTF(String data) throws IOException;
// Inner class to provide access to serializable fields.
abstract static public class PutField
{
public void put(String name, boolean value)
throws IOException, IllegalArgumentException;
public void put(String name, char data)
throws IOException, IllegalArgumentException;
public void put(String name, byte data)
throws IOException, IllegalArgumentException;
public void put(String name, short data)
throws IOException, IllegalArgumentException;
public void put(String name, int data)
throws IOException, IllegalArgumentException;
public void put(String name, long data)
throws IOException, IllegalArgumentException;
public void put(String name, float data)
throws IOException, IllegalArgumentException;
public void put(String name, double data)
throws IOException, IllegalArgumentException;
public void put(String name, Object data)
throws IOException, IllegalArgumentException;
}
public void useProtocolVersion(int version) throws IOException;
protected ObjectOutputStream()
throws IOException;
protected writeObjectOverride()
throws NotActiveException, IOException;
}
```
The single-argument `ObjectOutputStream` constructor creates an
`ObjectOutputStream` that serializes objects to the given `OutputStream`. The
constructor calls `writeStreamHeader` to write a magic number and version to
the stream that will be read and verified by a corresponding call to
`readStreamHeader` in the single-argument `ObjectInputStream` constructor. If a
security manager is installed, this constructor checks for the
`"enableSubclassImplementation"` `SerializablePermission` when invoked directly
or indirectly by the constructor of a subclass which overrides the `putFields`
and/or `writeUnshared` methods.
The `writeObject` method is used to serialize an object to the stream. An
object is serialized as follows:
1. If a subclass is overriding the implementation, call the
`writeObjectOverride` method and return. Overriding the implementation is
described at the end of this section.
2. If there is data in the block-data buffer, the data is written to the
stream and the buffer is reset.
3. If the object is null, null is put in the stream and `writeObject` returns.
4. If the object has been previously replaced, as described in Step 8, write
the handle of the replacement to the stream and `writeObject` returns.
5. If the object has already been written to the stream, its handle is written
to the stream and `writeObject` returns.
6. If the object is a `Class`, the corresponding `ObjectStreamClass` is
written to the stream, a handle is assigned for the class, and
`writeObject` returns.
7. If the object is an `ObjectStreamClass`, a handle is assigned to the
object, after which it is written to the stream using one of the class
descriptor formats described in [Section 4.3, "Serialized
Form"](class.html#serialized-form). In versions 1.3 and later of the Java 2
SDK, Standard Edition, the `writeClassDescriptor` method is called to
output the `ObjectStreamClass` if it represents a class that is not a
dynamic proxy class, as determined by passing the associated `Class` object
to the `isProxyClass` method of `java.lang.reflect.Proxy`. Afterwards, an
annotation for the represented class is written: if the class is a dynamic
proxy class, then the `annotateProxyClass` method is called; otherwise, the
`annotateClass` method is called. The `writeObject` method then returns.
8. Process potential substitutions by the class of the object and/or by a
subclass of `ObjectInputStream`.
a. If the class of an object is not an enum type and defines the
appropriate `writeReplace` method, the method is called. Optionally, it
can return a substitute object to be serialized.
b. Then, if enabled by calling the `enableReplaceObject` method, the
`replaceObject` method is called to allow subclasses of
`ObjectOutputStream` to substitute for the object being serialized. If
the original object was replaced in the previous step, the
`replaceObject` method is called with the replacement object.
If the original object was replaced by either one or both steps above, the
mapping from the original object to the replacement is recorded for later
use in Step 4. Then, Steps 3 through 7 are repeated on the new object.
If the replacement object is not one of the types covered by Steps 3
through 7, processing resumes using the replacement object at Step 10.
9. <a id="java-lang-string-encoding"></a>
If the object is a `java.lang.String,` the string is written as length
information followed by the contents of the string encoded in modified
UTF-8. For details, refer to [Section 6.2, "Stream
Elements"](protocol.html#stream-elements). A handle is assigned to the
string, and `writeObject` returns.
10. If the object is an array, `writeObject` is called recursively to write the
`ObjectStreamClass` of the array. The handle for the array is assigned. It
is followed by the length of the array. Each element of the array is then
written to the stream, after which `writeObject` returns.
11. If the object is an enum constant, the `ObjectStreamClass` for the enum
type of the constant is written by recursively calling `writeObject`. It
will appear in the stream only the first time it is referenced. A handle is
assigned for the enum constant. Next, the value returned by the `name`
method of the enum constant is written as a `String` object, as described
in step 9. Note that if the same name string has appeared previously in the
stream, a back reference to it will be written. The `writeObject` method
then returns.
12. For regular objects, the `ObjectStreamClass` for the class of the object is
written by recursively calling `writeObject`. It will appear in the stream
only the first time it is referenced. A handle is assigned for the object.
13. The contents of the object are written to the stream.
a. If the object is serializable, the highest serializable class is
located. For that class, and each derived class, that class's fields
are written. If the class does not have a `writeObject` method, the
`defaultWriteObject` method is called to write the serializable fields
to the stream. If the class does have a `writeObject` method, it is
called. It may call `defaultWriteObject` or `putFields` and
`writeFields` to save the state of the object, and then it can write
other information to the stream.
b. If the object is externalizable, the `writeExternal` method of the
object is called.
c. If the object is neither serializable or externalizable, the
`NotSerializableException` is thrown.
Exceptions may occur during the traversal or may occur in the underlying
stream. For any subclass of `IOException`, the exception is written to the
stream using the exception protocol and the stream state is discarded. If a
second `IOException` is thrown while attempting to write the first exception
into the stream, the stream is left in an unknown state and
`StreamCorruptedException` is thrown from `writeObject`. For other exceptions,
the stream is aborted and left in an unknown and unusable state.
The `writeUnshared` method writes an "unshared" object to the
`ObjectOutputStream`. This method is identical to `writeObject`, except that it
always writes the given object as a new, unique object in the stream (as
opposed to a back-reference pointing to a previously serialized instance).
Specifically:
- An object written via `writeUnshared` is always serialized in the same
manner as a newly appearing object (an object that has not been written to
the stream yet), regardless of whether or not the object has been written
previously.
- If `writeObject` is used to write an object that has been previously
written with `writeUnshared`, the previous `writeUnshared` operation is
treated as if it were a write of a separate object. In other words,
`ObjectOutputStream` will never generate back-references to object data
written by calls to `writeUnshared`.
While writing an object via `writeUnshared` does not in itself guarantee a
unique reference to the object when it is deserialized, it allows a single
object to be defined multiple times in a stream, so that multiple calls to the
`ObjectInputStream.readUnshared` method (see [Section 3.1, "The
ObjectInputStream Class"](input.html#the-objectinputstream-class)) by the
receiver will not conflict. Note that the rules described above only apply to
the base-level object written with `writeUnshared`, and not to any transitively
referenced sub-objects in the object graph to be serialized.
The `defaultWriteObject` method implements the default serialization mechanism
for the current class. This method may be called only from a class's
`writeObject` method. The method writes all of the serializable fields of the
current class to the stream. If called from outside the `writeObject` method,
the `NotActiveException` is thrown.
The `putFields` method returns a `PutField` object the caller uses to set the
values of the serializable fields in the stream. The fields may be set in any
order. After all of the fields have been set, `writeFields` must be called to
write the field values in the canonical order to the stream. If a field is not
set, the default value appropriate for its type will be written to the stream.
This method may only be called from within the `writeObject` method of a
serializable class. It may not be called more than once or if
`defaultWriteObject` has been called. Only after `writeFields` has been called
can other data be written to the stream.
The `reset` method resets the stream state to be the same as if it had just
been constructed. `Reset` will discard the state of any objects already written
to the stream. The current point in the stream is marked as reset, so the
corresponding `ObjectInputStream` will reset at the same point. Objects
previously written to the stream will not be remembered as already having been
written to the stream. They will be written to the stream again. This is useful
when the contents of an object or objects must be sent again. `Reset` may not
be called while objects are being serialized. If called inappropriately, an
`IOException` is thrown.
Starting with the Java 2 SDK, Standard Edition, v1.3, the
`writeClassDescriptor` method is called when an `ObjectStreamClass` needs to be
serialized. `writeClassDescriptor` is responsible for writing a representation
of the `ObjectStreamClass` to the serialization stream. Subclasses may override
this method to customize the way in which class descriptors are written to the
serialization stream. If this method is overridden, then the corresponding
`readClassDescriptor` method in `ObjectInputStream` should also be overridden
to reconstitute the class descriptor from its custom stream representation. By
default, `writeClassDescriptor` writes class descriptors according to the
format specified in [Section 6.4, "Grammar for the Stream
Format"](protocol.html#grammar-for-the-stream-format). Note that this method
will only be called if the `ObjectOutputStream` is not using the old
serialization stream format (see [Section 6.3, "Stream Protocol
Versions"](protocol.html#stream-protocol-versions)). If the serialization
stream is using the old format (`ObjectStreamConstants.PROTOCOL_VERSION_1`),
the class descriptor will be written internally in a manner that cannot be
overridden or customized.
The `annotateClass` method is called while a `Class` is being serialized, and
after the class descriptor has been written to the stream. Subclasses may
extend this method and write other information to the stream about the class.
This information must be read by the `resolveClass` method in a corresponding
`ObjectInputStream` subclass.
An `ObjectOutputStream` subclass can implement the `replaceObject` method to
monitor or replace objects during serialization. Replacing objects must be
enabled explicitly by calling `enableReplaceObject` before calling
`writeObject` with the first object to be replaced. Once enabled,
`replaceObject` is called for each object just prior to serializing the object
for the first time. Note that the `replaceObject` method is not called for
objects of the specially handled classes, `Class` and `ObjectStreamClass`. An
implementation of a subclass may return a substitute object that will be
serialized instead of the original. The substitute object must be serializable.
All references in the stream to the original object will be replaced by the
substitute object.
When objects are being replaced, the subclass must ensure that the substituted
object is compatible with every field where the reference will be stored, or
that a complementary substitution will be made during deserialization. Objects,
whose type is not a subclass of the type of the field or array element, will
later abort the deserialization by raising a `ClassCastException` and the
reference will not be stored.
The `enableReplaceObject` method can be called by trusted subclasses of
`ObjectOutputStream` to enable the substitution of one object for another
during serialization. Replacing objects is disabled until `enableReplaceObject`
is called with a `true` value. It may thereafter be disabled by setting it to
`false`. The previous setting is returned. The `enableReplaceObject` method
checks that the stream requesting the replacement can be trusted. To ensure
that the private state of objects is not unintentionally exposed, only trusted
stream subclasses may use `replaceObject`. Trusted classes are those classes
that belong to a security protection domain with permission to enable
Serializable substitution.
If the subclass of `ObjectOutputStream` is not considered part of the system
domain, `SerializablePermission "enableSubstitution"` must be added to the
security policy file. `AccessControlException` is thrown if the protection
domain of the subclass of `ObjectInputStream` does not have permission to
`"enableSubstitution"` by calling `enableReplaceObject`. See the document Java
Security Architecture (JDK1.2) for additional information about the security
model.
The `writeStreamHeader` method writes the magic number and version to the
stream. This information must be read by the `readStreamHeader` method of
`ObjectInputStream`. Subclasses may need to implement this method to identify
the stream's unique format.
The `flush` method is used to empty any buffers being held by the stream and to
forward the flush to the underlying stream. The `drain` method may be used by
subclassers to empty only the `ObjectOutputStream`'s buffers without forcing
the underlying stream to be flushed.
All of the write methods for primitive types encode their values using a
`DataOutputStream` to put them in the standard stream format. The bytes are
buffered into block data records so they can be distinguished from the encoding
of objects. This buffering allows primitive data to be skipped if necessary for
class versioning. It also allows the stream to be parsed without invoking
class-specific methods.
To override the implementation of serialization, the subclass of
`ObjectOutputStream` should call the protected no-arg `ObjectOutputStream`,
constructor. There is a security check within the no-arg constructor for
`SerializablePermission "enableSubclassImplementation"` to ensure that only
trusted classes are allowed to override the default implementation. This
constructor does not allocate any private data for `ObjectOutputStream` and
sets a flag that indicates that the final `writeObject` method should invoke
the `writeObjectOverride` method and return. All other `ObjectOutputStream`
methods are not final and can be directly overridden by the subclass.
## 2.2 The ObjectOutputStream.PutField Class
Class `PutField` provides the API for setting values of the serializable fields
for a class when the class does not use default serialization. Each method puts
the specified named value into the stream. An `IllegalArgumentException` is
thrown if `name` does not match the name of a serializable field for the class
whose fields are being written, or if the type of the named field does not
match the second parameter type of the specific `put` method invoked.
## 2.3 The writeObject Method
For serializable objects, the `writeObject` method allows a class to control
the serialization of its own fields. Here is its signature:
```
private void writeObject(ObjectOutputStream stream)
throws IOException;
```
Each subclass of a serializable object may define its own `writeObject` method.
If a class does not implement the method, the default serialization provided by
`defaultWriteObject` will be used. When implemented, the class is only
responsible for writing its own fields, not those of its supertypes or
subtypes.
The class's `writeObject` method, if implemented, is responsible for saving the
state of the class. Either `ObjectOutputStream`'s `defaultWriteObject` or
`writeFields` method must be called once (and only once) before writing any
optional data that will be needed by the corresponding `readObject` method to
restore the state of the object; even if no optional data is written,
`defaultWriteObject` or `writeFields` must still be invoked once. If
`defaultWriteObject` or `writeFields` is not invoked once prior to the writing
of optional data (if any), then the behavior of instance deserialization is
undefined in cases where the `ObjectInputStream` cannot resolve the class which
defined the `writeObject` method in question.
The responsibility for the format, structure, and versioning of the optional
data lies completely with the class.
## 2.4 The writeExternal Method
Objects implementing `java.io.Externalizable` must implement the
`writeExternal` method to save the entire state of the object. It must
coordinate with its superclasses to save their state. All of the methods of
`ObjectOutput` are available to save the object's primitive typed fields and
object fields.
```
public void writeExternal(ObjectOutput stream)
throws IOException;
```
A new default format for writing Externalizable data has been introduced in JDK
1.2. The new format specifies that primitive data will be written in block data
mode by `writeExternal` methods. Additionally, a tag denoting the end of the
External object is appended to the stream after the `writeExternal` method
returns. The benefits of this format change are discussed in [Section 3.6, "The
readExternal Method"](input.html#the-readexternal-method). Compatibility issues
caused by this change are discussed in [Section 2.6, "The useProtocolVersion
Method"](#the-useprotocolversion-method).
## 2.5 The writeReplace Method
For Serializable and Externalizable classes, the `writeReplace` method allows a
class of an object to nominate its own replacement in the stream before the
object is written. By implementing the `writeReplace` method, a class can
directly control the types and instances of its own instances being serialized.
The method is defined as follows:
```
ANY-ACCESS-MODIFIER Object writeReplace()
throws ObjectStreamException;
```
The `writeReplace` method is called when `ObjectOutputStream` is preparing to
write the object to the stream. The `ObjectOutputStream` checks whether the
class defines the `writeReplace` method. If the method is defined, the
`writeReplace` method is called to allow the object to designate its
replacement in the stream. The object returned should be either of the same
type as the object passed in or an object that when read and resolved will
result in an object of a type that is compatible with all references to the
object. If it is not, a `ClassCastException` will occur when the type mismatch
is discovered.
## 2.6 The useProtocolVersion Method
Due to a stream protocol change that was not backwards compatible, a mechanism
has been added to enable the current Virtual Machine to write a serialization
stream that is readable by a previous release. Of course, the problems that are
corrected by the new stream format will exist when using the backwards
compatible protocol.
Stream protocol versions are discussed in [Section 6.3, "Stream Protocol
Versions"](protocol.html#stream-protocol-versions).
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -1,504 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](version.html) | [NEXT](security.html)'
include-after: '[CONTENTS](index.html) | [PREV](version.html) | [NEXT](security.html)'
title: 'Java Object Serialization Specification: 6 - Object Serialization Stream Protocol'
---
- [Overview](#overview)
- [Stream Elements](#stream-elements)
- [Stream Protocol Versions](#stream-protocol-versions)
- [Grammar for the Stream Format](#grammar-for-the-stream-format)
- [Example](#example)
-------------------------------------------------------------------------------
## 6.1 Overview
The stream format satisfies the following design goals:
- Is compact and is structured for efficient reading.
- Allows skipping through the stream using only the knowledge of the
structure and format of the stream. Does not require invoking any per class
code.
- Requires only stream access to the data.
## 6.2 Stream Elements
A basic structure is needed to represent objects in a stream. Each attribute of
the object needs to be represented: its classes, its fields, and data written
and later read by class-specific methods. The representation of objects in the
stream can be described with a grammar. There are special representations for
null objects, new objects, classes, arrays, strings, and back references to any
object already in the stream. Each object written to the stream is assigned a
handle that is used to refer back to the object. Handles are assigned
sequentially starting from 0x7E0000. The handles restart at 0x7E0000 when the
stream is reset.
A class object is represented by the following:
- Its `ObjectStreamClass` object.
An `ObjectStreamClass` object for a Class that is not a dynamic proxy class is
represented by the following:
- The Stream Unique Identifier (SUID) of compatible classes.
- A set of flags indicating various properties of the class, such as whether
the class defines a `writeObject` method, and whether the class is
serializable, externalizable, or an enum type
- The number of serializable fields
- The array of fields of the class that are serialized by the default
mechanismFor arrays and object fields, the type of the field is included as
a string which must be in "field descriptor" format (e.g.,
"`Ljava/lang/Object;`") as specified in The Java Virtual Machine
Specification.
- Optional block-data records or objects written by the `annotateClass`
method
- The `ObjectStreamClass` of its supertype (null if the superclass is not
serializable)
An `ObjectStreamClass` object for a dynamic proxy class is represented by the
following:
- The number of interfaces that the dynamic proxy class implements
- The names of all of the interfaces implemented by the dynamic proxy class,
listed in the order that they are returned by invoking the `getInterfaces`
method on the Class object.
- Optional block-data records or objects written by the `annotateProxyClass`
method.
- The ObjectStreamClass of its supertype, `java.lang.reflect.Proxy`.
The representation of `String` objects consists of length information followed
by the contents of the string encoded in modified UTF-8. The modified UTF-8
encoding is the same as used in the Java Virtual Machine and in the
`java.io.DataInput` and `DataOutput` interfaces; it differs from standard UTF-8
in the representation of supplementary characters and of the null character.
The form of the length information depends on the length of the string in
modified UTF-8 encoding. If the modified UTF-8 encoding of the given `String`
is less than 65536 bytes in length, the length is written as 2 bytes
representing an unsigned 16-bit integer. Starting with the Java 2 platform,
Standard Edition, v1.3, if the length of the string in modified UTF-8 encoding
is 65536 bytes or more, the length is written in 8 bytes representing a signed
64-bit integer. The typecode preceding the `String` in the serialization stream
indicates which format was used to write the `String`.
Arrays are represented by the following:
- Their `ObjectStreamClass` object.
- The number of elements.
- The sequence of values. The type of the values is implicit in the type of
the array. for example the values of a byte array are of type byte.
Enum constants are represented by the following:
- The `ObjectStreamClass` object of the constant's base enum type.
- The constant's name string.
New objects in the stream are represented by the following:
- The most derived class of the object.
- Data for each serializable class of the object, with the highest superclass
first. For each class the stream contains the following:
- The serializable fields.See [Section 1.5, "Defining Serializable Fields
for a
Class"](serial-arch.html#defining-serializable-fields-for-a-class).
- If the class has `writeObject`/`readObject` methods, there may be
optional objects and/or block-data records of primitive types written
by the `writeObject` method followed by an `endBlockData` code.
All primitive data written by classes is buffered and wrapped in block-data
records, regardless if the data is written to the stream within a `writeObject`
method or written directly to the stream from outside a `writeObject` method.
This data can only be read by the corresponding `readObject` methods or be read
directly from the stream. Objects written by the `writeObject` method terminate
any previous block-data record and are written either as regular objects or
null or back references, as appropriate. The block-data records allow error
recovery to discard any optional data. When called from within a class, the
stream can discard any data or objects until the `endBlockData`.
## 6.3 Stream Protocol Versions
It was necessary to make a change to the serialization stream format in JDK 1.2
that is not backwards compatible to all minor releases of JDK 1.1. To provide
for cases where backwards compatibility is required, a capability has been
added to indicate what `PROTOCOL_VERSION` to use when writing a serialization
stream. The method `ObjectOutputStream.useProtocolVersion` takes as a parameter
the protocol version to use to write the serialization stream.
The Stream Protocol Versions are as follows:
- `ObjectStreamConstants.PROTOCOL_VERSION_1`: Indicates the initial stream
format.
- `ObjectStreamConstants.PROTOCOL_VERSION_2`: Indicates the new external data
format. Primitive data is written in block data mode and is terminated with
`TC_ENDBLOCKDATA`.
Block data boundaries have been standardized. Primitive data written in
block data mode is normalized to not exceed 1024 byte chunks. The benefit
of this change was to tighten the specification of serialized data format
within the stream. This change is fully backward and forward compatible.
JDK 1.2 defaults to writing `PROTOCOL_VERSION_2`.
JDK 1.1 defaults to writing `PROTOCOL_VERSION_1`.
JDK 1.1.7 and greater can read both versions.
Releases prior to JDK 1.1.7 can only read `PROTOCOL_VERSION_1`.
## 6.4 Grammar for the Stream Format
The table below contains the grammar for the stream format. Nonterminal symbols
are shown in italics. Terminal symbols in a *fixed width font*. Definitions of
nonterminals are followed by a ":". The definition is followed by one or more
alternatives, each on a separate line. The following table describes the
notation:
------------- --------------------------------------------------------------
**Notation** **Meaning**
------------- --------------------------------------------------------------
(*datatype*) This token has the data type specified, such as byte.
*token*\[n\] A predefined number of occurrences of the token, that is an
array.
*x0001* A literal value expressed in hexadecimal. The number of hex
digits reflects the size of the value.
&lt;*xxx*&gt; A value read from the stream used to indicate the length of an
array.
------------- --------------------------------------------------------------
Note that the symbol (utf) is used to designate a string written using 2-byte
length information, and (long-utf) is used to designate a string written using
8-byte length information. For details, refer to [Section 6.2, "Stream
Elements"](#stream-elements).
### 6.4.1 Rules of the Grammar
A Serialized stream is represented by any stream satisfying the *stream* rule.
```
stream:
magic version contents
contents:
content
contents content
content:
object
blockdata
object:
newObject
newClass
newArray
newString
newEnum
newClassDesc
prevObject
nullReference
exception
TC_RESET
newClass:
TC_CLASS classDesc newHandle
classDesc:
newClassDesc
nullReference
(ClassDesc)prevObject // an object required to be of type ClassDesc
superClassDesc:
classDesc
newClassDesc:
TC_CLASSDESC className serialVersionUID newHandle classDescInfo
TC_PROXYCLASSDESC newHandle proxyClassDescInfo
classDescInfo:
classDescFlags fields classAnnotation superClassDesc
className:
(utf)
serialVersionUID:
(long)
classDescFlags:
(byte) // Defined in Terminal Symbols and Constants
proxyClassDescInfo:
(int)<count> proxyInterfaceName[count] classAnnotation
superClassDesc
proxyInterfaceName:
(utf)
fields:
(short)<count> fieldDesc[count]
fieldDesc:
primitiveDesc
objectDesc
primitiveDesc:
prim_typecode fieldName
objectDesc:
obj_typecode fieldName className1
fieldName:
(utf)
className1:
(String)object // String containing the field's type,
// in field descriptor format
classAnnotation:
endBlockData
contents endBlockData // contents written by annotateClass
prim_typecode:
'B' // byte
'C' // char
'D' // double
'F' // float
'I' // integer
'J' // long
'S' // short
'Z' // boolean
obj_typecode:
'[' // array
'L' // object
newArray:
TC_ARRAY classDesc newHandle (int)<size> values[size]
newObject:
TC_OBJECT classDesc newHandle classdata[] // data for each class
classdata:
nowrclass // SC_SERIALIZABLE & classDescFlag &&
// !(SC_WRITE_METHOD & classDescFlags)
wrclass objectAnnotation // SC_SERIALIZABLE & classDescFlag &&
// SC_WRITE_METHOD & classDescFlags
externalContents // SC_EXTERNALIZABLE & classDescFlag &&
// !(SC_BLOCKDATA & classDescFlags
objectAnnotation // SC_EXTERNALIZABLE & classDescFlag&&
// SC_BLOCKDATA & classDescFlags
nowrclass:
values // fields in order of class descriptor
wrclass:
nowrclass
objectAnnotation:
endBlockData
contents endBlockData // contents written by writeObject
// or writeExternal PROTOCOL_VERSION_2.
blockdata:
blockdatashort
blockdatalong
blockdatashort:
TC_BLOCKDATA (unsigned byte)<size> (byte)[size]
blockdatalong:
TC_BLOCKDATALONG (int)<size> (byte)[size]
endBlockData:
TC_ENDBLOCKDATA
externalContent: // Only parseable by readExternal
(bytes) // primitive data
object
externalContents: // externalContent written by
externalContent // writeExternal in PROTOCOL_VERSION_1.
externalContents externalContent
newString:
TC_STRING newHandle (utf)
TC_LONGSTRING newHandle (long-utf)
newEnum:
TC_ENUM classDesc newHandle enumConstantName
enumConstantName:
(String)object
prevObject:
TC_REFERENCE (int)handle
nullReference:
TC_NULL
exception:
TC_EXCEPTION reset (Throwable)object reset
magic:
STREAM_MAGIC
version:
STREAM_VERSION
values: // The size and types are described by the
// classDesc for the current object
newHandle: // The next number in sequence is assigned
// to the object being serialized or deserialized
reset: // The set of known objects is discarded
// so the objects of the exception do not
// overlap with the previously sent objects
// or with objects that may be sent after
// the exception
```
### 6.4.2 Terminal Symbols and Constants
The following symbols in `java.io.ObjectStreamConstants` define the terminal
and constant values expected in a stream.
```
final static short STREAM_MAGIC = (short)0xaced;
final static short STREAM_VERSION = 5;
final static byte TC_NULL = (byte)0x70;
final static byte TC_REFERENCE = (byte)0x71;
final static byte TC_CLASSDESC = (byte)0x72;
final static byte TC_OBJECT = (byte)0x73;
final static byte TC_STRING = (byte)0x74;
final static byte TC_ARRAY = (byte)0x75;
final static byte TC_CLASS = (byte)0x76;
final static byte TC_BLOCKDATA = (byte)0x77;
final static byte TC_ENDBLOCKDATA = (byte)0x78;
final static byte TC_RESET = (byte)0x79;
final static byte TC_BLOCKDATALONG = (byte)0x7A;
final static byte TC_EXCEPTION = (byte)0x7B;
final static byte TC_LONGSTRING = (byte) 0x7C;
final static byte TC_PROXYCLASSDESC = (byte) 0x7D;
final static byte TC_ENUM = (byte) 0x7E;
final static int baseWireHandle = 0x7E0000;
```
The flag byte *classDescFlags* may include values of
```
final static byte SC_WRITE_METHOD = 0x01; //if SC_SERIALIZABLE
final static byte SC_BLOCK_DATA = 0x08; //if SC_EXTERNALIZABLE
final static byte SC_SERIALIZABLE = 0x02;
final static byte SC_EXTERNALIZABLE = 0x04;
final static byte SC_ENUM = 0x10;
```
The flag `SC_WRITE_METHOD` is set if the Serializable class writing the stream
had a `writeObject` method that may have written additional data to the stream.
In this case a `TC_ENDBLOCKDATA` marker is always expected to terminate the
data for that class.
The flag `SC_BLOCKDATA` is set if the `Externalizable` class is written into
the stream using `STREAM_PROTOCOL_2`. By default, this is the protocol used to
write `Externalizable` objects into the stream in JDK 1.2. JDK 1.1 writes
`STREAM_PROTOCOL_1`.
The flag `SC_SERIALIZABLE` is set if the class that wrote the stream extended
`java.io.Serializable` but not `java.io.Externalizable`, the class reading the
stream must also extend `java.io.Serializable` and the default serialization
mechanism is to be used.
The flag `SC_EXTERNALIZABLE` is set if the class that wrote the stream extended
`java.io.Externalizable`, the class reading the data must also extend
`Externalizable` and the data will be read using its `writeExternal` and
`readExternal` methods.
The flag `SC_ENUM` is set if the class that wrote the stream was an enum type.
The receiver's corresponding class must also be an enum type. Data for
constants of the enum type will be written and read as described in [Section
1.12, "Serialization of Enum
Constants"](serial-arch.html#serialization-of-enum-constants).
#### Example
Consider the case of an original class and two instances in a linked list:
```
class List implements java.io.Serializable {
int value;
List next;
public static void main(String[] args) {
try {
List list1 = new List();
List list2 = new List();
list1.value = 17;
list1.next = list2;
list2.value = 19;
list2.next = null;
ByteArrayOutputStream o = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(o);
out.writeObject(list1);
out.writeObject(list2);
out.flush();
...
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
```
The resulting stream contains:
```
00: ac ed 00 05 73 72 00 04 4c 69 73 74 69 c8 8a 15 >....sr..Listi...<
10: 40 16 ae 68 02 00 02 49 00 05 76 61 6c 75 65 4c >Z......I..valueL<
20: 00 04 6e 65 78 74 74 00 06 4c 4c 69 73 74 3b 78 >..nextt..LList;x<
30: 70 00 00 00 11 73 71 00 7e 00 00 00 00 00 13 70 >p....sq.~......p<
40: 71 00 7e 00 03 >q.~..<
```
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -1,38 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](protocol.html) | [NEXT](exceptions.html)'
include-after: '[CONTENTS](index.html) | [PREV](protocol.html) | [NEXT](exceptions.html)'
title: 'Java Object Serialization Specification: A - Security in Object Serialization'
---
-------------------------------------------------------------------------------
Refer to the [Secure Coding Guidelines for the Java Programming
Language](http://www.oracle.com/pls/topic/lookup?ctx=javase9&id=secure_coding_guidelines_javase)
for information about security in object serialization.
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -1,575 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](index.html) | [NEXT](output.html)'
include-after: '[CONTENTS](index.html) | [PREV](index.html) | [NEXT](output.html)'
title: 'Java Object Serialization Specification: 1 - System Architecture'
---
- [Overview](#overview)
- [Writing to an Object Stream](#writing-to-an-object-stream)
- [Reading from an Object Stream](#reading-from-an-object-stream)
- [Object Streams as Containers](#object-streams-as-containers)
- [Defining Serializable Fields for a
Class](#defining-serializable-fields-for-a-class)
- [Documenting Serializable Fields and Data for a
Class](#documenting-serializable-fields-and-data-for-a-class)
- [Accessing Serializable Fields of a
Class](#accessing-serializable-fields-of-a-class)
- [The ObjectOutput Interface](#the-objectoutput-interface)
- [The ObjectInput Interface](#the-objectinput-interface)
- [The Serializable Interface](#the-serializable-interface)
- [The Externalizable Interface](#the-externalizable-interface)
- [Serialization of Enum Constants](#serialization-of-enum-constants)
- [Protecting Sensitive Information](#protecting-sensitive-information)
-------------------------------------------------------------------------------
## 1.1 Overview
The ability to store and retrieve Java^TM^ objects is essential to building all
but the most transient applications. The key to storing and retrieving objects
in a serialized form is representing the state of objects sufficient to
reconstruct the object(s). Objects to be saved in the stream may support either
the `Serializable` or the `Externalizable` interface. For Java^TM^ objects, the
serialized form must be able to identify and verify the Java^TM^ class from
which the contents of the object were saved and to restore the contents to a
new instance. For serializable objects, the stream includes sufficient
information to restore the fields in the stream to a compatible version of the
class. For Externalizable objects, the class is solely responsible for the
external format of its contents.
Objects to be stored and retrieved frequently refer to other objects. Those
other objects must be stored and retrieved at the same time to maintain the
relationships between the objects. When an object is stored, all of the objects
that are reachable from that object are stored as well.
The goals for serializing Java^TM^ objects are to:
- Have a simple yet extensible mechanism.
- Maintain the Java^TM^ object type and safety properties in the serialized
form.
- Be extensible to support marshaling and unmarshaling as needed for remote
objects.
- Be extensible to support simple persistence of Java^TM^ objects.
- Require per class implementation only for customization.
- Allow the object to define its external format.
## 1.2 Writing to an Object Stream
Writing objects and primitives to a stream is a straightforward process. For
example:
```
// Serialize today's date to a file.
FileOutputStream f = new FileOutputStream("tmp");
ObjectOutput s = new ObjectOutputStream(f);
s.writeObject("Today");
s.writeObject(new Date());
s.flush();
```
First an `OutputStream`, in this case a `FileOutputStream`, is needed to
receive the bytes. Then an `ObjectOutputStream` is created that writes to the
`FileOutputStream`. Next, the string "Today" and a Date object are written to
the stream. More generally, objects are written with the `writeObject` method
and primitives are written to the stream with the methods of `DataOutput`.
The `writeObject` method (see [Section 2.3, "The writeObject
Method"](output.html#the-writeobject-method)) serializes the specified object
and traverses its references to other objects in the object graph recursively
to create a complete serialized representation of the graph. Within a stream,
the first reference to any object results in the object being serialized or
externalized and the assignment of a handle for that object. Subsequent
references to that object are encoded as the handle. Using object handles
preserves sharing and circular references that occur naturally in object
graphs. Subsequent references to an object use only the handle allowing a very
compact representation.
Special handling is required for arrays, enum constants, and objects of type
`Class`, `ObjectStreamClass`, and `String`. Other objects must implement either
the `Serializable` or the `Externalizable` interface to be saved in or restored
from a stream.
Primitive data types are written to the stream with the methods in the
`DataOutput` interface, such as `writeInt`, `writeFloat`, or `writeUTF`.
Individual bytes and arrays of bytes are written with the methods of
`OutputStream`. Except for serializable fields, primitive data is written to
the stream in block-data records, with each record prefixed by a marker and an
indication of the number of bytes in the record.
`ObjectOutputStream` can be extended to customize the information about classes
in the stream or to replace objects to be serialized. Refer to the
`annotateClass` and `replaceObject` method descriptions for details.
## 1.3 Reading from an Object Stream
Reading an object from a stream, like writing, is straightforward:
```
// Deserialize a string and date from a file.
FileInputStream in = new FileInputStream("tmp");
ObjectInputStream s = new ObjectInputStream(in);
String today = (String)s.readObject();
Date date = (Date)s.readObject();
```
First an `InputStream`, in this case a `FileInputStream`, is needed as the
source stream. Then an `ObjectInputStream` is created that reads from the
`InputStream`. Next, the string "Today" and a Date object are read from the
stream. Generally, objects are read with the `readObject` method and primitives
are read from the stream with the methods of `DataInput`.
The `readObject` method deserializes the next object in the stream and
traverses its references to other objects recursively to create the complete
graph of objects serialized.
Primitive data types are read from the stream with the methods in the
`DataInput` interface, such as `readInt`, `readFloat`, or `readUTF`. Individual
bytes and arrays of bytes are read with the methods of `InputStream`. Except
for serializable fields, primitive data is read from block-data records.
`ObjectInputStream` can be extended to utilize customized information in the
stream about classes or to replace objects that have been deserialized. Refer
to the `resolveClass` and `resolveObject` method descriptions for details.
## 1.4 Object Streams as Containers
Object Serialization produces and consumes a stream of bytes that contain one
or more primitives and objects. The objects written to the stream, in turn,
refer to other objects, which are also represented in the stream. Object
Serialization produces just one stream format that encodes and stores the
contained objects.
Each object that acts as a container implements an interface which allows
primitives and objects to be stored in or retrieved from it. These interfaces
are the `ObjectOutput` and `ObjectInput` interfaces which:
- Provide a stream to write to and to read from
- Handle requests to write primitive types and objects to the stream
- Handle requests to read primitive types and objects from the stream
Each object which is to be stored in a stream must explicitly allow itself to
be stored and must implement the protocols needed to save and restore its
state. Object Serialization defines two such protocols. The protocols allow the
container to ask the object to write and read its state.
To be stored in an Object Stream, each object must implement either the
`Serializable` or the `Externalizable` interface:
- For a `Serializable` class, Object Serialization can automatically save and
restore fields of each class of an object and automatically handle classes
that evolve by adding fields or supertypes. A serializable class can
declare which of its fields are saved or restored, and write and read
optional values and objects.
- For an `Externalizable` class, Object Serialization delegates to the class
complete control over its external format and how the state of the
supertype(s) is saved and restored.
## 1.5 Defining Serializable Fields for a Class
The serializable fields of a class can be defined two different ways. Default
serializable fields of a class are defined to be the non-transient and
non-static fields. This default computation can be overridden by declaring a
special field in the `Serializable` class, `serialPersistentFields`. This field
must be initialized with an array of `ObjectStreamField` objects that list the
names and types of the serializable fields. The modifiers for the field are
required to be private, static, and final. If the field's value is null or is
otherwise not an instance of `ObjectStreamField[]`, or if the field does not
have the required modifiers, then the behavior is as if the field were not
declared at all.
For example, the following declaration duplicates the default behavior.
```
class List implements Serializable {
List next;
private static final ObjectStreamField[] serialPersistentFields
= {new ObjectStreamField("next", List.class)};
}
```
By using `serialPersistentFields` to define the Serializable fields for a
class, there no longer is a limitation that a serializable field must be a
field within the current definition of the `Serializable` class. The
`writeObject` and `readObject` methods of the `Serializable` class can map the
current implementation of the class to the serializable fields of the class
using the interface that is described in [Section 1.7, "Accessing Serializable
Fields of a Class"](#accessing-serializable-fields-of-a-class). Therefore, the
fields for a `Serializable` class can change in a later release, as long as it
maintains the mapping back to its Serializable fields that must remain
compatible across release boundaries.
**Note:** There is, however, a limitation to the use of this mechanism to
specify serializable fields for inner classes. Inner classes can only contain
final static fields that are initialized to constants or expressions built up
from constants. Consequently, it is not possible to set
`serialPersistentFields` for an inner class (though it is possible to set it
for static member classes). For other restrictions pertaining to serialization
of inner class instances, see section [Section 1.10, "The Serializable
Interface"](#the-serializable-interface).
## 1.6 Documenting Serializable Fields and Data for a Class
It is important to document the serializable state of a class to enable
interoperability with alternative implementations of a Serializable class and
to document class evolution. Documenting a serializable field gives one a final
opportunity to review whether or not the field should be serializable. The
serialization javadoc tags, `@serial`, `@serialField`, and `@serialData`,
provide a way to document the serialized form for a Serializable class within
the source code.
- The `@serial` tag should be placed in the javadoc comment for a default
serializable field. The syntax is as follows: `@serial` *field-description*
The optional *field-description* describes the meaning of the field and its
acceptable values. The *field-description* can span multiple lines. When a
field is added after the initial release, a *@since* tag indicates the
version the field was added. The *field-description* for `@serial` provides
serialization-specific documentation and is appended to the javadoc comment
for the field within the serialized form documentation.
- The `@serialField` tag is used to document an `ObjectStreamField` component
of a `serialPersistentFields` array. One of these tags should be used for
each `ObjectStreamField` component. The syntax is as follows:
`@serialField` *field-name field-type field-description*
- The `@serialData` tag describes the sequences and types of data written or
read. The tag describes the sequence and type of optional data written by
`writeObject` or all data written by the `Externalizable.writeExternal`
method. The syntax is as follows: `@serialData` *data-description*
The javadoc application recognizes the serialization javadoc tags and generates
a specification for each Serializable and Externalizable class. See [Section
C.1, "Example Alternate Implementation of
java.io.File"](examples.html#c.1-example-alternate-implementation-of-java.io.file)
for an example that uses these tags.
When a class is declared Serializable, the serializable state of the object is
defined by serializable fields (by name and type) plus optional data. Optional
data can only be written explicitly by the `writeObject` method of a
`Serializable` class. Optional data can be read by the `Serializable` class'
`readObject` method or serialization will skip unread optional data.
When a class is declared Externalizable, the data that is written to the stream
by the class itself defines the serialized state. The class must specify the
order, types, and meaning of each datum that is written to the stream. The
class must handle its own evolution, so that it can continue to read data
written by and write data that can be read by previous versions. The class must
coordinate with the superclass when saving and restoring data. The location of
the superclasses data in the stream must be specified.
The designer of a Serializable class must ensure that the information saved for
the class is appropriate for persistence and follows the
serialization-specified rules for interoperability and evolution. Class
evolution is explained in greater detail in [Chapter
5](version.html#versioning-of-serializable-objects), "Versioning of
Serializable Objects".
## 1.7 Accessing Serializable Fields of a Class
Serialization provides two mechanisms for accessing the serializable fields in
a stream:
- The default mechanism requires no customization
- The Serializable Fields API allows a class to explicitly access/set the
serializable fields by name and type
The default mechanism is used automatically when reading or writing objects
that implement the `Serializable` interface and do no further customization.
The serializable fields are mapped to the corresponding fields of the class and
values are either written to the stream from those fields or are read in and
assigned respectively. If the class provides `writeObject` and `readObject`
methods, the default mechanism can be invoked by calling `defaultWriteObject`
and `defaultReadObject`. When the `writeObject` and `readObject` methods are
implemented, the class has an opportunity to modify the serializable field
values before they are written or after they are read.
When the default mechanism cannot be used, the serializable class can use the
`putFields` method of `ObjectOutputStream` to put the values for the
serializable fields into the stream. The `writeFields` method of
`ObjectOutputStream` puts the values in the correct order, then writes them to
the stream using the existing protocol for serialization. Correspondingly, the
`readFields` method of `ObjectInputStream` reads the values from the stream and
makes them available to the class by name in any order. See [Section 2.2, "The
ObjectOutputStream.PutField
Class"](output.html#the-objectoutputstream.putfield-class) and [Section 3.2,
"The ObjectInputStream.GetField
Class"](input.html#the-objectinputstream.getfield-class) for a detailed
description of the Serializable Fields API.
## 1.8 The ObjectOutput Interface
The `ObjectOutput` interface provides an abstract, stream-based interface to
object storage. It extends the DataOutput interface so those methods can be
used for writing primitive data types. Objects that implement this interface
can be used to store primitives and objects.
```
package java.io;
public interface ObjectOutput extends DataOutput
{
public void writeObject(Object obj) throws IOException;
public void write(int b) throws IOException;
public void write(byte b[]) throws IOException;
public void write(byte b[], int off, int len) throws IOException;
public void flush() throws IOException;
public void close() throws IOException;
}
```
`The` `writeObject` method is used to write an object. The exceptions thrown
reflect errors while accessing the object or its fields, or exceptions that
occur in writing to storage. If any exception is thrown, the underlying storage
may be corrupted. If this occurs, refer to the object that is implementing this
interface for more information.
## 1.9 The ObjectInput Interface
The `ObjectInput` interface provides an abstract stream based interface to
object retrieval. It extends the `DataInput` interface so those methods for
reading primitive data types are accessible in this interface.
```
package java.io;
public interface ObjectInput extends DataInput
{
public Object readObject()
throws ClassNotFoundException, IOException;
public int read() throws IOException;
public int read(byte b[]) throws IOException;
public int read(byte b[], int off, int len) throws IOException;
public long skip(long n) throws IOException;
public int available() throws IOException;
public void close() throws IOException;
}
```
The `readObject` method is used to read and return an object. The exceptions
thrown reflect errors while accessing the objects or its fields or exceptions
that occur in reading from the storage. If any exception is thrown, the
underlying storage may be corrupted. If this occurs, refer to the object
implementing this interface for additional information.
## 1.10 The Serializable Interface
Object Serialization produces a stream with information about the Java^TM^
classes for the objects which are being saved. For serializable objects,
sufficient information is kept to restore those objects even if a different
(but compatible) version of the implementation of the class is present. The
`Serializable` interface is defined to identify classes which implement the
serializable protocol:
```
package java.io;
public interface Serializable {};
```
A Serializable class must do the following:
- Implement the `java.io.Serializable` interface
- Identify the fields that should be serializable
(Use the `serialPersistentFields` member to explicitly declare them
serializable or use the transient keyword to denote nonserializable
fields.)
- Have access to the no-arg constructor of its first nonserializable
superclass
The class can optionally define the following methods:
- A `writeObject` method to control what information is saved or to append
additional information to the stream
- A `readObject` method either to read the information written by the
corresponding `writeObject` method or to update the state of the object
after it has been restored
- A `writeReplace` method to allow a class to nominate a replacement object
to be written to the stream
(See [Section 2.5, "The writeReplace
Method"](output.html#the-writereplace-method) for additional information.)
- A `readResolve` method to allow a class to designate a replacement object
for the object just read from the stream
(See [Section 3.7, "The readResolve
Method](input.html#the-readresolve-method) for additional information.)
`ObjectOutputStream` and `ObjectInputStream` allow the serializable classes on
which they operate to evolve (allow changes to the classes that are compatible
with the earlier versions of the classes). See [Section 5.5, "Compatible Java
Type Evolution"](version.html#compatible-java-type-evolution) for information
about the mechanism which is used to allow compatible changes.
**Note:** Serialization of inner classes (i.e., nested classes that are not
static member classes), including local and anonymous classes, is strongly
discouraged for several reasons. Because inner classes declared in non-static
contexts contain implicit non-transient references to enclosing class
instances, serializing such an inner class instance will result in
serialization of its associated outer class instance as well. Synthetic fields
generated by `javac` (or other Java^TM^ compilers) to implement inner classes
are implementation dependent and may vary between compilers; differences in
such fields can disrupt compatibility as well as result in conflicting default
`serialVersionUID` values. The names assigned to local and anonymous inner
classes are also implementation dependent and may differ between compilers.
Since inner classes cannot declare static members other than compile-time
constant fields, they cannot use the `serialPersistentFields` mechanism to
designate serializable fields. Finally, because inner classes associated with
outer instances do not have zero-argument constructors (constructors of such
inner classes implicitly accept the enclosing instance as a prepended
parameter), they cannot implement `Externalizable`. None of the issues listed
above, however, apply to static member classes.
## 1.11 The Externalizable Interface
For Externalizable objects, only the identity of the class of the object is
saved by the container; the class must save and restore the contents. The
`Externalizable` interface is defined as follows:
```
package java.io;
public interface Externalizable extends Serializable
{
public void writeExternal(ObjectOutput out)
throws IOException;
public void readExternal(ObjectInput in)
throws IOException, java.lang.ClassNotFoundException;
}
```
The class of an Externalizable object must do the following:
- Implement the `java.io.Externalizable` interface
- Implement a `writeExternal` method to save the state of the object
(It must explicitly coordinate with its supertype to save its state.)
- Implement a `readExternal` method to read the data written by the
`writeExternal` method from the stream and restore the state of the object
(It must explicitly coordinate with the supertype to save its state.)
- Have the `writeExternal` and `readExternal` methods be solely responsible
for the format, if an externally defined format is written
**Note:** The `writeExternal` and `readExternal` methods are public and
raise the risk that a client may be able to write or read information in
the object other than by using its methods and fields. These methods must
be used only when the information held by the object is not sensitive or
when exposing it does not present a security risk.
- Have a public no-arg constructor
**Note:** Inner classes associated with enclosing instances cannot have
no-arg constructors, since constructors of such classes implicitly accept
the enclosing instance as a prepended parameter. Consequently the
`Externalizable` interface mechanism cannot be used for inner classes and
they should implement the `Serializable` interface, if they must be
serialized. Several limitations exist for serializable inner classes as
well, however; see [Section 1.10, "The Serializable
Interface"](#the-serializable-interface), for a full enumeration.
An Externalizable class can optionally define the following methods:
- A `writeReplace` method to allow a class to nominate a replacement object
to be written to the stream
(See [Section 2.5, "The writeReplace
Method"](output.html#the-writereplace-method) for additional information.)
- A `readResolve` method to allow a class to designate a replacement object
for the object just read from the stream
(See [Section 3.7, "The readResolve
Method"](input.html#the-readresolve-method) for additional information.)
## 1.12 Serialization of Enum Constants
Enum constants are serialized differently than ordinary serializable or
externalizable objects. The serialized form of an enum constant consists solely
of its name; field values of the constant are not present in the form. To
serialize an enum constant, `ObjectOutputStream` writes the value returned by
the enum constant's `name` method. To deserialize an enum constant,
`ObjectInputStream` reads the constant name from the stream; the deserialized
constant is then obtained by calling the `java.lang.Enum.valueOf` method,
passing the constant's enum type along with the received constant name as
arguments. Like other serializable or externalizable objects, enum constants
can function as the targets of back references appearing subsequently in the
serialization stream.
The process by which enum constants are serialized cannot be customized: any
class-specific `writeObject`, `readObject`, `readObjectNoData`, `writeReplace`,
and `readResolve` methods defined by enum types are ignored during
serialization and deserialization. Similarly, any `serialPersistentFields` or
`serialVersionUID` field declarations are also ignored--all enum types have a
fixed `serialVersionUID` of `0L`. Documenting serializable fields and data for
enum types is unnecessary, since there is no variation in the type of data
sent.
## 1.13 Protecting Sensitive Information
When developing a class that provides controlled access to resources, care must
be taken to protect sensitive information and functions. During
deserialization, the private state of the object is restored. For example, a
file descriptor contains a handle that provides access to an operating system
resource. Being able to forge a file descriptor would allow some forms of
illegal access, since restoring state is done from a stream. Therefore, the
serializing runtime must take the conservative approach and not trust the
stream to contain only valid representations of objects. To avoid compromising
a class, the sensitive state of an object must not be restored from the stream,
or it must be reverified by the class. Several techniques are available to
protect sensitive data in classes.
The easiest technique is to mark fields that contain sensitive data as *private
transient*. Transient fields are not persistent and will not be saved by any
persistence mechanism. Marking the field will prevent the state from appearing
in the stream and from being restored during deserialization. Since writing and
reading (of private fields) cannot be superseded outside of the class, the
transient fields of the class are safe.
Particularly sensitive classes should not be serialized at all. To accomplish
this, the object should not implement either the `Serializable` or the
`Externalizable` interface.
Some classes may find it beneficial to allow writing and reading but
specifically handle and revalidate the state as it is deserialized. The class
should implement `writeObject` and `readObject` methods to save and restore
only the appropriate state. If access should be denied, throwing a
`NotSerializableException` will prevent further access.
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -1,304 +0,0 @@
---
# Copyright (c) 2005, 2017, 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.
include-before: '[CONTENTS](index.html) | [PREV](class.html) | [NEXT](protocol.html)'
include-after: '[CONTENTS](index.html) | [PREV](class.html) | [NEXT](protocol.html)'
title: 'Java Object Serialization Specification: 5 - Versioning of Serializable Objects'
---
- [Overview](#overview)
- [Goals](#goals)
- [Assumptions](#assumptions)
- [Who's Responsible for Versioning of
Streams](#whos-responsible-for-versioning-of-streams)
- [Compatible Java Type Evolution](#compatible-java-type-evolution)
- [Type Changes Affecting
Serialization](#type-changes-affecting-serialization)
-------------------------------------------------------------------------------
## 5.1 Overview
When Java objects use serialization to save state in files, or as blobs in
databases, the potential arises that the version of a class reading the data is
different than the version that wrote the data.
Versioning raises some fundamental questions about the identity of a class,
including what constitutes a compatible change. A ***compatible change*** is a
change that does not affect the contract between the class and its callers.
This section describes the goals, assumptions, and a solution that attempts to
address this problem by restricting the kinds of changes allowed and by
carefully choosing the mechanisms.
The proposed solution provides a mechanism for "automatic" handling of classes
that evolve by adding fields and adding classes. Serialization will handle
versioning without class-specific methods to be implemented for each version.
The stream format can be traversed without invoking class-specific methods.
## 5.2 Goals
The goals are to:
- Support bidirectional communication between different versions of a class
operating in different virtual machines by:
- Defining a mechanism that allows Java classes to read streams written
by older versions of the same class.
- Defining a mechanism that allows Java classes to write streams intended
to be read by older versions of the same class.
- Provide default serialization for persistence and for RMI.
- Perform well and produce compact streams in simple cases, so that RMI can
use serialization.
- Be able to identify and load classes that match the exact class used to
write the stream.
- Keep the overhead low for nonversioned classes.
- Use a stream format that allows the traversal of the stream without having
to invoke methods specific to the objects saved in the stream.
## 5.3 Assumptions
The assumptions are that:
- Versioning will only apply to serializable classes since it must control
the stream format to achieve it goals. Externalizable classes will be
responsible for their own versioning which is tied to the external format.
- All data and objects must be read from, or skipped in, the stream in the
same order as they were written.
- Classes evolve individually as well as in concert with supertypes and
subtypes.
- Classes are identified by name. Two classes with the same name may be
different versions or completely different classes that can be
distinguished only by comparing their interfaces or by comparing hashes of
the interfaces.
- Default serialization will not perform any type conversions.
- The stream format only needs to support a linear sequence of type changes,
not arbitrary branching of a type.
## 5.4 Who's Responsible for Versioning of Streams
In the evolution of classes, it is the responsibility of the evolved (later
version) class to maintain the contract established by the nonevolved class.
This takes two forms. First, the evolved class must not break the existing
assumptions about the interface provided by the original version, so that the
evolved class can be used in place of the original. Secondly, when
communicating with the original (or previous) versions, the evolved class must
provide sufficient and equivalent information to allow the earlier version to
continue to satisfy the nonevolved contract.
> ![*Private serialization protocol and contract with supertype relationships
between evolved and nonevolved classes and their
instances*](images/version.gif)
For the purposes of the discussion here, each class implements and extends the
interface or contract defined by its supertype. New versions of a class, for
example `foo'`, must continue to satisfy the contract for `foo` and may extend
the interface or modify its implementation.
Communication between objects via serialization is not part of the contract
defined by these interfaces. Serialization is a private protocol between the
implementations. It is the responsibility of the implementations to communicate
sufficiently to allow each implementation to continue to satisfy the contract
expected by its clients.
## 5.5 Compatible Java Type Evolution
The Java Language Specification discusses binary compatibility of Java classes
as those classes evolve. Most of the flexibility of binary compatibility comes
from the use of late binding of symbolic references for the names of classes,
interfaces, fields, methods, and so on.
The following are the principle aspects of the design for versioning of
serialized object streams.
- The default serialization mechanism will use a symbolic model for binding
the fields in the stream to the fields in the corresponding class in the
virtual machine.
- Each class referenced in the stream will uniquely identify itself, its
supertype, and the types and names of each serializable field written to
the stream. The fields are ordered with the primitive types first sorted by
field name, followed by the object fields sorted by field name.
- Two types of data may occur in the stream for each class: required data
(corresponding directly to the serializable fields of the object); and
optional data (consisting of an arbitrary sequence of primitives and
objects). The stream format defines how the required and optional data
occur in the stream so that the whole class, the required, or the optional
parts can be skipped if necessary.
- The required data consists of the fields of the object in the order
defined by the class descriptor.
- The optional data is written to the stream and does not correspond
directly to fields of the class. The class itself is responsible for
the length, types, and versioning of this optional information.
- If defined for a class, the `writeObject`/`readObject` methods supersede
the default mechanism to write/read the state of the class. These methods
write and read the optional data for a class. The required data is written
by calling `defaultWriteObject` and read by calling `defaultReadObject`.
- The stream format of each class is identified by the use of a Stream Unique
Identifier (SUID). By default, this is the hash of the class. All later
versions of the class must declare the Stream Unique Identifier (SUID) that
they are compatible with. This guards against classes with the same name
that might inadvertently be identified as being versions of a single class.
- Subtypes of `ObjectOutputStream` and `ObjectInputStream` may include their
own information identifying the class using the `annotateClass` method; for
example, `MarshalOutputStream` embeds the URL of the class.
## 5.6 Type Changes Affecting Serialization
With these concepts, we can now describe how the design will cope with the
different cases of an evolving class. The cases are described in terms of a
stream written by some version of a class. When the stream is read back by the
same version of the class, there is no loss of information or functionality.
The stream is the only source of information about the original class. Its
class descriptions, while a subset of the original class description, are
sufficient to match up the data in the stream with the version of the class
being reconstituted.
The descriptions are from the perspective of the stream being read in order to
reconstitute either an earlier or later version of the class. In the parlance
of RPC systems, this is a "receiver makes right" system. The writer writes its
data in the most suitable form and the receiver must interpret that information
to extract the parts it needs and to fill in the parts that are not available.
### 5.6.1 Incompatible Changes
Incompatible changes to classes are those changes for which the guarantee of
interoperability cannot be maintained. The incompatible changes that may occur
while evolving a class are:
- Deleting fields - If a field is deleted in a class, the stream written will
not contain its value. When the stream is read by an earlier class, the
value of the field will be set to the default value because no value is
available in the stream. However, this default value may adversely impair
the ability of the earlier version to fulfill its contract.
- Moving classes up or down the hierarchy - This cannot be allowed since the
data in the stream appears in the wrong sequence.
- Changing a nonstatic field to static or a nontransient field to transient -
When relying on default serialization, this change is equivalent to
deleting a field from the class. This version of the class will not write
that data to the stream, so it will not be available to be read by earlier
versions of the class. As when deleting a field, the field of the earlier
version will be initialized to the default value, which can cause the class
to fail in unexpected ways.
- Changing the declared type of a primitive field - Each version of the class
writes the data with its declared type. Earlier versions of the class
attempting to read the field will fail because the type of the data in the
stream does not match the type of the field.
- Changing the `writeObject` or `readObject` method so that it no longer
writes or reads the default field data or changing it so that it attempts
to write it or read it when the previous version did not. The default field
data must consistently either appear or not appear in the stream.
- Changing a class from `Serializable` to `Externalizable` or vice versa is
an incompatible change since the stream will contain data that is
incompatible with the implementation of the available class.
- Changing a class from a non-enum type to an enum type or vice versa since
the stream will contain data that is incompatible with the implementation
of the available class.
- Removing either `Serializable` or `Externalizable` is an incompatible
change since when written it will no longer supply the fields needed by
older versions of the class.
- Adding the `writeReplace` or `readResolve` method to a class is
incompatible if the behavior would produce an object that is incompatible
with any older version of the class.
### 5.6.2 Compatible Changes
The compatible changes to a class are handled as follows:
- Adding fields - When the class being reconstituted has a field that does
not occur in the stream, that field in the object will be initialized to
the default value for its type. If class-specific initialization is needed,
the class may provide a readObject method that can initialize the field to
nondefault values.
- Adding classes - The stream will contain the type hierarchy of each object
in the stream. Comparing this hierarchy in the stream with the current
class can detect additional classes. Since there is no information in the
stream from which to initialize the object, the class's fields will be
initialized to the default values.
- Removing classes - Comparing the class hierarchy in the stream with that of
the current class can detect that a class has been deleted. In this case,
the fields and objects corresponding to that class are read from the
stream. Primitive fields are discarded, but the objects referenced by the
deleted class are created, since they may be referred to later in the
stream. They will be garbage-collected when the stream is garbage-collected
or reset.
- Adding `writeObject`/`readObject` methods - If the version reading the
stream has these methods then `readObject` is expected, as usual, to read
the required data written to the stream by the default serialization. It
should call `defaultReadObject` first before reading any optional data. The
`writeObject` method is expected as usual to call `defaultWriteObject` to
write the required data and then may write optional data.
- Removing `writeObject`/`readObject` methods - If the class reading the
stream does not have these methods, the required data will be read by
default serialization, and the optional data will be discarded.
- Adding `java.io.Serializable` - This is equivalent to adding types. There
will be no values in the stream for this class so its fields will be
initialized to default values. The support for subclassing nonserializable
classes requires that the class's supertype have a no-arg constructor and
the class itself will be initialized to default values. If the no-arg
constructor is not available, the `InvalidClassException` is thrown.
- Changing the access to a field - The access modifiers public, package,
protected, and private have no effect on the ability of serialization to
assign values to the fields.
- Changing a field from static to nonstatic or transient to nontransient -
When relying on default serialization to compute the serializable fields,
this change is equivalent to adding a field to the class. The new field
will be written to the stream but earlier classes will ignore the value
since serialization will not assign values to static or transient fields.
-------------------------------------------------------------------------------
*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
and/or its affiliates. All rights reserved.*

View File

@ -376,7 +376,7 @@ static void javaPrinterJobToNSPrintInfo(JNIEnv* env, jobject srcPrinterJob, jobj
static JNF_MEMBER_CACHE(jm_getMaxPage, sjc_CPrinterJob, "getMaxPageAttrib", "()I");
static JNF_MEMBER_CACHE(jm_getSelectAttrib, sjc_CPrinterJob, "getSelectAttrib", "()I");
static JNF_MEMBER_CACHE(jm_getNumberOfPages, jc_Pageable, "getNumberOfPages", "()I");
static JNF_MEMBER_CACHE(jm_getPageFormat, sjc_CPrinterJob, "getPageFormat", "(I)Ljava/awt/print/PageFormat;");
static JNF_MEMBER_CACHE(jm_getPageFormat, sjc_CPrinterJob, "getPageFormatFromAttributes", "()Ljava/awt/print/PageFormat;");
NSMutableDictionary* printingDictionary = [dst dictionary];
@ -412,7 +412,7 @@ static void javaPrinterJobToNSPrintInfo(JNIEnv* env, jobject srcPrinterJob, jobj
[printingDictionary setObject:[NSNumber numberWithInteger:fromPage] forKey:NSPrintFirstPage];
[printingDictionary setObject:[NSNumber numberWithInteger:toPage] forKey:NSPrintLastPage];
jobject page = JNFCallObjectMethod(env, srcPrinterJob, jm_getPageFormat, (jint)0);
jobject page = JNFCallObjectMethod(env, srcPrinterJob, jm_getPageFormat);
if (page != NULL) {
javaPageFormatToNSPrintInfo(env, NULL, page, dst);
}

View File

@ -812,7 +812,7 @@ public class JEditorPane extends JTextComponent {
/**
* Scrolls the view to the given reference location
* (that is, the value returned by the <code>UL.getRef</code>
* (that is, the value returned by the <code>URL.getRef</code>
* method for the URL being displayed). By default, this
* method only knows how to locate a reference in an
* HTMLDocument. The implementation calls the

View File

@ -1900,7 +1900,7 @@ public class JTabbedPane extends JComponent
* Returns the accessible name of this object, or {@code null} if
* there is no accessible name.
*
* @return the accessible name of this object, nor {@code null}.
* @return the accessible name of this object, or {@code null}.
* @since 1.6
*/
public String getAccessibleName() {

View File

@ -27,6 +27,24 @@
* Defines the AWT and Swing user interface toolkits, plus APIs for
* accessibility, audio, imaging, printing, and JavaBeans.
*
* @uses java.awt.im.spi.InputMethodDescriptor
* @uses javax.accessibility.AccessibilityProvider
* @uses javax.imageio.spi.ImageInputStreamSpi
* @uses javax.imageio.spi.ImageOutputStreamSpi
* @uses javax.imageio.spi.ImageReaderSpi
* @uses javax.imageio.spi.ImageTranscoderSpi
* @uses javax.imageio.spi.ImageWriterSpi
* @uses javax.print.PrintServiceLookup
* @uses javax.print.StreamPrintServiceFactory
* @uses javax.sound.midi.spi.MidiDeviceProvider
* @uses javax.sound.midi.spi.MidiFileReader
* @uses javax.sound.midi.spi.MidiFileWriter
* @uses javax.sound.midi.spi.SoundbankReader
* @uses javax.sound.sampled.spi.AudioFileReader
* @uses javax.sound.sampled.spi.AudioFileWriter
* @uses javax.sound.sampled.spi.FormatConversionProvider
* @uses javax.sound.sampled.spi.MixerProvider
*
* @moduleGraph
* @since 9
*/

View File

@ -886,6 +886,14 @@ public abstract class RasterPrinterJob extends PrinterJob {
}
}
protected PageFormat getPageFormatFromAttributes() {
if (attributes == null || attributes.isEmpty()) {
return null;
}
return attributeToPageFormat(getPrintService(), this.attributes);
}
/**
* Presents the user a dialog for changing properties of the
* print job interactively.

View File

@ -1,776 +0,0 @@
<!--
Copyright (c) 2005, 2017, 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.
-->
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
"en-US">
<head>
<title>Java AWT Native Interface Specification and Guide</title>
</head>
<body>
<h2>The Java AWT Native Interface Specification and Guide</h2>
<h3>Introduction</h3>
<p>The Java AWT Native Interface (JAWT) comprises a small set of native
(eg C language-based) APIs that provide a standard supported way
for interaction between Java API windows and surfaces, and
platform native API windows and surfaces.
Non-Java libraries may then render to a Java owned window.
<p>
Note: in this document the terms "Java AWT Native Interface",
"AWT Native Interface" and "JAWT" are interchangeable and
refer to this same specification.
<p>
The fundamental obstacle to native rendering without JAWT is that
is that the rendering code cannot identify where to draw.
The native code needs access to information about a Java
drawing surface (such as a handle to the underlying native ID of a
<tt>Canvas</tt>), but cannot get it.</p>
Without that information (ie without JAWT) an application could
use native rendering only by creating its own top-level window
not shared at all with Java. This is unacceptable for most uses.
Except for usage via JAWT, this is considered to be entirely
internal to the Java platform implementation: private, unsupported
and undocumented.
<p>
JAWT should be supported in all headful implementations
where technically possible although this is not enforced by the JCK.
There is a platform-specific and a platform
independent portion to the API, to account for the differing
data structures and requirements of each platform.
This document specifies the platform independent portions and
also documents the platform dependent portions for the Oracle JDK
supported desktop operating environments.
For AWT the term platform is less tied to the underlying operating
system than it is to the desktop windowing environment.
<p>
Reasons for using the AWT Native Interface include
<ul>
<li>Use of a 3rd party native library not available in Java
<li>A temporary porting aid before converting legacy code to Java
<li>Rendering performance available only to native hardware accelerated APIs
<li>Interoperation with another toolkit
</ul>
<p>
Drawbacks include
<ul>
<li>A more complex application implementation, eg for painting
<li>Potential for application instability if the native library does
not interoperate properly with AWT.
<li>Increased application delivery complexity - per platform binaries
</ul>
The header file <a href="#jawt.h"> "jawt.h"</a>
in the Appendix fully specifies the APIs provided by JAWT.
<p>
An example illustrating how easy it is to use the AWT Native Interface
is presented and discussed later in this document.</p>
<p><b>JAWT usage depends on JNI</b></p>
<p>The definition of Java Standard Edition includes JNI, the Java
Native Interface. Many Java developers will never need to use it,
but the interface is the only standard supported way for a Java
language program to interact directly with
application code that has been compiled to the native machine
instructions for the host processor architecture.
JNI is used where ever there is a need for mixed languages.
These are by no means limited to cases like AWT. For example, you
could use JNI to integrate with native code that communicates with
a peripheral device, such as a scanner, connected to a system via a
USB port.</p>
<p>So JNI is general enough to be used to access almost any
sort of native library.
The rest of this document assumes a familiarity with how
to use JNI.
<p><b>How to use JAWT </b></p>
<p>In this section we describe the most common usage of the AWT
Native Interface &mdash; overriding the <tt>paint</tt> method to
direct drawing operations to a native rendering library which then
queries the Java VM to determine the information it needs in order
to render. Note, however, that any native code may use the AWT
Native Interface to learn about a target drawing surface, not just
code in a <tt>paint</tt> method.</p>
<p>The first step in hooking up a native rendering library to a
Java <tt>Canvas</tt> is to define a new class that extends
<tt>Canvas</tt> and overrides the <tt>paint</tt> method. The Java
system routes all drawing operations for a <tt>Canvas</tt> object
through the <tt>paint</tt> method, as it does for all other GUI
objects. Canvas is a good candidate for the rendering surface as
it does not have any content as a Button would.</p>
<p>The new <tt>paint</tt> method, to be implemented in the native
rendering library, must be declared as <tt>public native void</tt>
, and the native library itself is loaded at runtime by including a
call to <tt>System.loadLibrary( &quot;myRenderingLib&quot;)</tt>in
the <tt>static</tt> block of the class. The <tt>myRenderingLib</tt>
name is used for the native shared library; for Linux or the Solaris
operating environment, the actual name for the library file on disk
is <tt>libmyRenderingLib.so</tt> .</p>
<p>Here is a simple example of such a class:</p>
<pre>
import java.awt.*;
import java.awt.event.*;
public class MyCanvas extends Canvas {
static {
System.loadLibrary("myRenderingLib");
}
public native void paint(Graphics g);
public static void main(String[] args) {
Frame f = new Frame();
f.setBounds(0, 0, 500, 110);
f.add(new MyCanvas());
f.addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
System.exit(0);
}
} );
f.show();
}
}
<br />
</pre>
<p>Note that this class has a <tt>main</tt> method that can be used
to run this code as an application for testing purposes.</p>
<p>The next step is to run the <tt>javah</tt> tool on the
<tt>MyCanvas</tt> class file above to generate a C/C++ header file
that describes the interface to the native <tt>paint</tt> method
that Java expects to be used. <tt>javah</tt> is a standard tool
included with the JDK. NB: <tt>javac -h outputdir</tt> may also be used.</p>
<p>The final step &#173; and the most interesting one &#173; is to
write the native rendering method, with an interface that conforms
to the header file that <tt>javah</tt> generated, and build it as a
standard shared library (called <tt>myRenderingLib</tt> in the
above example) by linking it, against the appropriate JDK provided
$JDK_HOME/lib/$JAWT_LIB library for the target platform.
Where JAWT_LIB has the base name "jawt" and follows platform
shared object naming rules. i.e.:
<ul>
<li>Windows: jawt.dll
<li>MacOS: libjawt.dylib
<li>Linux: libjawt.so
<li>Solaris: libjawt.so
</ul>
This code will call back to the Java virtual machine to
get the drawing surface information it needs to access the
<tt>MyCanvas</tt> peer. Once this information is available, the
code can draw directly to <tt>MyCanvas</tt> using standard drawing
routines supplied by the underlying operating system.</p>
<p>Here is sample source code for a native <tt>paint</tt> method
designed for use in a X11-based drawing environment (Linux
or Solaris) and a Java VM where the AWT Native Interface is present:</p>
<pre>
#include "MyCanvas.h"
#include "jawt_md.h"
/*
* Class: MyCanvas
* Method: paint
* Signature: (Ljava/awt/Graphics;)V
*/
JNIEXPORT void JNICALL Java_MyCanvas_paint
(JNIEnv* env, jobject canvas, jobject graphics)
{
JAWT awt;
JAWT_DrawingSurface* ds;
JAWT_DrawingSurfaceInfo* dsi;
JAWT_X11DrawingSurfaceInfo* dsi_x11;
jboolean result;
jint lock;
GC gc;
short i;
char *testString = "^^^ rendered from native code ^^^";
/* Get the AWT */
awt.version = JAWT_VERSION_9;
if (JAWT_GetAWT(env, &amp;awt) == JNI_FALSE) {
printf("AWT Not found\n");
return;
}
/* Get the drawing surface */
ds = awt.GetDrawingSurface(env, canvas);
if (ds == NULL) {
printf("NULL drawing surface\n");
return;
}
/* Lock the drawing surface */
lock = ds-&gt;Lock(ds);
if((lock &amp; JAWT_LOCK_ERROR) != 0) {
printf("Error locking surface\n");
awt.FreeDrawingSurface(ds);
return;
}
/* Get the drawing surface info */
dsi = ds-&gt;GetDrawingSurfaceInfo(ds);
if (dsi == NULL) {
printf("Error getting surface info\n");
ds-&gt;Unlock(ds);
awt.FreeDrawingSurface(ds);
return;
}
/* Get the platform-specific drawing info */
dsi_x11 = (JAWT_X11DrawingSurfaceInfo*)dsi-&gt;platformInfo;
/* Now paint */
gc = XCreateGC(dsi_x11-&gt;display, dsi_x11-&gt;drawable, 0, 0);
XSetBackground(dsi_x11-&gt;display, gc, 0);
for (i=0; i&lt;36;i++)
{
XSetForeground(dsi_x11-&gt;display, gc, 10*i);
XFillRectangle(dsi_x11-&gt;display, dsi_x11-&gt;drawable, gc,
10*i, 5, 90, 90);
}
XSetForeground(dsi_x11-&gt;display, gc, 155);
XDrawImageString(dsi_x11-&gt;display, dsi_x11-&gt;drawable, gc,
100, 110, testString, strlen(testString));
XFreeGC(dsi_x11-&gt;display, gc);
/* Free the drawing surface info */
ds-&gt;FreeDrawingSurfaceInfo(dsi);
/* Unlock the drawing surface */
ds-&gt;Unlock(ds);
/* Free the drawing surface */
awt.FreeDrawingSurface(ds);
}
</pre>
<p>The key data structure here is <tt>JAWT</tt> , which is defined
in <tt>jawt.h</tt> (included by <tt>jawt_md.h)</tt> ; it provides
access to all the information the native code needs to get the job
done. The first part of the native method is boilerplate: it
populates the <tt>JAWT</tt> structure, gets a
<tt>JAWT_DrawingSurface</tt> structure, locks the surface (only one
drawing engine at a time, please!), then gets a
<tt>JAWT_DrawingSurfaceInfo</tt> structure that contains a pointer
(in the <tt>platformInfo</tt> field) to the necessary
platform-specific drawing information. It also includes the
bounding rectangle of the drawing surface and the current clipping
region.</p>
<p>The structure of the information pointed to by
<tt>platformInfo</tt> is defined in a machine-dependent header file
called <tt>jawt_md.h</tt>. For X11 drawing, it includes
information about the X11 display and X11 drawable associated with
<tt>MyCanvas</tt>. After the drawing operations are completed,
there is more boilerplate code as <tt>JAWT_DrawingSurfaceInfo</tt>
is freed and <tt>JAWT_DrawingSurface</tt> is unlocked and
freed.</p>
<p>The corresponding code for the GDI API on the Microsoft Windows platform would
be structured similarly, but would include the version of
<tt>jawt_md.h</tt> for Microsoft Windows and the structure located
in the <tt>platformInfo</tt> field of drawing surface info would be
cast as a <tt>JAWT_Win32DrawingSurfaceInfo*</tt> . And, of course,
the actual drawing operations would need to be changed to those
appropriate for the Microsoft Windows platform.
The same also for MacOS.
</p>
<p><b>Summary</b></p>
<p>The ability to draw directly into a Java <tt>Canvas</tt> from a
native code library is extremely useful for developers planning to
migrate a legacy software system to Java, especially one that
includes a high-performance rendering engine. It makes it much
easier to migrate in stages, leaving performance-sensitive
rendering code alone, while other less-sensitive portions of code
are converted to Java. The result can be a modern Java-centric
application, providing the benefit of portability and development
efficiency, but one that does not sacrifice an investment in
performance of a key piece of native code.</p>
<p><b>References</b></p>
<p>The definitive reference to the Java Native Interface is <i>The
Java Native Interface: Programmer's Guide and Specification</i> by
Sheng Liang. This book was published in June
1999 by Addison-Wesley. The ISBN is 0-201-32577-2.</p>
<p><b>Appendix</b></p>
<p><b>Header Files for jawt.h and jawt_md.h</b></p>
<a name="jawt.h"></a>
<p>jawt.h</p>
<pre>
#ifndef _JAVASOFT_JAWT_H_
#define _JAVASOFT_JAWT_H_
#include "jni.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* AWT native interface.
*
* The AWT native interface allows a native C or C++ application a means
* by which to access native structures in AWT. This is to facilitate moving
* legacy C and C++ applications to Java and to target the needs of the
* developers who need to do their own native rendering to canvases
* for performance or other reasons.
*
* Conversely it also provides mechanisms for an application which already
* has a native window to provide that to AWT for AWT rendering.
*
* Since every platform may be different in its native data structures
* and APIs for windowing systems the application must necessarily
* provided per-platform source and compile and deliver per-platform
* native code to use this API.
*
* These interfaces are not part of the Java SE specification and
* a VM is not required to implement this API. However it is strongly
* recommended that all implementations which support headful AWT
* also support these interfaces.
*
*/
/*
* AWT Native Drawing Surface (JAWT_DrawingSurface).
*
* For each platform, there is a native drawing surface structure. This
* platform-specific structure can be found in jawt_md.h. It is recommended
* that additional platforms follow the same model. It is also recommended
* that VMs on all platforms support the existing structures in jawt_md.h.
*
*******************
* EXAMPLE OF USAGE:
*******************
*
* On Microsoft Windows, a programmer wishes to access the HWND of a canvas
* to perform native rendering into it. The programmer has declared the
* paint() method for their canvas subclass to be native:
*
*
* MyCanvas.java:
*
* import java.awt.*;
*
* public class MyCanvas extends Canvas {
*
* static {
* System.loadLibrary("mylib");
* }
*
* public native void paint(Graphics g);
* }
*
*
* myfile.c:
*
* #include "jawt_md.h"
* #include &lt;assert.h&gt;
*
* JNIEXPORT void JNICALL
* Java_MyCanvas_paint(JNIEnv* env, jobject canvas, jobject graphics)
* {
* JAWT awt;
* JAWT_DrawingSurface* ds;
* JAWT_DrawingSurfaceInfo* dsi;
* JAWT_Win32DrawingSurfaceInfo* dsi_win;
* jboolean result;
* jint lock;
*
* // Get the AWT. Request version 9 to access features in that release.
* awt.version = JAWT_VERSION_9;
* result = JAWT_GetAWT(env, &amp;awt);
* assert(result != JNI_FALSE);
*
* // Get the drawing surface
* ds = awt.GetDrawingSurface(env, canvas);
* assert(ds != NULL);
*
* // Lock the drawing surface
* lock = ds-&gt;Lock(ds);
* assert((lock &amp; JAWT_LOCK_ERROR) == 0);
*
* // Get the drawing surface info
* dsi = ds-&gt;GetDrawingSurfaceInfo(ds);
*
* // Get the platform-specific drawing info
* dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi-&gt;platformInfo;
*
* //////////////////////////////
* // !!! DO PAINTING HERE !!! //
* //////////////////////////////
*
* // Free the drawing surface info
* ds-&gt;FreeDrawingSurfaceInfo(dsi);
*
* // Unlock the drawing surface
* ds-&gt;Unlock(ds);
*
* // Free the drawing surface
* awt.FreeDrawingSurface(ds);
* }
*
*/
/*
* JAWT_Rectangle
* Structure for a native rectangle.
*/
typedef struct jawt_Rectangle {
jint x;
jint y;
jint width;
jint height;
} JAWT_Rectangle;
struct jawt_DrawingSurface;
/*
* JAWT_DrawingSurfaceInfo
* Structure for containing the underlying drawing information of a component.
*/
typedef struct jawt_DrawingSurfaceInfo {
/*
* Pointer to the platform-specific information. This can be safely
* cast to a JAWT_Win32DrawingSurfaceInfo on Microsoft Windows or a
* JAWT_X11DrawingSurfaceInfo on Linux and Solaris. On MacOS this is a
* pointer to a NSObject that conforms to the JAWT_SurfaceLayers protocol.
* See jawt_md.h for details.
*/
void* platformInfo;
/* Cached pointer to the underlying drawing surface */
struct jawt_DrawingSurface* ds;
/* Bounding rectangle of the drawing surface */
JAWT_Rectangle bounds;
/* Number of rectangles in the clip */
jint clipSize;
/* Clip rectangle array */
JAWT_Rectangle* clip;
} JAWT_DrawingSurfaceInfo;
#define JAWT_LOCK_ERROR 0x00000001
#define JAWT_LOCK_CLIP_CHANGED 0x00000002
#define JAWT_LOCK_BOUNDS_CHANGED 0x00000004
#define JAWT_LOCK_SURFACE_CHANGED 0x00000008
/*
* JAWT_DrawingSurface
* Structure for containing the underlying drawing information of a component.
* All operations on a JAWT_DrawingSurface MUST be performed from the same
* thread as the call to GetDrawingSurface.
*/
typedef struct jawt_DrawingSurface {
/* Cached reference to the Java environment of the calling thread.
* If Lock(), Unlock(), GetDrawingSurfaceInfo() or
* FreeDrawingSurfaceInfo() are called from a different thread,
* this data member should be set before calling those functions.
*/
JNIEnv* env;
/* Cached reference to the target object */
jobject target;
/*
* Lock the surface of the target component for native rendering.
* When finished drawing, the surface must be unlocked with
* Unlock(). This function returns a bitmask with one or more of the
* following values:
*
* JAWT_LOCK_ERROR - When an error has occurred and the surface could not
* be locked.
*
* JAWT_LOCK_CLIP_CHANGED - When the clip region has changed.
*
* JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed.
*
* JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed
*/
jint (JNICALL *Lock)
(struct jawt_DrawingSurface* ds);
/*
* Get the drawing surface info.
* The value returned may be cached, but the values may change if
* additional calls to Lock() or Unlock() are made.
* Lock() must be called before this can return a valid value.
* Returns NULL if an error has occurred.
* When finished with the returned value, FreeDrawingSurfaceInfo must be
* called.
*/
JAWT_DrawingSurfaceInfo* (JNICALL *GetDrawingSurfaceInfo)
(struct jawt_DrawingSurface* ds);
/*
* Free the drawing surface info.
*/
void (JNICALL *FreeDrawingSurfaceInfo)
(JAWT_DrawingSurfaceInfo* dsi);
/*
* Unlock the drawing surface of the target component for native rendering.
*/
void (JNICALL *Unlock)
(struct jawt_DrawingSurface* ds);
} JAWT_DrawingSurface;
/*
* JAWT
* Structure for containing native AWT functions.
*/
typedef struct jawt {
/*
* Version of this structure. This must always be set before
* calling JAWT_GetAWT(). It affects the functions returned.
* Must be one of the known pre-defined versions.
*/
jint version;
/*
* Return a drawing surface from a target jobject. This value
* may be cached.
* Returns NULL if an error has occurred.
* Target must be a java.awt.Component (should be a Canvas
* or Window for native rendering).
* FreeDrawingSurface() must be called when finished with the
* returned JAWT_DrawingSurface.
*/
JAWT_DrawingSurface* (JNICALL *GetDrawingSurface)
(JNIEnv* env, jobject target);
/*
* Free the drawing surface allocated in GetDrawingSurface.
*/
void (JNICALL *FreeDrawingSurface)
(JAWT_DrawingSurface* ds);
/*
* Since 1.4
* Locks the entire AWT for synchronization purposes
*/
void (JNICALL *Lock)(JNIEnv* env);
/*
* Since 1.4
* Unlocks the entire AWT for synchronization purposes
*/
void (JNICALL *Unlock)(JNIEnv* env);
/*
* Since 1.4
* Returns a reference to a java.awt.Component from a native
* platform handle. On Windows, this corresponds to an HWND;
* on Solaris and Linux, this is a Drawable. For other platforms,
* see the appropriate machine-dependent header file for a description.
* The reference returned by this function is a local
* reference that is only valid in this environment.
* This function returns a NULL reference if no component could be
* found with matching platform information.
*/
jobject (JNICALL *GetComponent)(JNIEnv* env, void* platformInfo);
/**
* Since 9
* Creates a java.awt.Frame placed in a native container. Container is
* referenced by the native platform handle. For example on Windows this
* corresponds to an HWND. For other platforms, see the appropriate
* machine-dependent header file for a description. The reference returned
* by this function is a local reference that is only valid in this
* environment. This function returns a NULL reference if no frame could be
* created with matching platform information.
*/
jobject (JNICALL *CreateEmbeddedFrame) (JNIEnv *env, void* platformInfo);
/**
* Since 9
* Moves and resizes the embedded frame. The new location of the top-left
* corner is specified by x and y parameters relative to the native parent
* component. The new size is specified by width and height.
*
* The embedded frame should be created by CreateEmbeddedFrame() method, or
* this function will not have any effect.
*
* java.awt.Component.setLocation() and java.awt.Component.setBounds() for
* EmbeddedFrame really don't move it within the native parent. These
* methods always locate the embedded frame at (0, 0) for backward
* compatibility. To allow moving embedded frames this method was
* introduced, and it works just the same way as setLocation() and
* setBounds() for usual, non-embedded components.
*
* Using usual get/setLocation() and get/setBounds() together with this new
* method is not recommended.
*/
void (JNICALL *SetBounds) (JNIEnv *env, jobject embeddedFrame,
jint x, jint y, jint w, jint h);
/**
* Since 9
* Synthesize a native message to activate or deactivate an EmbeddedFrame
* window depending on the value of parameter doActivate, if "true"
* activates the window; otherwise, deactivates the window.
*
* The embedded frame should be created by CreateEmbeddedFrame() method, or
* this function will not have any effect.
*/
void (JNICALL *SynthesizeWindowActivation) (JNIEnv *env,
jobject embeddedFrame, jboolean doActivate);
} JAWT;
/*
* Get the AWT native structure. This function returns JNI_FALSE if
* an error occurs.
*/
_JNI_IMPORT_OR_EXPORT_
jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt);
/*
* Specify one of these constants as the JAWT.version
* Specifying an earlier version will limit the available functions to
* those provided in that earlier version of JAWT.
* See the "Since" note on each API. Methods with no "Since"
* may be presumed to be present in JAWT_VERSION_1_3.
*/
#define JAWT_VERSION_1_3 0x00010003
#define JAWT_VERSION_1_4 0x00010004
#define JAWT_VERSION_1_7 0x00010007
#define JAWT_VERSION_9 0x00090000
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* !_JAVASOFT_JAWT_H_ */
</pre>
<p>jawt_md.h (Linux/Solaris/X11 operating environment version)</p>
<pre>
#ifndef _JAVASOFT_JAWT_MD_H_
#define _JAVASOFT_JAWT_MD_H_
#include &lt;X11/Xlib.h&gt;
#include &lt;X11/Xutil.h&gt;
#include &lt;X11/Intrinsic.h&gt;
#include "jawt.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* X11-specific declarations for AWT native interface.
* See notes in jawt.h for an example of use.
*/
typedef struct jawt_X11DrawingSurfaceInfo {
Drawable drawable;
Display* display;
VisualID visualID;
Colormap colormapID;
int depth;
} JAWT_X11DrawingSurfaceInfo;
#ifdef __cplusplus
}
#endif
#endif /* !_JAVASOFT_JAWT_MD_H_ */
</pre>
<p>jawt_md.h (Microsoft Windows version)</p>
<pre>
#ifndef _JAVASOFT_JAWT_MD_H_
#define _JAVASOFT_JAWT_MD_H_
#include &lt;windows.h&gt;
#include "jawt.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Microsoft Windows specific declarations for AWT native interface.
* See notes in jawt.h for an example of use.
*/
typedef struct jawt_Win32DrawingSurfaceInfo {
/* Native window, DDB, or DIB handle */
union {
HWND hwnd;
HBITMAP hbitmap;
void* pbits;
};
/*
* This HDC should always be used instead of the HDC returned from
* BeginPaint() or any calls to GetDC().
*/
HDC hdc;
HPALETTE hpalette;
} JAWT_Win32DrawingSurfaceInfo;
#ifdef __cplusplus
}
#endif
#endif /* !_JAVASOFT_JAWT_MD_H_ */
</pre>
<p>jawt_md.h (MacOS version)</p>
<pre>
#ifndef _JAVASOFT_JAWT_MD_H_
#define _JAVASOFT_JAWT_MD_H_
#include "jawt.h"
#ifdef __OBJC__
#import <QuartzCore/CALayer.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* MacOS specific declarations for AWT native interface.
* See notes in jawt.h for an example of use.
*/
/*
* When calling JAWT_GetAWT with a JAWT version less than 1.7, you must pass this
* flag or you will not be able to get a valid drawing surface and JAWT_GetAWT will
* return false. This is to maintain compatibility with applications that used the
* interface with Java 6 which had multiple rendering models. This flag is not necessary
* when JAWT version 1.7 or greater is used as this is the only supported rendering mode.
*
* Example:
* JAWT awt;
* awt.version = JAWT_VERSION_1_4 | JAWT_MACOSX_USE_CALAYER;
* jboolean success = JAWT_GetAWT(env, &awt);
*/
#define JAWT_MACOSX_USE_CALAYER 0x80000000
/*
* When the native Cocoa toolkit is in use, the pointer stored in
* JAWT_DrawingSurfaceInfo->platformInfo points to a NSObject that conforms to the
* JAWT_SurfaceLayers protocol. Setting the layer property of this object will cause the
* specified layer to be overlaid on the Components rectangle. If the window the
* Component belongs to has a CALayer attached to it, this layer will be accessible via
* the windowLayer property.
*/
#ifdef __OBJC__
@protocol JAWT_SurfaceLayers
@property (readwrite, retain) CALayer *layer;
@property (readonly) CALayer *windowLayer;
@end
#endif
#ifdef __cplusplus
}
#endif
#endif /* !_JAVASOFT_JAWT_MD_H_ */
</pre>
<!-- Body text ends here -->
</body>
</html>

View File

@ -24,27 +24,27 @@
*/
/**
* Defines the RMI Connector for the Java Management Extensions (JMX) Remote API.
* <P>
* The {@linkplain javax.management.remote.rmi RMI connector} is a connector
* for the JMX Remote API that uses RMI to transmit client requests to a remote
* MBean server.
* Defines the {@linkplain javax.management.remote.rmi RMI connector}
* for the Java Management Extensions (JMX) Remote API.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Providers:</dt>
* <dd>This module provides
* {@link javax.management.remote.JMXConnectorProvider} service
* that creates the JMX connector clients using RMI protocol.
* Instances of {@code JMXConnector} can be obtained via the
* {@link javax.management.remote.JMXConnectorFactory#newJMXConnector
* JMXConnectorFactory.newJMXConnector} factory method.
* It also provides {@link javax.management.remote.JMXConnectorServerProvider} service
* that creates the JMX connector servers using RMI protocol.
* Instances of {@code JMXConnectorServer} can be obtained via the
* {@link javax.management.remote.JMXConnectorServerFactory#newJMXConnectorServer
* JMXConnectorServerFactory.newJMXConnectorServer} factory method.
* </dd>
* </dl>
*
* @provides javax.management.remote.JMXConnectorProvider
* A provider of {@code JMXConnector} for the RMI protocol.<br>
* Instances of {@code JMXConnector} using the RMI protocol
* are usually created by the {@link
* javax.management.remote.JMXConnectorFactory} which will locate
* and load the appropriate {@code JMXConnectorProvider} service
* implementation for the given protocol.
*
* @provides javax.management.remote.JMXConnectorServerProvider
* A provider of {@code JMXConnectorServer} for the RMI protocol.<br>
* Instances of {@code JMXConnectorServer} using the RMI protocol
* are usually created by the {@link
* javax.management.remote.JMXConnectorServerFactory} which will locate
* and load the appropriate {@code JMXConnectorServerProvider} service
* implementation for the given protocol.
*
* @moduleGraph
* @since 9

View File

@ -29,6 +29,9 @@
* The JMX API consists of interfaces for monitoring and management of the
* JVM and other components in the Java runtime.
*
* @uses javax.management.remote.JMXConnectorProvider
* @uses javax.management.remote.JMXConnectorServerProvider
*
* @moduleGraph
* @since 9
*/

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,8 @@
/**
* Defines the Preferences API.
*
* @uses java.util.prefs.PreferencesFactory
*
* @moduleGraph
* @since 9
*/
@ -35,4 +37,3 @@ module java.prefs {
exports java.util.prefs;
uses java.util.prefs.PreferencesFactory;
}

View File

@ -26,6 +26,21 @@
/**
* Defines the Remote Method Invocation (RMI) API.
*
* <p> The JDK implementation of this module includes
* the <em>{@index rmiregistry rmiregistry tool}</em> tool to start a remote
* object registry, and the <em>{@index rmid rmid tool}</em> tool to start
* the activation system daemon.
*
* <p>
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:</dt>
* <dd> {@extLink rmiregistry_tool_reference rmiregistry},
* {@extLink rmid_tool_reference rmid}
* </dd>
* </dl>
*
* @uses java.rmi.server.RMIClassLoaderSpi
*
* @moduleGraph
* @since 9
*/

View File

@ -26,6 +26,19 @@
/**
* Defines the Scripting API.
*
* <p> The JDK implementation of this module includes a language-independent
* command-line script shell, <em>{@index jrunscript jrunscript tool}</em>,
* that supports executing JavaScript and other languages if its corresponding
* script engine is installed.
*
* <p>
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd> {@extLink jrunscript_tool_reference jrunscript}</dd>
* </dl>
*
* @uses javax.script.ScriptEngineFactory
*
* @moduleGraph
* @since 9
*/
@ -33,4 +46,3 @@ module java.scripting {
exports javax.script;
uses javax.script.ScriptEngineFactory;
}

View File

@ -34,6 +34,7 @@
*/
@SuppressWarnings({"deprecation",
"removal"}) // java.corba and other modules
@Deprecated(since="9", forRemoval=true)
module java.se.ee {
requires transitive java.se;

View File

@ -29,6 +29,15 @@
* The modules defining CORBA and Java EE APIs are not required by
* this module, but they are required by {@code java.se.ee}.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Optional for Java SE Platform:</dt>
* <dd>
* <a href="../specs/jni/index.html">Java Native Interface (JNI)</a><br>
* <a href="../specs/jvmti.html">Java Virtual Machine Tool Interface (JVM TI)</a><br>
* <a href="../specs/jdwp/jdwp-spec.html">Java Debug Wire Protocol (JDWP)</a><br>
* </dd>
* </dl>
*
* @moduleGraph
* @since 9
*/

View File

@ -26,6 +26,8 @@
/**
* Defines the JDBC RowSet API.
*
* @uses javax.sql.rowset.RowSetFactory
*
* @moduleGraph
* @since 9
*/
@ -39,4 +41,3 @@ module java.sql.rowset {
exports javax.sql.rowset.spi;
uses javax.sql.rowset.RowSetFactory;
}

View File

@ -26,6 +26,8 @@
/**
* Defines the JDBC API.
*
* @uses java.sql.Driver
*
* @moduleGraph
* @since 9
*/
@ -38,4 +40,3 @@ module java.sql {
exports javax.transaction.xa;
uses java.sql.Driver;
}

View File

@ -26,6 +26,8 @@
/**
* Defines the attach API.
*
* @uses com.sun.tools.attach.spi.AttachProvider
*
* @moduleGraph
* @since 9
*/
@ -39,4 +41,3 @@ module jdk.attach {
uses com.sun.tools.attach.spi.AttachProvider;
provides com.sun.tools.attach.spi.AttachProvider with sun.tools.attach.AttachProviderImpl;
}

View File

@ -24,9 +24,11 @@
*/
/**
* {@link java.nio.charset.Charset Charset} provider for the charsets that
* Provides {@link java.nio.charset.Charset charsets} that
* are not in {@code java.base} (mostly double byte and IBM charsets).
*
* @provides java.nio.charset.spi.CharsetProvider
*
* @moduleGraph
* @since 9
*/
@ -34,4 +36,3 @@ module jdk.charsets {
provides java.nio.charset.spi.CharsetProvider
with sun.nio.cs.ext.ExtendedCharsets;
}

View File

@ -24,7 +24,9 @@
*/
/**
* The SunPKCS11 security provider.
* Provides the implementation of the SunPKCS11 security provider.
*
* @provides java.security.Provider
*
* @moduleGraph
* @since 9
@ -34,4 +36,3 @@ module jdk.crypto.cryptoki {
requires jdk.crypto.ec;
provides java.security.Provider with sun.security.pkcs11.SunPKCS11;
}

View File

@ -24,7 +24,9 @@
*/
/**
* The SunEC security provider.
* Provides the implementation of the SunEC security provider.
*
* @provides java.security.Provider
*
* @moduleGraph
* @since 9
@ -32,4 +34,3 @@
module jdk.crypto.ec {
provides java.security.Provider with sun.security.ec.SunEC;
}

View File

@ -24,8 +24,9 @@
*/
/**
* The SunMSCAPI security provider.
* Provides the implementation of the SunMSCAPI security provider.
*
* @provides java.security.Provider
* @moduleGraph
* @since 9
*/

View File

@ -24,8 +24,9 @@
*/
/**
* The OracleUCrypto security provider.
* Provides the implementation of the OracleUCrypto security provider.
*
* @provides java.security.Provider
* @moduleGraph
* @since 9
*/

View File

@ -24,7 +24,7 @@
*/
/**
* Implementation of the edit pad service.
* Provides the implementation of the edit pad service used by {@link jdk.jshell}.
*
* @moduleGraph
* @since 9

View File

@ -26,6 +26,8 @@
/**
* Defines the JDK-specific API for HTTP server.
*
* @uses com.sun.net.httpserver.spi.HttpServerProvider
*
* @moduleGraph
* @since 9
*/
@ -35,4 +37,3 @@ module jdk.httpserver {
exports com.sun.net.httpserver.spi;
uses com.sun.net.httpserver.spi.HttpServerProvider;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -111,47 +111,56 @@ class Http2Connection {
*/
// A small class that allows to control the state of
// the connection preface. This is just a thin wrapper
// over a CountDownLatch.
private final class PrefaceController {
// A small class that allows to control frames with respect to the state of
// the connection preface. Any data received before the connection
// preface is sent will be buffered.
private final class FramesController {
volatile boolean prefaceSent;
private final CountDownLatch latch = new CountDownLatch(1);
volatile List<ByteBufferReference> pending;
// This method returns immediately if the preface is sent,
// and blocks until the preface is sent if not.
// In the common case this where the preface is already sent
// this will cost not more than a volatile read.
void waitUntilPrefaceSent() {
boolean processReceivedData(FramesDecoder decoder, ByteBufferReference buf)
throws IOException
{
// if preface is not sent, buffers data in the pending list
if (!prefaceSent) {
try {
// If the preface is not sent then await on the latch
Log.logTrace("Waiting until connection preface is sent");
latch.await();
Log.logTrace("Preface sent: resuming reading");
assert prefaceSent;
} catch (InterruptedException e) {
String msg = Utils.stackTrace(e);
Log.logTrace(msg);
shutdown(e);
synchronized (this) {
if (!prefaceSent) {
if (pending == null) pending = new ArrayList<>();
pending.add(buf);
return false;
}
}
}
// Preface is sent. Checks for pending data and flush it.
// We rely on this method being called from within the readlock,
// so we know that no other thread could execute this method
// concurrently while we're here.
// This ensures that later incoming buffers will not
// be processed before we have flushed the pending queue.
// No additional synchronization is therefore necessary here.
List<ByteBufferReference> pending = this.pending;
this.pending = null;
if (pending != null) {
// flush pending data
for (ByteBufferReference b : pending) {
decoder.decode(b);
}
}
// push the received buffer to the frames decoder.
decoder.decode(buf);
return true;
}
// Mark that the connection preface is sent
void markPrefaceSent() {
assert !prefaceSent;
prefaceSent = true;
// Release the latch. If asyncReceive was scheduled it will
// be waiting for the release and will be woken up by this
// call. If not, then the semaphore will no longer be used after
// this.
latch.countDown();
synchronized (this) {
prefaceSent = true;
}
}
boolean isPrefaceSent() {
return prefaceSent;
}
}
volatile boolean closed;
@ -176,7 +185,7 @@ class Http2Connection {
* Each of this connection's Streams MUST use this controller.
*/
private final WindowController windowController = new WindowController();
private final PrefaceController prefaceController = new PrefaceController();
private final FramesController framesController = new FramesController();
final WindowUpdateSender windowUpdater;
static final int DEFAULT_FRAME_SIZE = 16 * 1024;
@ -409,11 +418,11 @@ class Http2Connection {
// SettingsFrame sent by the server) before the connection
// preface is fully sent might result in the server
// sending a GOAWAY frame with 'invalid_preface'.
prefaceController.waitUntilPrefaceSent();
synchronized (readlock) {
assert prefaceController.isPrefaceSent();
try {
framesDecoder.decode(buffer);
// the readlock ensures that the order of incoming buffers
// is preserved.
framesController.processReceivedData(framesDecoder, buffer);
} catch (Throwable e) {
String msg = Utils.stackTrace(e);
Log.logTrace(msg);
@ -646,7 +655,8 @@ class Http2Connection {
Log.logFrames(sf, "OUT");
// send preface bytes and SettingsFrame together
connection.write(ref.get());
// mark preface sent.
framesController.markPrefaceSent();
Log.logTrace("PREFACE_BYTES sent");
Log.logTrace("Settings Frame sent");
@ -654,8 +664,10 @@ class Http2Connection {
// minus the initial 64 K specified in protocol
final int len = client2.client().getReceiveBufferSize() - (64 * 1024 - 1);
windowUpdater.sendWindowUpdate(len);
// there will be an ACK to the windows update - which should
// cause any pending data stored before the preface was sent to be
// flushed (see PrefaceController).
Log.logTrace("finished sending connection preface");
prefaceController.markPrefaceSent();
}
/**

View File

@ -344,7 +344,13 @@ class HttpClientImpl extends HttpClient {
c.configureBlocking(false);
SelectionKey key = c.keyFor(selector);
SelectorAttachment sa;
if (key == null) {
if (key == null || !key.isValid()) {
if (key != null) {
// key is canceled.
// invoke selectNow() to purge it
// before registering the new event.
selector.selectNow();
}
sa = new SelectorAttachment(c, selector);
} else {
sa = (SelectorAttachment) key.attachment();

View File

@ -62,6 +62,7 @@ class PlainHttpConnection extends HttpConnection implements AsyncConnection {
private volatile Consumer<ByteBufferReference> asyncReceiver;
private volatile Consumer<Throwable> errorReceiver;
private volatile Supplier<ByteBufferReference> readBufferSupplier;
private boolean asyncReading;
private final AsyncWriteQueue asyncOutputQ = new AsyncWriteQueue(this::asyncOutput);
@ -70,6 +71,9 @@ class PlainHttpConnection extends HttpConnection implements AsyncConnection {
@Override
public void startReading() {
try {
synchronized(reading) {
asyncReading = true;
}
client.registerEvent(new ReadEvent());
} catch (IOException e) {
shutdown();
@ -78,6 +82,9 @@ class PlainHttpConnection extends HttpConnection implements AsyncConnection {
@Override
public void stopAsyncReading() {
synchronized(reading) {
asyncReading = false;
}
client.cancelRegistration(chan);
}
@ -279,7 +286,7 @@ class PlainHttpConnection extends HttpConnection implements AsyncConnection {
void asyncRead() {
synchronized (reading) {
try {
while (true) {
while (asyncReading) {
ByteBufferReference buf = readBufferSupplier.get();
int n = chan.read(buf.get());
if (n == -1) {
@ -325,7 +332,7 @@ class PlainHttpConnection extends HttpConnection implements AsyncConnection {
return -1;
}
Utils.flipToMark(buf, mark);
String s = "Receive (" + n + " bytes) ";
// String s = "Receive (" + n + " bytes) ";
//debugPrint(s, buf);
return n;
}
@ -393,6 +400,10 @@ class PlainHttpConnection extends HttpConnection implements AsyncConnection {
shutdown();
}
@Override
public String toString() {
return super.toString() + "/" + chan;
}
}
// used in blocking channels only
@ -422,6 +433,11 @@ class PlainHttpConnection extends HttpConnection implements AsyncConnection {
public void abort() {
close();
}
@Override
public String toString() {
return super.toString() + "/" + chan;
}
}
@Override
@ -447,7 +463,8 @@ class PlainHttpConnection extends HttpConnection implements AsyncConnection {
CompletableFuture<Void> whenReceivingResponse() {
CompletableFuture<Void> cf = new MinimalFuture<>();
try {
client.registerEvent(new ReceiveResponseEvent(cf));
ReceiveResponseEvent evt = new ReceiveResponseEvent(cf);
client.registerEvent(evt);
} catch (IOException e) {
cf.completeExceptionally(e);
}

View File

@ -803,7 +803,9 @@ class Stream<T> extends ExchangeImpl<T> {
completeResponseExceptionally(e);
try {
// will send a RST_STREAM frame
connection.resetStream(streamid, ResetFrame.CANCEL);
if (streamid != 0) {
connection.resetStream(streamid, ResetFrame.CANCEL);
}
} catch (IOException ex) {
Log.logError(ex);
}

View File

@ -25,7 +25,21 @@
/**
* Defines tools for manipulating Java Archive (JAR) files,
* including the jar and jarsigner tools.
* including the <em>{@index jar jar tool}</em> and
* <em>{@index jarsigner jarsigner tool}</em> tools.
*
* <p> This module provides the equivalent of command-line access to
* <em>jar</em> via the {@link java.util.spi.ToolProvider ToolProvider} SPI.
* Instances of the tool can be obtained by calling
* {@link java.util.spi.ToolProvider#findFirst ToolProvider.findFirst}
* or the {@link java.util.ServiceLoader service loader} with the name
* {@code "jar"}.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>{@extLink jar_tool_reference jar},
* {@extLink jarsigner_tool_reference jarsigner}
* </dl>
*
* @moduleGraph
* @since 9
@ -36,4 +50,3 @@ module jdk.jartool {
provides java.util.spi.ToolProvider with sun.tools.jar.JarToolProvider;
}

View File

@ -24,8 +24,20 @@
*/
/**
* Defines tools for diagnostics and troubleshooting a JVM,
* including the jcmd, jps, jstat and other diagnostics tools.
* Defines tools for diagnostics and troubleshooting a JVM
* such as the <em>{@index jcmd jcmd tool}</em>, <em>{@index jps jps tool}</em>,
* <em>{@index jstat jstat tool}</em> tools.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>
* {@extLink jcmd_tool_reference jcmd},
* {@extLink jinfo_tool_reference jinfo},
* {@extLink jmap_tool_reference jmap},
* {@extLink jps_tool_reference jps},
* {@extLink jstack_tool_reference jstack},
* {@extLink jstat_tool_reference jstat}
* </dl>
*
* @moduleGraph
* @since 9

View File

@ -24,8 +24,16 @@
*/
/**
* Defines the JMX graphical tool, jconsole, for monitoring and managing
* a running application.
* Defines the JMX graphical tool, <em>{@index jconsole jconsole}</em>,
* for monitoring and managing a running application.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>{@extLink jconsole_tool_reference jconsole},
* {@extLink using_jconsole Using JConsole}
* </dl>
*
* @uses com.sun.tools.jconsole.JConsolePlugin
*
* @moduleGraph
* @since 9

View File

@ -82,7 +82,7 @@ public abstract class Connection {
* thrown. The first byte of the packet is stored in element
* {@code 0} of the byte array, the second in element {@code 1},
* and so on. The bytes in the byte array are laid out as per the
* <a href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html">
* <a href="{@docRoot}/../specs/jdwp/jdwp-spec.html">
* JDWP specification</a>. That is, all fields in the packet
* are in big endian order as per the JDWP specification.
*
@ -119,7 +119,7 @@ public abstract class Connection {
*
* <p> The byte array provided to this method should be laid out
* as per the <a
* href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html">
* href="{@docRoot}/../specs/jdwp/jdwp-spec.html">
* JDWP specification</a>. That is, all fields in the packet
* are in big endian order. The first byte, that is element
* {@code pkt[0]}, is the first byte of the {@code length} field.

View File

@ -43,7 +43,7 @@ import com.sun.jdi.connect.TransportTimeoutException;
* Debug Wire Protocol (JDWP) packets over an underlying
* communication protocol. In essence a transport service
* implementation binds JDWP (as specified in the
* <a href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html">
* <a href="{@docRoot}/../specs/jdwp/jdwp-spec.html">
* JDWP specification</a>) to an underlying communication
* protocol. A transport service implementation provides
* a reliable JDWP packet transportation service. JDWP
@ -166,7 +166,7 @@ public abstract class TransportService {
* is followed by a handshake to ensure that the connection is
* to a target VM. The handshake involves the exchange
* of a string <i>JDWP-Handshake</i> as specified in the <a
* href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html">
* href="{@docRoot}/../specs/jdwp/jdwp-spec.html">
* Java Debug Wire Protocol</a> specification.
*
* @param address
@ -315,7 +315,7 @@ public abstract class TransportService {
* connection is indeed to a target VM. The handshake involves
* the exchange of a string <i>JDWP-Handshake</i> as specified
* in the <a
* href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html">
* href="{@docRoot}/../specs/jdwp/jdwp-spec.html">
* Java Debug Wire Protocol</a> specification.
*
* @param listenKey

View File

@ -45,8 +45,7 @@
* Platform Debugger Architecture documentation</a> for this release and the <a
* href="http://java.sun.com/products/jpda">Java Platform Debugger Architecture
* website</a>.
* <p style="font-size:larger">
* <b>Global Exceptions:</b>
* <h3>Global Exceptions</h3>
* <p>
* This section documents exceptions which apply to the entire API and are thus
* not documented on individual methods.
@ -103,6 +102,21 @@
* unloaded.
* </blockquote>
*
* <h3>jdb</h3>
*
* <em>{@index jdb jdb tool}</em> is a simple command-line debugger provided
* in this module.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>{@extLink jdb_tool_reference jdb}
* </dl>
*
* @provides com.sun.jdi.connect.Connector
*
* @uses com.sun.jdi.connect.Connector
* @uses com.sun.jdi.connect.spi.TransportService
*
* @moduleGraph
* @since 9
*/
@ -127,4 +141,3 @@ module jdk.jdi {
com.sun.tools.jdi.SocketListeningConnector,
com.sun.tools.jdi.SunCommandLineLauncher;
}

View File

@ -24,11 +24,12 @@
*/
/**
* Java Debug Wire Protocol.
* Provides the implementation of the Java Debug Wire Protocol (JDWP) agent.
*
* @moduleGraph
* @since 9
* @see <a href="../specs/jdwp/jdwp-spec.html">JDWP Specification</a>
* @see <a href="../specs/jdwp/jdwp-transport.html">JDWP Transport Specification</a>
*/
module jdk.jdwp.agent {
}

View File

@ -24,7 +24,31 @@
*/
/**
* Defines the Java linker tool, jlink.
* Defines the <em>{@index jlink jlink tool}</em> tool for creating run-time
* images, the <em>{@index jmod jmod tool}</em> tool for creating and manipulating
* JMOD files, and the <em>{@index jimage jimage tool}</em> tool for inspecting
* the JDK implementation-specific container file for classes and resources.
*
* <p> This module provides the equivalent of command-line access to the
* <em>{@extLink jlink_tool_reference jlink}</em> and
* <em>{@extLink jmod_tool_reference jmod}</em> tools via the
* {@link java.util.spi.ToolProvider ToolProvider} SPI.
* Instances of the tools can be obtained by calling
* {@link java.util.spi.ToolProvider#findFirst ToolProvider.findFirst}
* or the {@link java.util.ServiceLoader service loader} with the name
* {@code "jlink"} or {@code "jmod"} as appropriate.
*
* <p> <em>{@extLink jimage_tool_reference jimage}</em> only exists
* as a command-line tool, and does not provide any direct API.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>{@extLink jlink_tool_reference jlink},
* {@extLink jmod_tool_reference jmod},
* {@extLink jimage_tool_reference jimage}
* </dl>
*
* @provides java.util.spi.ToolProvider
*
* @moduleGraph
* @since 9

View File

@ -24,8 +24,13 @@
*/
/**
* Defines the tool for starting a daemon for the jstat tool to monitor
* JVM statistics remotely.
* Defines the <em>{@index jstatd jstatd tool}</em> tool for starting a daemon
* for the jstat tool to monitor JVM statistics remotely.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>{@extLink jstatd_tool_reference jstatd}
* </dl>
*
* @moduleGraph
* @since 9

View File

@ -24,7 +24,7 @@
*/
/**
* Locale data provider for locales other than {@linkplain java.util.Locale#US US locale}.
* Provides the locale data for locales other than {@linkplain java.util.Locale#US US locale}.
*
* @moduleGraph
* @since 9

View File

@ -24,7 +24,12 @@
*/
/**
* Define the JMX management agent.
* Defines the JMX management agent.
*
* <p> This module allows a Java Virtual Machine to be monitored and managed
* via JMX API. See more information from the
* {@extLink monitoring_and_management_using_jmx_technology
* Monitoring and Management Using JMX} guide.
*
* @moduleGraph
* @since 9

View File

@ -24,8 +24,9 @@
*/
/**
* DNS Java Naming provider.
* Provides the implementation of the DNS Java Naming provider.
*
* @provides javax.naming.spi.InitialContextFactory
* @moduleGraph
* @since 9
*/
@ -38,4 +39,3 @@ module jdk.naming.dns {
provides javax.naming.spi.InitialContextFactory
with com.sun.jndi.dns.DnsContextFactory;
}

View File

@ -24,8 +24,9 @@
*/
/**
* RMI Java Naming provider.
* Provides the implementation of the RMI Java Naming provider.
*
* @provides javax.naming.spi.InitialContextFactory
* @moduleGraph
* @since 9
*/
@ -39,4 +40,3 @@ module jdk.naming.rmi {
exports com.sun.jndi.url.rmi to java.naming;
exports com.sun.jndi.rmi.registry to java.rmi;
}

View File

@ -25,8 +25,15 @@
/**
* Defines tools for transforming a JAR file into a compressed pack200 file
* and transforming a packed file into a JAR file, including the pack200,
* and unpack200 tools.
* and transforming a packed file into a JAR file, including the
* <em>{@index pack200 pack200 tool}</em> and
* <em>{@index unpack200 unpack200 tool}</em> tools.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>{@extLink pack200_tool_reference pack200},
* {@extLink unpack200_tool_reference unpack200}
* </dl>
*
* @moduleGraph
* @since 9

View File

@ -24,7 +24,13 @@
*/
/**
* GUI tool for managing policy files.
* Defines the GUI tool for managing policy files
* called <em>{@index policytool policytool}</em>.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>{@extLink policytool_tool_reference policytool}
* </dl>
*
* @since 9
* @deprecated
@ -39,4 +45,3 @@ module jdk.policytool {
requires java.security.jgss;
requires jdk.security.jgss;
}

View File

@ -24,10 +24,15 @@
*/
/**
* Defines the rmic compiler for generating stubs and skeletons using
* the Java Remote Method Protocol (JRMP) and
* Defines the <em>{@index rmic rmic}</em> compiler for generating stubs and
* skeletons using the Java Remote Method Protocol (JRMP) and
* stubs and tie class files (IIOP protocol) for remote objects.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>{@extLink rmic_tool_reference rmic}
* </dl>
*
* @moduleGraph
* @since 9
*/

View File

@ -24,9 +24,10 @@
*/
/**
* Contains the implementation of the javax.security.auth.* interfaces and
* various authentication modules.
* Provides the implementation of the {@code javax.security.auth.*}
* interfaces and various authentication modules.
*
* @provides javax.security.auth.spi.LoginModule
* @moduleGraph
* @since 9
*/
@ -47,4 +48,3 @@ module jdk.security.auth {
com.sun.security.auth.module.LdapLoginModule,
com.sun.security.auth.module.NTLoginModule;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2017, 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
@ -872,7 +872,7 @@ public final class Unsafe {
public final boolean compareAndSwapObject(Object o, long offset,
Object expected,
Object x) {
return theInternalUnsafe.compareAndSwapObject(o, offset, expected, x);
return theInternalUnsafe.compareAndSetObject(o, offset, expected, x);
}
/**
@ -888,7 +888,7 @@ public final class Unsafe {
public final boolean compareAndSwapInt(Object o, long offset,
int expected,
int x) {
return theInternalUnsafe.compareAndSwapInt(o, offset, expected, x);
return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);
}
/**
@ -904,7 +904,7 @@ public final class Unsafe {
public final boolean compareAndSwapLong(Object o, long offset,
long expected,
long x) {
return theInternalUnsafe.compareAndSwapLong(o, offset, expected, x);
return theInternalUnsafe.compareAndSetLong(o, offset, expected, x);
}
/**

View File

@ -24,12 +24,17 @@
*/
/**
* Zip file system provider.
* Provides the implementation of the zip file system provider.
*
* <p> The zip file system provider treats a zip or JAR file as a file system
* and provides the ability to manipulate the contents of the file.
* The zip file system provider can be created by
* {@link java.nio.file.FileSystems#newFileSystem} if installed.
*
* @provides java.nio.file.spi.FileSystemProvider
* @moduleGraph
* @since 9
*/
module jdk.zipfs {
provides java.nio.file.spi.FileSystemProvider with jdk.nio.zipfs.ZipFileSystemProvider;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2017, 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
@ -214,8 +214,8 @@ class EchoHandler implements HttpHandler {
t.sendResponseHeaders(200, in.length);
OutputStream os = t.getResponseBody();
os.write(in);
os.close();
is.close();
close(os);
close(is);
} else {
OutputStream os = t.getResponseBody();
byte[] buf = new byte[64 * 1024];
@ -232,9 +232,15 @@ class EchoHandler implements HttpHandler {
String s = Integer.toString(count);
os.write(s.getBytes());
}
close(os);
close(is);
}
}
protected void close(OutputStream os) throws IOException {
os.close();
}
protected void close(InputStream is) throws IOException {
is.close();
}
}
}

View File

@ -24,7 +24,7 @@
/*
* @test
* @key headful
* @bug 8033936
* @bug 8033936 8172510
* @summary Verify that correct ItemEvent is received while selection &
* deselection of multi select List items.
*/
@ -109,14 +109,16 @@ public class ItemEventTest extends Frame
boolean isMac = osName.contains("Mac") || osName.contains("mac");
if(isMac) {
robot.keyPress(KeyEvent.VK_META);
robot.waitForIdle();
}
// First loop to select & Second loop to deselect the list items.
for (int j = 0; j < 2; ++j) {
for (int i = 0; i < list.getItemCount(); ++i) {
robot.mouseMove(loc.x, loc.y + i * dY);
robot.waitForIdle();
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.delay(100);
robot.waitForIdle();
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.waitForIdle();
}

View File

@ -24,6 +24,7 @@
/* @test
@bug 8167102
@summary PrintRequestAttributeSet breaks page size set using PageFormat
@ignore Exclude the test until 8167102 is resolved by a new reassessed fix
@run main/manual WrongPaperPrintingTest
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -23,7 +23,7 @@
/*
* @test
* @bug 8087112
* @bug 8087112 8180044
* @modules jdk.incubator.httpclient
* java.logging
* jdk.httpserver
@ -32,13 +32,20 @@
* @compile ../../../com/sun/net/httpserver/LogFilter.java
* @compile ../../../com/sun/net/httpserver/FileServerHandler.java
* @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests
* @run main/othervm/timeout=40 -Dtest.insertDelay=true ManyRequests
* @run main/othervm/timeout=40 -Dtest.chunkSize=64 ManyRequests
* @run main/othervm/timeout=40 -Dtest.insertDelay=true -Dtest.chunkSize=64 ManyRequests
* @summary Send a large number of requests asynchronously
*/
// * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsParameters;
import com.sun.net.httpserver.HttpsServer;
import com.sun.net.httpserver.HttpExchange;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import jdk.incubator.http.HttpClient;
import jdk.incubator.http.HttpRequest;
import java.net.InetSocketAddress;
@ -65,7 +72,10 @@ public class ManyRequests {
Logger logger = Logger.getLogger("com.sun.net.httpserver");
logger.setLevel(Level.ALL);
logger.info("TEST");
System.out.println("Sending " + REQUESTS
+ " requests; delay=" + INSERT_DELAY
+ ", chunks=" + CHUNK_SIZE
+ ", XFixed=" + XFIXED);
SSLContext ctx = new SimpleSSLContext().get();
InetSocketAddress addr = new InetSocketAddress(0);
@ -86,11 +96,36 @@ public class ManyRequests {
//static final int REQUESTS = 1000;
static final int REQUESTS = 20;
static final boolean INSERT_DELAY = Boolean.getBoolean("test.insertDelay");
static final int CHUNK_SIZE = Math.max(0,
Integer.parseInt(System.getProperty("test.chunkSize", "0")));
static final boolean XFIXED = Boolean.getBoolean("test.XFixed");
static class TestEchoHandler extends EchoHandler {
final Random rand = new Random();
@Override
public void handle(HttpExchange e) throws IOException {
System.out.println("Server: received " + e.getRequestURI());
super.handle(e);
}
protected void close(OutputStream os) throws IOException {
if (INSERT_DELAY) {
try { Thread.sleep(rand.nextInt(200)); } catch (InterruptedException e) {}
}
super.close(os);
}
protected void close(InputStream is) throws IOException {
if (INSERT_DELAY) {
try { Thread.sleep(rand.nextInt(200)); } catch (InterruptedException e) {}
}
super.close(is);
}
}
static void test(HttpsServer server, HttpClient client) throws Exception {
int port = server.getAddress().getPort();
URI uri = new URI("https://127.0.0.1:" + port + "/foo/x");
server.createContext("/foo", new EchoHandler());
URI baseURI = new URI("https://127.0.0.1:" + port + "/foo/x");
server.createContext("/foo", new TestEchoHandler());
server.start();
RequestLimiter limiter = new RequestLimiter(40);
@ -99,24 +134,32 @@ public class ManyRequests {
HashMap<HttpRequest,byte[]> bodies = new HashMap<>();
for (int i=0; i<REQUESTS; i++) {
byte[] buf = new byte[i+1]; // different size bodies
byte[] buf = new byte[(i+1)*CHUNK_SIZE+i+1]; // different size bodies
rand.nextBytes(buf);
URI uri = new URI(baseURI.toString() + String.valueOf(i+1));
HttpRequest r = HttpRequest.newBuilder(uri)
.header("XFixed", "true")
.POST(fromByteArray(buf))
.build();
bodies.put(r, buf);
results[i] =
limiter.whenOkToSend()
.thenCompose((v) -> client.sendAsync(r, asByteArray()))
.thenCompose((v) -> {
System.out.println("Client: sendAsync: " + r.uri());
return client.sendAsync(r, asByteArray());
})
.thenCompose((resp) -> {
limiter.requestComplete();
if (resp.statusCode() != 200) {
String s = "Expected 200, got: " + resp.statusCode();
System.out.println(s + " from "
+ resp.request().uri().getPath());
return completedWithIOException(s);
} else {
counter++;
System.out.println("Result from " + counter);
System.out.println("Result (" + counter + ") from "
+ resp.request().uri().getPath());
}
return CompletableFuture.completedStage(resp.body())
.thenApply((b) -> new Pair<>(resp, b));

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2017, 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 8087112 8180044
* @modules jdk.incubator.httpclient
* java.logging
* jdk.httpserver
* @library /lib/testlibrary/ /
* @build jdk.testlibrary.SimpleSSLContext EchoHandler
* @compile ../../../com/sun/net/httpserver/LogFilter.java
* @compile ../../../com/sun/net/httpserver/FileServerHandler.java
* @build ManyRequests ManyRequests2
* @run main/othervm/timeout=40 -Dtest.XFixed=true ManyRequests2
* @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.insertDelay=true ManyRequests2
* @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.chunkSize=64 ManyRequests2
* @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.insertDelay=true -Dtest.chunkSize=64 ManyRequests2
* @summary Send a large number of requests asynchronously. The server echoes back using known content length.
*/
// * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests
public class ManyRequests2 {
public static void main(String[] args) throws Exception {
ManyRequests.main(args);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, 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
@ -38,7 +38,7 @@ import sun.security.krb5.Config;
/*
* @test
* @bug 8164656
* @bug 8164656 8181461
* @run main/othervm KdcPolicy udp
* @run main/othervm KdcPolicy tcp
* @summary krb5.kdc.bad.policy test
@ -110,7 +110,7 @@ public class KdcPolicy {
// It is possible the real KDC cannot fulfil the request
// in 3s, so it might fail (either 1st time or 2nd time).
writeConf(1, 3000, p1, p3);
test("a3000c3000c3000|a3000c3000-|a3000c3000c3000-");
test("a3000c3000c3000|a3000c3000-|a3000c3000c3000a3000-");
// If a test case won't use a real KDC, it can be sped up.
writeConf(3, 5, p1, p2);