下面列出了怎么用java.io.ObjectStreamClass的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Compare targetClassSerialVersionUID and current JVM's targetClass serialVersionUID.
* If they are same return true else return false.
*/
public boolean isTargetClassAndCurrentJvmTargetClassMatch() {
Class<?> targetClassOnThisJVM;
// JVM에 Class가 없는 상황
try {
targetClassOnThisJVM = Class.forName(targetClassName);
} catch (ClassNotFoundException e) {
log.error("target class " + targetClassName + " does not exist on this JVM.");
return false;
}
ObjectStreamClass osc = ObjectStreamClass.lookup(targetClassOnThisJVM);
// JVM Class가 Not serializable
if (osc == null) {
return false;
}
return targetClassSerialVersionUID == osc.getSerialVersionUID();
}
@Override
protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
try {
if (this.classLoader != null) {
// Use the specified ClassLoader to resolve local classes.
return ClassUtils.forName(classDesc.getName(), this.classLoader);
}
else {
// Use the default ClassLoader...
return super.resolveClass(classDesc);
}
}
catch (ClassNotFoundException ex) {
return resolveFallbackIfPossible(classDesc.getName(), ex);
}
}
/**
* Write and read class descriptors to/from a stream.
* Arguments: <# cycles>
*/
public long run(String[] args) throws Exception {
int ncycles = Integer.parseInt(args[0]);
StreamBuffer sbuf = new StreamBuffer();
ObjectOutputStream oout =
new ObjectOutputStream(sbuf.getOutputStream());
ObjectInputStream oin =
new ObjectInputStream(sbuf.getInputStream());
ObjectStreamClass desc = ObjectStreamClass.lookup(Dummy50.class);
doReps(oout, oin, sbuf, desc, 1); // warmup
long start = System.currentTimeMillis();
doReps(oout, oin, sbuf, desc, ncycles);
return System.currentTimeMillis() - start;
}
/**
* Write and read class descriptors to/from a stream.
* Arguments: <# cycles>
*/
public long run(String[] args) throws Exception {
int ncycles = Integer.parseInt(args[0]);
StreamBuffer sbuf = new StreamBuffer();
ObjectOutputStream oout =
new ObjectOutputStream(sbuf.getOutputStream());
ObjectInputStream oin =
new ObjectInputStream(sbuf.getInputStream());
ObjectStreamClass desc = ObjectStreamClass.lookup(Dummy50.class);
doReps(oout, oin, sbuf, desc, 1); // warmup
long start = System.currentTimeMillis();
doReps(oout, oin, sbuf, desc, ncycles);
return System.currentTimeMillis() - start;
}
/**
* Write and read proxy class descriptors to/from a stream.
* Arguments: <# cycles>
*/
public long run(String[] args) throws Exception {
int ncycles = Integer.parseInt(args[0]);
StreamBuffer sbuf = new StreamBuffer();
ObjectOutputStream oout =
new ObjectOutputStream(sbuf.getOutputStream());
ObjectInputStream oin =
new ObjectInputStream(sbuf.getInputStream());
ObjectStreamClass[] descs = genDescs();
doReps(oout, oin, sbuf, descs, 1); // warmup
long start = System.currentTimeMillis();
doReps(oout, oin, sbuf, descs, ncycles);
return System.currentTimeMillis() - start;
}
/**
* Get the names and types of all the persistent fields of a Class.
*/
private Hashtable getPersistentFields (Class clz) {
Hashtable result = new Hashtable();
ObjectStreamClass osc = ObjectStreamClass.lookup(clz);
if (osc != null) {
ObjectStreamField[] fields = osc.getFields();
for (int i = 0; i < fields.length; i++) {
String typeSig;
String typePrefix = String.valueOf(fields[i].getTypeCode());
if (fields[i].isPrimitive()) {
typeSig = typePrefix;
} else {
if (fields[i].getTypeCode() == '[') {
typePrefix = "";
}
typeSig = typePrefix + fields[i].getType().getName().replace('.','/');
if (typeSig.endsWith(";")) {
typeSig = typeSig.substring(0,typeSig.length()-1);
}
}
result.put(fields[i].getName(),typeSig);
}
}
return result;
}
public static void main(String[] args) throws Exception {
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
ObjectOutputStream output = new ObjectOutputStream(byteOutput);
output.writeObject(new TestClass());
ByteArrayInputStream bais = new ByteArrayInputStream(byteOutput.toByteArray());
TestObjectInputStream input = new TestObjectInputStream(bais);
input.readObject();
ObjectStreamClass osc = input.getDescriptor();
// All OSC public API methods should complete without throwing.
osc.getName();
osc.forClass();
osc.getField("str");
osc.getFields();
osc.getSerialVersionUID();
osc.toString();
}
@Test
public void resolveClass()
throws IOException, ClassNotFoundException
{
ObjectStreamClass intClass = ObjectStreamClass.lookupAny(int.class);
byte[] bytes = Serializables.serialize(1);
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(bytes);
ObjectInputStreamProxy objectInputStream = new ObjectInputStreamProxy(arrayInputStream, ObjectInputStreamProxy.getLatestUserDefinedLoader());
when(objectStreamClass.getName()).thenReturn("gadtry.gadtry.gadtry.gadtry");
Assert.assertEquals(int.class, objectInputStream.resolveClass(intClass));
try {
objectInputStream.resolveClass(objectStreamClass);
Assert.fail();
}
catch (ClassNotFoundException ignored) {
}
//ObjectStreamClass
Assert.assertEquals(1, (int) objectInputStream.readObject());
}
/**
* Get the names and types of all the persistent fields of a Class.
*/
private Hashtable getPersistentFields (Class clz) {
Hashtable result = new Hashtable();
ObjectStreamClass osc = ObjectStreamClass.lookup(clz);
if (osc != null) {
ObjectStreamField[] fields = osc.getFields();
for (int i = 0; i < fields.length; i++) {
String typeSig;
String typePrefix = String.valueOf(fields[i].getTypeCode());
if (fields[i].isPrimitive()) {
typeSig = typePrefix;
} else {
if (fields[i].getTypeCode() == '[') {
typePrefix = "";
}
typeSig = typePrefix + fields[i].getType().getName().replace('.','/');
if (typeSig.endsWith(";")) {
typeSig = typeSig.substring(0,typeSig.length()-1);
}
}
result.put(fields[i].getName(),typeSig);
}
}
return result;
}
/**
* Generate proxy class descriptors.
*/
ObjectStreamClass[] genDescs() {
ClassLoader ldr = ProxyClassDesc.class.getClassLoader();
Class[] ifaces = new Class[3];
Class[] a =
new Class[] { A1.class, A2.class, A3.class, A4.class, A5.class };
Class[] b =
new Class[] { B1.class, B2.class, B3.class, B4.class, B5.class };
Class[] c =
new Class[] { C1.class, C2.class, C3.class, C4.class, C5.class };
ObjectStreamClass[] descs =
new ObjectStreamClass[a.length * b.length * c.length];
int n = 0;
for (int i = 0; i < a.length; i++) {
ifaces[0] = a[i];
for (int j = 0; j < b.length; j++) {
ifaces[1] = b[j];
for (int k = 0; k < c.length; k++) {
ifaces[2] = c[k];
Class proxyClass = Proxy.getProxyClass(ldr, ifaces);
descs[n++] = ObjectStreamClass.lookup(proxyClass);
}
}
}
return descs;
}
/**
* Write and read class descriptors to/from a stream.
* Arguments: <# cycles>
*/
public long run(String[] args) throws Exception {
int ncycles = Integer.parseInt(args[0]);
StreamBuffer sbuf = new StreamBuffer();
ObjectOutputStream oout =
new ObjectOutputStream(sbuf.getOutputStream());
ObjectInputStream oin =
new ObjectInputStream(sbuf.getInputStream());
ObjectStreamClass desc = ObjectStreamClass.lookup(Dummy50.class);
doReps(oout, oin, sbuf, desc, 1); // warmup
long start = System.currentTimeMillis();
doReps(oout, oin, sbuf, desc, ncycles);
return System.currentTimeMillis() - start;
}
/**
* Write and read class descriptors to/from a stream.
* Arguments: <# cycles>
*/
public long run(String[] args) throws Exception {
int ncycles = Integer.parseInt(args[0]);
StreamBuffer sbuf = new StreamBuffer();
ObjectOutputStream oout =
new ObjectOutputStream(sbuf.getOutputStream());
ObjectInputStream oin =
new ObjectInputStream(sbuf.getInputStream());
ObjectStreamClass desc = ObjectStreamClass.lookup(Dummy50.class);
doReps(oout, oin, sbuf, desc, 1); // warmup
long start = System.currentTimeMillis();
doReps(oout, oin, sbuf, desc, ncycles);
return System.currentTimeMillis() - start;
}
/**
* Write and read proxy class descriptors to/from a stream.
* Arguments: <# cycles>
*/
public long run(String[] args) throws Exception {
int ncycles = Integer.parseInt(args[0]);
StreamBuffer sbuf = new StreamBuffer();
ObjectOutputStream oout =
new ObjectOutputStream(sbuf.getOutputStream());
ObjectInputStream oin =
new ObjectInputStream(sbuf.getInputStream());
ObjectStreamClass[] descs = genDescs();
doReps(oout, oin, sbuf, descs, 1); // warmup
long start = System.currentTimeMillis();
doReps(oout, oin, sbuf, descs, ncycles);
return System.currentTimeMillis() - start;
}
public StreamFunction<?> getStreamFunction(String classLoaderId, InputStream inputStream) throws IOException {
final ClassLoader classLoader = getClassLoader(classLoaderId);
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream) {
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
return classLoader.loadClass(desc.getName());
}
};
try {
return (StreamFunction<?>) objectInputStream.readObject();
} catch (ClassNotFoundException e) {
throw new IOException(e);
} finally {
objectInputStream.close();
}
}
/**
* Updates the options that the current classifier is using.
*/
@Override
protected void updateOptions() {
if (m_Template instanceof OptionHandler) {
m_ClassifierOptions = Utils.joinOptions(((OptionHandler) m_Template)
.getOptions());
} else {
m_ClassifierOptions = "";
}
if (m_Template instanceof Serializable) {
ObjectStreamClass obs = ObjectStreamClass.lookup(m_Template.getClass());
m_ClassifierVersion = "" + obs.getSerialVersionUID();
} else {
m_ClassifierVersion = "";
}
}
/**
* Run benchmark for given number of cycles.
*/
void doReps(ObjectOutputStream oout, ObjectInputStream oin,
StreamBuffer sbuf, ObjectStreamClass[] descs, int ncycles)
throws Exception
{
int ndescs = descs.length;
for (int i = 0; i < ncycles; i++) {
sbuf.reset();
oout.reset();
for (int j = 0; j < ndescs; j++) {
oout.writeObject(descs[j]);
}
oout.flush();
for (int j = 0; j < ndescs; j++) {
oin.readObject();
}
}
}
/**
* Write and read proxy class descriptors to/from a stream.
* Arguments: <# cycles>
*/
public long run(String[] args) throws Exception {
int ncycles = Integer.parseInt(args[0]);
StreamBuffer sbuf = new StreamBuffer();
ObjectOutputStream oout =
new ObjectOutputStream(sbuf.getOutputStream());
ObjectInputStream oin =
new ObjectInputStream(sbuf.getInputStream());
ObjectStreamClass[] descs = genDescs();
doReps(oout, oin, sbuf, descs, 1); // warmup
long start = System.currentTimeMillis();
doReps(oout, oin, sbuf, descs, ncycles);
return System.currentTimeMillis() - start;
}
public static void main(String[] args) throws Exception {
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
ObjectOutputStream output = new ObjectOutputStream(byteOutput);
output.writeObject(new TestClass());
ByteArrayInputStream bais = new ByteArrayInputStream(byteOutput.toByteArray());
TestObjectInputStream input = new TestObjectInputStream(bais);
input.readObject();
ObjectStreamClass osc = input.getDescriptor();
// All OSC public API methods should complete without throwing.
osc.getName();
osc.forClass();
osc.getField("str");
osc.getFields();
osc.getSerialVersionUID();
osc.toString();
}
private int getOrAddMapping(ObjectStreamClass desc) {
SerializableDataKey probe = new SerializableDataKey(desc, false);
Integer rep = writeLookupCache.get(probe);
if (rep == null) {
return addMappingUnderLock(desc, probe);
} else {
return rep;
}
}
/**
* Load the local class equivalent of the specified stream class
* description, by using the class loader assigned to this Context.
*
* @param classDesc Class description from the input stream
*
* @exception ClassNotFoundException if this class cannot be found
* @exception IOException if an input/output error occurs
*/
@Override
public Class<?> resolveClass(ObjectStreamClass classDesc)
throws ClassNotFoundException, IOException {
String name = classDesc.getName();
if (allowedClassNamePattern != null) {
boolean allowed = allowedClassNamePattern.matcher(name).matches();
if (!allowed) {
boolean doLog = warnOnFailure && reportedClasses.add(name);
String msg = sm.getString("customObjectInputStream.nomatch", name, allowedClassNameFilter);
if (doLog) {
log.warn(msg);
} else if (log.isDebugEnabled()) {
log.debug(msg);
}
throw new InvalidClassException(msg);
}
}
try {
return Class.forName(name, false, classLoader);
} catch (ClassNotFoundException e) {
try {
// Try also the superclass because of primitive types
return super.resolveClass(classDesc);
} catch (ClassNotFoundException e2) {
// Rethrow original exception, as it can have more information
// about why the class was not found. BZ 48007
throw e;
}
}
}
@Override
protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
Class<?> clazz = desc.forClass();
if (clazz.isPrimitive() || clazz.isArray()) {
write(0);
super.writeClassDescriptor(desc);
} else {
write(1);
writeUTF(desc.getName());
}
}
@Override
protected Class<?> resolveClass(ObjectStreamClass classDesc)
throws IOException, ClassNotFoundException {
String name = classDesc.getName();
ReflectUtil.checkPackageAccess(name);
return Class.forName(name, false, loader);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass aClass)
throws IOException, ClassNotFoundException {
if (loader == null) {
return super.resolveClass(aClass);
} else {
String name = aClass.getName();
ReflectUtil.checkPackageAccess(name);
// Query the class loader ...
return Class.forName(name, false, loader);
}
}
private static Map<String, ObjectStreamClass> initMap() {
final Map<String, ObjectStreamClass> init = new HashMap<>(4);
for (MigrationUtil m: MigrationUtil.values()) {
init.put(m.oldSerializerName, m.newSerializerStreamClass);
}
return init;
}
/**
* Verifies that serializers of anonymous classes can be deserialized, even if serialVersionUID changes.
*/
@Test
public void testAnonymousSerializerClassWithChangedSerialVersionUID() throws Exception {
TypeSerializer anonymousClassSerializer = new AbstractIntSerializer() {
@Override
public TypeSerializerSnapshot<Integer> snapshotConfiguration() {
return null;
}
};
// assert that our assumption holds
Assert.assertTrue(anonymousClassSerializer.getClass().isAnonymousClass());
byte[] anonymousSerializerBytes;
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
TypeSerializerSerializationUtil.writeSerializer(new DataOutputViewStreamWrapper(out), anonymousClassSerializer);
anonymousSerializerBytes = out.toByteArray();
}
long newSerialVersionUID = 1234567L;
// assert that we're actually modifying to a different serialVersionUID
Assert.assertNotEquals(ObjectStreamClass.lookup(anonymousClassSerializer.getClass()).getSerialVersionUID(), newSerialVersionUID);
modifySerialVersionUID(anonymousSerializerBytes, anonymousClassSerializer.getClass().getName(), newSerialVersionUID);
try (ByteArrayInputStream in = new ByteArrayInputStream(anonymousSerializerBytes)) {
anonymousClassSerializer = TypeSerializerSerializationUtil.tryReadSerializer(new DataInputViewStreamWrapper(in), Thread.currentThread().getContextClassLoader());
}
// serializer should have been deserialized despite serialVersionUID mismatch
Assert.assertNotNull(anonymousClassSerializer);
Assert.assertTrue(anonymousClassSerializer.getClass().isAnonymousClass());
}
@Override
protected Class<?> resolveClass(ObjectStreamClass aClass)
throws IOException, ClassNotFoundException {
if (loader == null) {
return super.resolveClass(aClass);
} else {
String name = aClass.getName();
ReflectUtil.checkPackageAccess(name);
// Query the class loader ...
return Class.forName(name, false, loader);
}
}
private static byte[] getSerializedForm(ObjectStreamClass desc) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try {
try (ObjectOutputStream oout = new ObjectOutputStream(bout)) {
oout.writeObject(desc);
}
} finally {
bout.close();
}
return bout.toByteArray();
}
private final Serializable readSerializable(final ClassLoader loader) {
String name = readString();
if (name == null) {
// For some reason we were unable to read the name of the Serializable (either there
// is nothing left in the Parcel to read, or the next value wasn't a String), so
// return null, which indicates that the name wasn't found in the parcel.
return null;
}
byte[] serializedData = createByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
try {
ObjectInputStream ois = new ObjectInputStream(bais) {
@Override
protected Class<?> resolveClass(ObjectStreamClass osClass)
throws IOException, ClassNotFoundException {
// try the custom classloader if provided
if (loader != null) {
Class<?> c = Class.forName(osClass.getName(), false, loader);
if (c != null) {
return c;
}
}
return super.resolveClass(osClass);
}
};
return (Serializable) ois.readObject();
} catch (IOException ioe) {
throw new RuntimeException("Parcelable encountered " +
"IOException reading a Serializable object (name = " + name +
")", ioe);
} catch (ClassNotFoundException cnfe) {
throw new RuntimeException("Parcelable encountered " +
"ClassNotFoundException reading a Serializable object (name = "
+ name + ")", cnfe);
}
}
/**
* @see ObjectInputStream#resolveClass(ObjectStreamClass)
*/
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException,
ClassNotFoundException {
String name = desc.getName();
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return Class.forName(name, false, classLoader);
} catch (ClassNotFoundException ex) {
return super.resolveClass(desc);
}
}
private void readObject(
ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
ObjectStreamClass myObject = ObjectStreamClass.lookup(
Class.forName(Rittner_Agilent7700_RawDataTemplate.class.getCanonicalName()));
long theSUID = myObject.getSerialVersionUID();
System.out.println("Customized De-serialization of Rittner_Agilent7700_RawDataTemplate " + theSUID);
}