feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.bind.v2.bytecode;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sun.xml.internal.bind.Util;
|
||||
|
||||
/**
|
||||
* Replaces a few constant pool tokens from a class "template" and then loads it into the VM.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class ClassTailor {
|
||||
|
||||
private ClassTailor() {} // no instanciation please
|
||||
|
||||
private static final Logger logger = Util.getClassLogger();
|
||||
|
||||
/**
|
||||
* Returns the class name in the JVM format (such as "java/lang/String")
|
||||
*/
|
||||
public static String toVMClassName( Class c ) {
|
||||
assert !c.isPrimitive();
|
||||
if(c.isArray())
|
||||
// I have no idea why it is designed like this, but javap says so.
|
||||
return toVMTypeName(c);
|
||||
return c.getName().replace('.','/');
|
||||
}
|
||||
|
||||
public static String toVMTypeName( Class c ) {
|
||||
if(c.isArray()) {
|
||||
// TODO: study how an array type is encoded.
|
||||
return '['+toVMTypeName(c.getComponentType());
|
||||
}
|
||||
if(c.isPrimitive()) {
|
||||
if(c==Boolean.TYPE) return "Z";
|
||||
if(c==Character.TYPE) return "C";
|
||||
if(c==Byte.TYPE) return "B";
|
||||
if(c==Double.TYPE) return "D";
|
||||
if(c==Float.TYPE) return "F";
|
||||
if(c==Integer.TYPE) return "I";
|
||||
if(c==Long.TYPE) return "J";
|
||||
if(c==Short.TYPE) return "S";
|
||||
|
||||
throw new IllegalArgumentException(c.getName());
|
||||
}
|
||||
return 'L'+c.getName().replace('.','/')+';';
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static byte[] tailor( Class templateClass, String newClassName, String... replacements ) {
|
||||
String vmname = toVMClassName(templateClass);
|
||||
return tailor(
|
||||
SecureLoader.getClassClassLoader(templateClass).getResourceAsStream(vmname+".class"),
|
||||
vmname, newClassName, replacements );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Customizes a class file by replacing constant pools.
|
||||
*
|
||||
* @param image
|
||||
* The image of the template class.
|
||||
* @param replacements
|
||||
* A list of pair of strings that specify the substitution
|
||||
* {@code String[]{search_0, replace_0, search_1, replace_1, ..., search_n, replace_n }}
|
||||
*
|
||||
* The search strings found in the constant pool will be replaced by the corresponding
|
||||
* replacement string.
|
||||
*/
|
||||
public static byte[] tailor( InputStream image, String templateClassName, String newClassName, String... replacements ) {
|
||||
DataInputStream in = new DataInputStream(image);
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
||||
DataOutputStream out = new DataOutputStream(baos);
|
||||
|
||||
// skip until the constant pool count
|
||||
long l = in.readLong();
|
||||
out.writeLong(l);
|
||||
|
||||
// read the constant pool size
|
||||
short count = in.readShort();
|
||||
out.writeShort(count);
|
||||
|
||||
// replace constant pools
|
||||
for( int i=0; i<count; i++ ) {
|
||||
byte tag = in.readByte();
|
||||
out.writeByte(tag);
|
||||
switch(tag) {
|
||||
case 0:
|
||||
// this isn't described in the spec,
|
||||
// but class files often seem to have this '0' tag.
|
||||
// we can apparently just ignore it, but not sure
|
||||
// what this really means.
|
||||
break;
|
||||
|
||||
case 1: // CONSTANT_UTF8
|
||||
{
|
||||
String value = in.readUTF();
|
||||
if(value.equals(templateClassName))
|
||||
value = newClassName;
|
||||
else {
|
||||
for( int j=0; j<replacements.length; j+=2 )
|
||||
if(value.equals(replacements[j])) {
|
||||
value = replacements[j+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
out.writeUTF(value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // CONSTANT_Integer
|
||||
case 4: // CONSTANT_Float
|
||||
out.writeInt(in.readInt());
|
||||
break;
|
||||
|
||||
case 5: // CONSTANT_Long
|
||||
case 6: // CONSTANT_Double
|
||||
i++; // doubles and longs take two entries
|
||||
out.writeLong(in.readLong());
|
||||
break;
|
||||
|
||||
case 7: // CONSTANT_Class
|
||||
case 8: // CONSTANT_String
|
||||
out.writeShort(in.readShort());
|
||||
break;
|
||||
|
||||
case 9: // CONSTANT_Fieldref
|
||||
case 10: // CONSTANT_Methodref
|
||||
case 11: // CONSTANT_InterfaceMethodref
|
||||
case 12: // CONSTANT_NameAndType
|
||||
out.writeInt(in.readInt());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown constant type "+tag);
|
||||
}
|
||||
}
|
||||
|
||||
// then copy the rest
|
||||
byte[] buf = new byte[512];
|
||||
int len;
|
||||
while((len=in.read(buf))>0)
|
||||
out.write(buf,0,len);
|
||||
|
||||
in.close();
|
||||
out.close();
|
||||
|
||||
// by now we got the properly tailored class file image
|
||||
return baos.toByteArray();
|
||||
|
||||
} catch( IOException e ) {
|
||||
// never happen
|
||||
logger.log(Level.WARNING,"failed to tailor",e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.bind.v2.bytecode;
|
||||
|
||||
/**
|
||||
* Class defined for safe calls of getClassLoader methods of any kind (context/system/class
|
||||
* classloader. This MUST be package private and defined in every package which
|
||||
* uses such invocations.
|
||||
* @author snajper
|
||||
*/
|
||||
class SecureLoader {
|
||||
|
||||
static ClassLoader getContextClassLoader() {
|
||||
if (System.getSecurityManager() == null) {
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
} else {
|
||||
return (ClassLoader) java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public java.lang.Object run() {
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static ClassLoader getClassClassLoader(final Class c) {
|
||||
if (System.getSecurityManager() == null) {
|
||||
return c.getClassLoader();
|
||||
} else {
|
||||
return (ClassLoader) java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public java.lang.Object run() {
|
||||
return c.getClassLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static ClassLoader getSystemClassLoader() {
|
||||
if (System.getSecurityManager() == null) {
|
||||
return ClassLoader.getSystemClassLoader();
|
||||
} else {
|
||||
return (ClassLoader) java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public java.lang.Object run() {
|
||||
return ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user