private static ClassPool configureClassPool() { final ClassPool classPool = new ClassPool(ClassPool.getDefault()); classPool.appendClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader())); classPool.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader())); classPool.importPackage("com.lmax.tool.disruptor"); return classPool; }
public static void main(String... args) { classPool = new ClassPool(); classPool.importPackage("java.sql"); classPool.appendClassPath(new LoaderClassPath(JavassistProxyFactory.class.getClassLoader())); try { // Cast is not needed for these String methodBody = "{ try { return delegate.method($$); } catch (SQLException e) { throw checkException(e); } }"; generateProxyClass(Connection.class, ConnectionProxy.class.getName(), methodBody); generateProxyClass(Statement.class, StatementProxy.class.getName(), methodBody); generateProxyClass(ResultSet.class, ResultSetProxy.class.getName(), methodBody); // For these we have to cast the delegate methodBody = "{ try { return ((cast) delegate).method($$); } catch (SQLException e) { throw checkException(e); } }"; generateProxyClass( PreparedStatement.class, PreparedStatementProxy.class.getName(), methodBody); generateProxyClass( CallableStatement.class, CallableStatementProxy.class.getName(), methodBody); modifyProxyFactory(); } catch (Exception e) { throw new RuntimeException(e); } }
@Test public void testToString() throws Exception { ClassPool pool = ClassPool.getDefault(); System.out.println(pool.toString()); pool.appendSystemPath(); System.out.println(pool.toString()); pool.appendClassPath("/*"); System.out.println(pool.toString()); pool.importPackage("java.util"); System.out.println(pool.toString()); StringTokenizer st = new StringTokenizer(System.getProperty("java.class.path"), File.pathSeparator); Set<String> classpath = new HashSet<String>(); while (st.hasMoreElements()) classpath.add(st.nextToken()); for (String element : classpath) pool.appendClassPath(element); System.out.println(pool.toString()); Assert.assertTrue(true); }
/** * Creates a map of concrete json request handler invokers keyed by <b><code> * <service-name>/<op-name></code></b>. * * @param handlerInstance The request handler instance to generate invokers for * @return the map of generated invokers */ public static Map<String, Map<String, AbstractJSONRequestHandlerInvoker>> createInvokers( Object handlerInstance) { if (handlerInstance == null) throw new IllegalArgumentException("The passed handlerInstance was null"); Map<String, AbstractJSONRequestHandlerInvoker> subInvokerMap = new HashMap<String, AbstractJSONRequestHandlerInvoker>(); Map<String, Map<String, AbstractJSONRequestHandlerInvoker>> invokerMap = invokerCache.get(handlerInstance.getClass()); if (invokerMap != null) { LOG.info("Found Cached Invokers for [{}]", handlerInstance.getClass().getName()); return invokerMap; } invokerMap = new HashMap<String, Map<String, AbstractJSONRequestHandlerInvoker>>(1); LOG.info("Generating Invokers for [{}]", handlerInstance.getClass().getName()); JSONRequestService svc = handlerInstance.getClass().getAnnotation(JSONRequestService.class); final String invokerServiceKey = svc.name(); final String invokerServiceDescription = svc.description(); invokerMap.put(invokerServiceKey, subInvokerMap); ClassPool cp = new ClassPool(); cp.appendClassPath(new ClassClassPath(handlerInstance.getClass())); cp.appendClassPath(new ClassClassPath(AbstractJSONRequestHandlerInvoker.class)); cp.importPackage(handlerInstance.getClass().getPackage().getName()); Set<ClassLoader> classPathsAdded = new HashSet<ClassLoader>(); Set<String> packagesImported = new HashSet<String>(); try { final CtClass jsonRequestCtClass = cp.get(JSONRequest.class.getName()); final CtClass parent = cp.get(AbstractJSONRequestHandlerInvoker.class.getName()); CtClass targetClass = cp.get(handlerInstance.getClass().getName()); Collection<Method> methods = getTargetMethods(handlerInstance.getClass()); for (Method m : methods) { final JSONRequestHandler jsonHandler = m.getAnnotation(JSONRequestHandler.class); final String opName = jsonHandler.name(); final String opDescription = jsonHandler.description(); final RequestType opType = jsonHandler.type(); int targetMethodHashCode = m.toGenericString().hashCode(); final String className = String.format( "%s-%s%s-%s-%s", handlerInstance.getClass().getName(), invokerServiceKey, opName, "ServiceInvoker", targetMethodHashCode); final CtClass invokerClass = cp.makeClass(className, parent); CtField ctf = new CtField(targetClass, "typedTarget", invokerClass); ctf.setModifiers(ctf.getModifiers() | Modifier.FINAL); invokerClass.addField(ctf); for (CtConstructor parentCtor : parent.getConstructors()) { CtConstructor invokerCtor = CtNewConstructor.copy(parentCtor, invokerClass, null); invokerCtor.setBody( "{ super($$); typedTarget = (" + handlerInstance.getClass().getName() + ")$1; }"); invokerClass.addConstructor(invokerCtor); } CtMethod invokerMethod = CtNewMethod.copy( parent.getDeclaredMethod("doInvoke", new CtClass[] {jsonRequestCtClass}), invokerClass, null); StringBuilder b = new StringBuilder("{this.typedTarget.").append(m.getName()).append("($1"); final Class<?>[] ptypes = m.getParameterTypes(); final int remainingParamCount = ptypes.length - 1; // Set<Class<?>> classPathsAdded = new HashSet<Class<?>>(); // Set<String> packagesImported = new HashSet<String>(); if (remainingParamCount > 0) { for (int i = 0; i < remainingParamCount; i++) { final Class<?> type = ptypes[i + 1]; if (type.getName().contains("UniqueIdType")) { System.err.println("Comin Up...."); } if (type.isPrimitive()) { b.append(", (").append(type.getName()).append(") null"); } else { if (classPathsAdded.add(type.getClassLoader())) { cp.appendClassPath(new LoaderClassPath(type.getClassLoader())); } try { Package p = type.getPackage(); if (p == null) { if (type.isArray()) { if (!type.getComponentType().isPrimitive()) { p = type.getComponentType().getPackage(); } } } if (type.isEnum()) { final String f = type.getEnclosingClass().getName() + "." + type.getSimpleName(); b.append(", (").append(f).append(") null"); String pack = type.getEnclosingClass().getPackage().getName(); if (packagesImported.add(pack)) { cp.importPackage(pack); } continue; } if (p != null) { if (packagesImported.add(p.getName())) { cp.importPackage(p.getName()); } } } catch (Exception ex) { ex.printStackTrace(System.err); } b.append(", (").append(type.getSimpleName()).append(") null"); } } } b.append(");}"); System.out.println("[" + m.getName() + "]: [" + b.toString() + "]"); // invokerMethod.setBody("{this.typedTarget." + m.getName() + "($1);}"); invokerMethod.setBody(b.toString()); invokerMethod.setModifiers(invokerMethod.getModifiers() & ~Modifier.ABSTRACT); invokerClass.addMethod(invokerMethod); // invokerClass.writeFile(System.getProperty("java.io.tmpdir") + File.separator + // "jsoninvokers"); Class<?> clazz = invokerClass.toClass( handlerInstance.getClass().getClassLoader(), handlerInstance.getClass().getProtectionDomain()); Constructor<?> ctor = clazz.getDeclaredConstructor( Object.class, String.class, String.class, String.class, String.class, RequestType.class); AbstractJSONRequestHandlerInvoker invokerInstance = (AbstractJSONRequestHandlerInvoker) ctor.newInstance( handlerInstance, invokerServiceKey, invokerServiceDescription, opName, opDescription, opType); subInvokerMap.put(opName, invokerInstance); } invokerCache.put(handlerInstance.getClass(), invokerMap); return invokerMap; } catch (Exception ex) { LOG.error( "Failed to create RequestHandlerInvoker for [{}]", handlerInstance.getClass().getName(), ex); throw new RuntimeException( "Failed to create RequestHandlerInvoker [" + handlerInstance.getClass().getName() + "]", ex); } }
public byte[] transform( ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (infos.isEmpty()) { return null; } String convertedClassName = className.replace('/', '.'); SingleTableInheritanceInfo key = new SingleTableInheritanceInfo(); key.setClassName(convertedClassName); int pos = infos.indexOf(key); if (pos >= 0) { try { if (LOG.isDebugEnabled()) { LOG.debug("Converting " + convertedClassName + " to a SingleTable inheritance strategy."); } SingleTableInheritanceInfo myInfo = infos.get(pos); ClassFile classFile = new ClassFile(new DataInputStream(new ByteArrayInputStream(classfileBuffer))); ConstPool constantPool = classFile.getConstPool(); AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constantPool, AnnotationsAttribute.visibleTag); List<?> attributes = classFile.getAttributes(); Iterator<?> itr = attributes.iterator(); while (itr.hasNext()) { Object object = itr.next(); if (AnnotationsAttribute.class.isAssignableFrom(object.getClass())) { AnnotationsAttribute attr = (AnnotationsAttribute) object; Annotation[] items = attr.getAnnotations(); for (Annotation annotation : items) { String typeName = annotation.getTypeName(); if (!typeName.equals(Inheritance.class.getName()) && ((myInfo.getDiscriminatorName() == null && !typeName.equals(Table.class.getName())) || myInfo.getDiscriminatorName() != null)) { annotationsAttribute.addAnnotation(annotation); } } itr.remove(); } } Annotation inheritance = new Annotation(Inheritance.class.getName(), constantPool); ClassPool pool = ClassPool.getDefault(); pool.importPackage("javax.persistence"); pool.importPackage("java.lang"); EnumMemberValue strategy = (EnumMemberValue) Annotation.createMemberValue(constantPool, pool.makeClass("InheritanceType")); strategy.setType(InheritanceType.class.getName()); strategy.setValue(InheritanceType.SINGLE_TABLE.name()); inheritance.addMemberValue("strategy", strategy); annotationsAttribute.addAnnotation(inheritance); if (myInfo.getDiscriminatorName() != null) { Annotation discriminator = new Annotation(DiscriminatorColumn.class.getName(), constantPool); StringMemberValue name = new StringMemberValue(constantPool); name.setValue(myInfo.getDiscriminatorName()); discriminator.addMemberValue("name", name); EnumMemberValue discriminatorType = (EnumMemberValue) Annotation.createMemberValue(constantPool, pool.makeClass("DiscriminatorType")); discriminatorType.setType(DiscriminatorType.class.getName()); discriminatorType.setValue(myInfo.getDiscriminatorType().name()); discriminator.addMemberValue("discriminatorType", discriminatorType); IntegerMemberValue length = new IntegerMemberValue(constantPool); length.setValue(myInfo.getDiscriminatorLength()); discriminator.addMemberValue("length", length); annotationsAttribute.addAnnotation(discriminator); } classFile.addAttribute(annotationsAttribute); ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream os = new DataOutputStream(bos); classFile.write(os); os.close(); return bos.toByteArray(); } catch (Exception ex) { ex.printStackTrace(); throw new IllegalClassFormatException( "Unable to convert " + convertedClassName + " to a SingleTable inheritance strategy: " + ex.getMessage()); } } else { return null; } }
public ClazzInfo classProcessing(String clazzName) throws NotFoundException, CannotCompileException { ClassPool classPool = ClassPool.getDefault(); CtClass cz = classPool.get(clazzName); classPool.importPackage(clazzName); // 继承 classPool.importPackage("java.lang.reflect.Method"); // 添加反射引用 CtClass newClass = classPool.makeClass(clazzName + "$MC_IMPL"); // 新建代理类 newClass.setSuperclass(cz); // 继承 // 构造块 CtConstructor tempC; CtConstructor[] ctConstructors = cz.getDeclaredConstructors(); newClass.addConstructor(CtNewConstructor.defaultConstructor(newClass)); for (CtConstructor c : ctConstructors) { try { tempC = CtNewConstructor.copy(c, newClass, null); tempC.setBody("{super($$);}"); newClass.addConstructor(tempC); } catch (Exception e) { // e.printStackTrace(); } } // 字段块 // CtField[] ctFields = cz.getDeclaredFields(); // for (CtField f : ctFields) // System.out.println(f.getFieldInfo().getConstantValue()); // 方法块 CtMethod[] ctMethods = cz.getDeclaredMethods(); CtMethod tempM; // 复制方法名 Map<String, Method> tempMethod = new HashMap<String, Method>(); for (CtMethod m : ctMethods) { tempMethod.put( String.format( "%s %s %s(%s);", Modifier.toString(m.getModifiers()), m.getReturnType().getName(), m.getName(), Util.getParameterTypes(m.getParameterTypes())), null); // System.err.println(String.format("%s %s %s(%s);", Modifier.toString(m.getModifiers()), // m.getReturnType().getName(), m.getName(), Util.getParameterTypes(m.getParameterTypes()))); tempM = CtNewMethod.copy(m, newClass, null); if ("void".equals(tempM.getReturnType().getName())) tempM.setBody("{super." + tempM.getName() + "($$);}"); else tempM.setBody("{ return super." + tempM.getName() + "($$);}"); // CtNewMethod.make(src, declaring, delegateObj, delegateMethod) // 方法修改 // if (m.getName().equals("x")) { // //tempM.setBody("{$proceed($$);}", "this", "mba"); // //tempM.setBody("{n nn = new n();" + "Method a = n.class.getDeclaredMethod(\"a\", new // Class[] { Integer.TYPE });" + "a.invoke(nn, new Object[] { Integer.valueOf(1) });}"); // tempM.setBody("{Method a = n.class.getDeclaredMethod(\"axx\", new Class[] { Integer.TYPE // });}"); // } newClass.addMethod(tempM); } // 测试输出 try { newClass.writeFile("D:/Desktop"); } catch (IOException e) { e.printStackTrace(); } // Class clazz = newClass.toClass(); // System.out.println(clazz.getCanonicalName()); // DefaultCachePoolFactory.newInstance().addNFloop4Map(new ClazzInfo(clazz, tempMethod), // DefaultPool.NORNAL_BEAN, clazz.getCanonicalName()); // return clazz; return new ClazzInfo(newClass.toClass(), tempMethod); }