use of javassist.bytecode.ClassFile in project audit4j-core by audit4j.
the class AnnotationDB method scanClass.
/**
* Parse a .class file for annotations
*
* @param bits
* input stream pointing to .class file bits
* @throws IOException
*/
public void scanClass(InputStream bits) throws IOException {
DataInputStream dstream = new DataInputStream(new BufferedInputStream(bits));
ClassFile cf = null;
try {
cf = new ClassFile(dstream);
classIndex.put(cf.getName(), new HashSet<String>());
if (scanClassAnnotations)
scanClass(cf);
if (scanMethodAnnotations || scanParameterAnnotations)
scanMethods(cf);
if (scanFieldAnnotations)
scanFields(cf);
// create an index of interfaces the class implements
if (cf.getInterfaces() != null) {
Set<String> intfs = new HashSet<String>();
for (String intf : cf.getInterfaces()) intfs.add(intf);
implementsIndex.put(cf.getName(), intfs);
}
} finally {
dstream.close();
bits.close();
}
}
use of javassist.bytecode.ClassFile in project latke by b3log.
the class Discoverer method discover.
/**
* Scans classpath to discover bean classes.
*
* @param scanPath the paths to scan, using ',' as the separator. There are two types of the scanPath:
* <ul>
* <li>package: org.b3log.process</li>
* <li>ant-style classpath: org/b3log/** /*process.class</li>
* </ul>
* @return discovered classes
* @throws Exception exception
*/
public static Collection<Class<?>> discover(final String scanPath) throws Exception {
if (Strings.isEmptyOrNull(scanPath)) {
throw new IllegalStateException("Please specify the [scanPath]");
}
LOGGER.debug("scanPath[" + scanPath + "]");
// See issue #17 (https://github.com/b3log/latke/issues/17) for more details
final Collection<Class<?>> ret = new HashSet<Class<?>>();
final String[] splitPaths = scanPath.split(",");
// Adds some built-in components
final String[] paths = ArrayUtils.concatenate(splitPaths, BUILT_IN_COMPONENT_PKGS);
final Set<URL> urls = new LinkedHashSet<URL>();
for (String path : paths) {
/*
* the being two types of the scanPath.
* 1 package: org.b3log.process
* 2 ant-style classpath: org/b3log/** /*process.class
*/
if (!AntPathMatcher.isPattern(path)) {
path = path.replaceAll("\\.", "/") + "/**/*.class";
}
urls.addAll(ClassPathResolver.getResources(path));
}
for (URL url : urls) {
final DataInputStream classInputStream = new DataInputStream(url.openStream());
final ClassFile classFile = new ClassFile(classInputStream);
final String className = classFile.getName();
final AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.visibleTag);
if (null == annotationsAttribute) {
LOGGER.log(Level.TRACE, "The class[name={0}] is not a bean", className);
continue;
}
final ConstPool constPool = classFile.getConstPool();
final Annotation[] annotations = annotationsAttribute.getAnnotations();
boolean maybeBeanClass = false;
for (final Annotation annotation : annotations) {
if (annotation.getTypeName().equals(RequestProcessor.class.getName())) {
// Request Processor is singleton scoped
final Annotation singletonAnnotation = new Annotation("javax.inject.Singleton", constPool);
annotationsAttribute.addAnnotation(singletonAnnotation);
classFile.addAttribute(annotationsAttribute);
classFile.setVersionToJava5();
maybeBeanClass = true;
break;
}
if (annotation.getTypeName().equals(Service.class.getName()) || (annotation.getTypeName()).equals(Repository.class.getName())) {
// Service and Repository is singleton scoped by default
maybeBeanClass = true;
break;
}
if (annotation.getTypeName().equals(Named.class.getName())) {
// Annoatated with Named maybe a bean class
maybeBeanClass = true;
break;
}
// Others will not load
}
if (maybeBeanClass) {
Class<?> clz = null;
try {
clz = Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (final ClassNotFoundException e) {
LOGGER.log(Level.ERROR, "some error to load the class[" + className + "]", e);
}
ret.add(clz);
}
}
return ret;
}
use of javassist.bytecode.ClassFile in project libSBOLj by SynBioDex.
the class OBOTermCreator method createTerm.
// /**
// * Dynamically generates a Class file, for an interface that represents an OBO term with the given fields.
// *
// * The OBO term is uniquely identified by the id, and if a term with this id has been converted into a Class
// * file already, then that Class file (cached within the OBOTermCreator object) will be returned immediately.
// *
// * @param id
// * @param name
// * @param def
// * @param comments
// * @param is_a
// * @param relTypes
// * @param relTypedefs
// * @return term
// * @throws CannotCompileException
// */
public Class createTerm(String id, String name, String def, String[] comments, Class[] is_a, Class[] relTypes, String[] relTypedefs) throws CannotCompileException {
String ccClassName = unmangleName(name);
if (created.containsKey(id)) {
return created.get(id);
}
if (created.containsKey(ccClassName)) {
return created.get(ccClassName);
}
OBOAnnotationParser obo = new OBOAnnotationParser();
ClassPool cp = ClassPool.getDefault();
CtClass stringClass = null, stringArrayClass = null;
try {
stringClass = cp.get("java.lang.String");
stringArrayClass = cp.get("java.lang.String[]");
} catch (NotFoundException e) {
throw new IllegalStateException(e);
}
CtClass cc = cp.makeInterface(ccClassName);
cc.setModifiers(javassist.Modifier.INTERFACE | javassist.Modifier.PUBLIC);
ClassFile ccFile = cc.getClassFile();
ConstPool constpool = ccFile.getConstPool();
Annotation termAnnotation = new Annotation("org.sc.obo.annotations.Term", constpool);
CtField idField = new CtField(stringClass, "id", cc);
idField.setModifiers(javassist.Modifier.PUBLIC | javassist.Modifier.STATIC | javassist.Modifier.FINAL);
CtField nameField = new CtField(stringClass, "name", cc);
nameField.setModifiers(javassist.Modifier.PUBLIC | javassist.Modifier.STATIC | javassist.Modifier.FINAL);
CtField defField = new CtField(stringClass, "def", cc);
defField.setModifiers(javassist.Modifier.PUBLIC | javassist.Modifier.STATIC | javassist.Modifier.FINAL);
cc.addField(idField, CtField.Initializer.constant(removeSlashes(id)));
cc.addField(nameField, CtField.Initializer.constant(removeSlashes(name)));
cc.addField(defField, CtField.Initializer.constant(removeSlashes(def)));
if (is_a != null) {
for (Class superClass : is_a) {
if (!obo.isTerm(superClass)) {
throw new IllegalArgumentException(superClass.getCanonicalName());
}
try {
CtClass superCtClass = cp.get(superClass.getCanonicalName());
cc.addInterface(superCtClass);
} catch (NotFoundException e) {
throw new IllegalArgumentException(e);
}
}
}
/*
* Finally, we convert all the relTypes/relTypedefs into methods.
*
* The main trick here is to do this in a way that the method names don't clash!
*
* We want to rename each method to a form that's unique to this class as well -- the reason is that
* Class A and Class B can have incompatible methods with the same name, which is fine since neither of
* them is a superclass (super-interface, whatevs) of the other.
*
* However, as soon as we define a Class C that extends both interfaces A & B, we have a problem -- suddenly
* we inherit both methods, but with incompatible types.
*
* So we need to mangle the names of A and B's classes, so that they are (a) descriptive, but (b) don't
* clash with other class's method names. This leads to ugly code generation, but ... it works.
*/
if (relTypes != null && relTypedefs != null) {
if (relTypes.length != relTypedefs.length) {
throw new IllegalArgumentException();
}
String[] nonDups = renameDuplicates(relTypedefs);
for (int i = 0; i < relTypes.length; i++) {
try {
if (relTypes[i] == null) {
throw new IllegalArgumentException(id + " " + Arrays.asList(relTypes));
}
Class arrayType = relTypes[i].isArray() ? relTypes[i] : getArrayType(relTypes[i]);
String typeName = arrayType.getCanonicalName();
String methodName = findNonConflictingName(ccClassName, arrayType, nonDups[i], null, is_a);
CtClass relTypeClass = cp.get(typeName);
CtMethod relMethod = new CtMethod(relTypeClass, methodName, new CtClass[] {}, cc);
relMethod.setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
// We need to create this with the *original* typedef name,
// not the new (non-clashing) method name. That way, we can recover the original
// name of the property from the (mangled) method name.
Annotation relAnnotation = new Annotation("org.sc.obo.annotations.Relates", constpool);
relAnnotation.addMemberValue("value", new StringMemberValue(relTypedefs[i], ccFile.getConstPool()));
AnnotationsAttribute annotations = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
annotations.addAnnotation(relAnnotation);
relMethod.getMethodInfo().addAttribute(annotations);
cc.addMethod(relMethod);
} catch (NotFoundException e) {
throw new IllegalArgumentException(e);
}
}
}
AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
attr.addAnnotation(termAnnotation);
ccFile.addAttribute(attr);
Class c = cc.toClass();
created.put(id, c);
created.put(ccClassName, c);
return c;
}
use of javassist.bytecode.ClassFile in project fakereplace by fakereplace.
the class FieldReplacementTransformer method addField.
/**
* This will create a proxy with a non static field. This field does not
* store anything, it merely provides a Field object for reflection. Attempts
* to change and read it's value are redirected to the actual array based
* store
*/
private static int addField(ClassLoader loader, FieldInfo m, Set<FieldProxyInfo> builder, Class<?> oldClass) {
int fieldNo = FieldReferenceDataStore.instance().getFieldNo(m.getName(), m.getDescriptor());
String proxyName = ProxyDefinitionStore.getProxyName();
ClassFile proxy = new ClassFile(false, proxyName, "java.lang.Object");
ClassDataStore.instance().registerProxyName(oldClass, proxyName);
FieldAccessor accessor = new FieldAccessor(oldClass, fieldNo, (m.getAccessFlags() & AccessFlag.STATIC) != 0);
ClassDataStore.instance().registerFieldAccessor(proxyName, accessor);
proxy.setAccessFlags(AccessFlag.PUBLIC);
FieldInfo newField = new FieldInfo(proxy.getConstPool(), m.getName(), m.getDescriptor());
newField.setAccessFlags(m.getAccessFlags());
copyFieldAttributes(m, newField);
try {
proxy.addField(newField);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bytes);
try {
proxy.write(dos);
} catch (IOException e) {
throw new RuntimeException(e);
}
ProxyDefinitionStore.saveProxyDefinition(loader, proxyName, bytes.toByteArray());
builder.add(new FieldProxyInfo(newField, proxyName, m.getAccessFlags()));
} catch (DuplicateMemberException e) {
// can't happen
}
return fieldNo;
}
use of javassist.bytecode.ClassFile in project fakereplace by fakereplace.
the class MethodReplacementTransformer method generateFakeConstructorBytecode.
/**
* creates a class with a fake constructor that can be used by the reflection
* api
* <p>
* Constructors are not invoked through the proxy class, instead we have to
* do a lot more bytecode re-writing at the actual invocation sites
*/
private static String generateFakeConstructorBytecode(MethodInfo mInfo, ClassLoader loader) throws BadBytecode {
String proxyName = ProxyDefinitionStore.getProxyName();
ClassFile proxy = new ClassFile(false, proxyName, "java.lang.Object");
proxy.setVersionToJava5();
proxy.setAccessFlags(AccessFlag.PUBLIC);
// add our new annotations directly onto the new proxy method. This way
// they will just work without registering them with the
// AnnotationDataStore
String[] types = DescriptorUtils.descriptorStringToParameterArray(mInfo.getDescriptor());
// as this method is never called the bytecode just returns
Bytecode b = new Bytecode(proxy.getConstPool());
b.add(Opcode.ALOAD_0);
b.addInvokespecial("java.lang.Object", "<init>", "()V");
b.add(Opcode.RETURN);
MethodInfo method = new MethodInfo(proxy.getConstPool(), mInfo.getName(), mInfo.getDescriptor());
method.setAccessFlags(mInfo.getAccessFlags());
method.setCodeAttribute(b.toCodeAttribute());
method.getCodeAttribute().computeMaxStack();
method.getCodeAttribute().setMaxLocals(types.length + 1);
copyMethodAttributes(mInfo, method);
try {
proxy.addMethod(method);
} catch (DuplicateMemberException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bytes);
proxy.write(dos);
ProxyDefinitionStore.saveProxyDefinition(loader, proxyName, bytes.toByteArray());
return proxyName;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Aggregations