@Override public void weave(WovenClass wovenClass) { BundleWiring wiring = wovenClass.getBundleWiring(); Bundle bundle = wiring.getBundle(); ClassLoader cl = wiring.getClassLoader(); Collection<ClassTransformer> transformersToTry = getTransformers(bundle); for (ClassTransformer transformer : transformersToTry) { if (transformClass(wovenClass, cl, transformer)) { LOGGER.info("Weaving " + wovenClass.getClassName() + " using " + transformer.getClass().getName()); break; } } Class<?> dClass = wovenClass.getDefinedClass(); if (transformersToTry.isEmpty() && dClass != null && dClass.getAnnotation(Entity.class) != null) { LOGGER.warn("Loading " + wovenClass.getClassName() + " before transformer is present"); } }
private static boolean transformClass(WovenClass wovenClass, ClassLoader cl, ClassTransformer transformer) throws ThreadDeath, OutOfMemoryError { try { byte[] result = transformer .transform(cl, wovenClass.getClassName(), wovenClass.getDefinedClass(), wovenClass.getProtectionDomain(), wovenClass.getBytes()); if (result != null) { wovenClass.setBytes(result); wovenClass.getDynamicImports().add("org.eclipse.persistence.*"); wovenClass.getDynamicImports().add("org.apache.openjpa.*"); return true; } } catch (Exception t) { Bundle b = wovenClass.getBundleWiring().getBundle(); String msg = String.format("Weaving failure on class %s in bundle %s/%s using transformer %s", wovenClass.getClassName(), b.getSymbolicName(), b.getVersion(), transformer); throw new WeavingException(msg, t); } return false; }
@Override public void modified(WovenClass wovenClass) { if (wovenClass.getState() == WovenClass.TRANSFORMED) { boolean createNewLayer; // need to make sure the class loader is associated with a layer before allowing a class define layersRead.lock(); try { // check if there is an existing module for this wiring createNewLayer = wiringToModule.get(wovenClass.getBundleWiring()) == null; } finally { layersRead.unlock(); } if (createNewLayer) { createNewWiringLayers(); } } }
@Override public void weave(WovenClass wovenClass) { BundleWiring wiring = wovenClass.getBundleWiring(); if (!wovenClass.getDynamicImports().contains(SERVICES_FILE_PACKAGE) && !hasRequirement(wiring, SERVICES_FILE_PACKAGE) && !hasFile(wiring, SERVICES_FILE)) { LOGGER.debug("Adding a {} dynamic import to {}", SERVICES_FILE_PACKAGE, wiring.getBundle().getSymbolicName()); wovenClass.getDynamicImports().add(SERVICES_FILE_PACKAGE); if (!wovenClass.getDynamicImports().contains(JSR_303_IMPORT)) { wovenClass.getDynamicImports().add(JSR_303_IMPORT); } if (!wovenClass.getDynamicImports().contains(CONSTRAINTS_IMPORT)) { wovenClass.getDynamicImports().add(CONSTRAINTS_IMPORT); } } }
@Override public void weave(WovenClass wovenClass) { String className = wovenClass.getClassName(); // we should omit classes from slf4j library to avoid exception about missing class // definition of org.slf4j.helpers.MessageFormatter (it isn't exported by slf4j bundle) if (className.startsWith("org.slf4j")) { return; } LOGGER.trace("Weaving called for: {}", className); ClassData enhancedClassData = MotechClassPool.getEnhancedClassData(className); if (enhancedClassData == null) { LOGGER.trace("The class doesn't have enhanced metadata: {}", className); } else { LOGGER.info("Weaving {}", className); // these imports will be required by the provider addCommonImports(wovenClass); // add dynamic imports to enums and mds entities addDynamicImports(wovenClass); // change the bytecode wovenClass.setBytes(enhancedClassData.getBytecode()); } }
private void completeClass(WovenClass wovenClass) { // System.out.println("Woven: "+wovenClass); ClassReader cr = new ClassReader(wovenClass.getBytes()); LabelAnalyzer labelAnalyzer = new LabelAnalyzer(); cr.accept(labelAnalyzer, 0); Map<String, Label> tag2Label = labelAnalyzer.getTag2Label(); /* for (Entry<String, Label> entry : tag2Label.entrySet()) { System.out.println(entry.getKey() + "=" + entry.getValue() + "(" + entry.getValue().info + ")"); }*/ ClassWriter cw = new ClassWriter(cr, 0); ClassAdapter ca = new JumpTransformer(cw, wovenClass.getClassName().replace(".", "/"), tag2Label); cr.accept(ca, 0); wovenClass.setBytes(cw.toByteArray()); }
private void addDynamicImports(WovenClass wovenClass) { List<String> dynamicImports = wovenClass.getDynamicImports(); List<String> packages = Arrays.asList( ClassName.getEnumPackage(wovenClass.getClassName()), Constants.PackagesGenerated.ENTITY); for (String pkg : packages) { if (!dynamicImports.contains(pkg)) { dynamicImports.add(pkg); } } }
private void addCommonImports(WovenClass wovenClass) { List<String> dynamicImports = wovenClass.getDynamicImports(); for (String sdi : STANDARD_DYNAMIC_IMPORTS) { if (!dynamicImports.contains(sdi)) { dynamicImports.add(sdi); } } }
@Override public void weave(WovenClass clz) { if (!hasBundle(clz.getBundleWiring().getBundle())) return; if (!clz.getDynamicImports().containsAll(imports)) { clz.getDynamicImports().addAll(imports); } }
@Override public void weave(WovenClass clazz) { try { if (transformers.isEmpty()) { return; } BundleWiring wiring = clazz.getBundleWiring(); Bundle b = wiring.getBundle(); ClassTransformer trfs[]; synchronized (transformers) { Collection<ClassTransformer> list = transformers.get(b); if (list == null) { return; } trfs = list.toArray(new ClassTransformer[list.size()]); } LOGGER.info("Transforming {} with {}", clazz.getClassName(), Arrays.toString(trfs)); for (ClassTransformer ctf : trfs) { if (ctf != null) { ctf.transform(wiring.getClassLoader(), clazz.getClassName(), clazz.getDefinedClass(), clazz.getProtectionDomain(), clazz.getBytes()); } } if (!imports.isEmpty()) { clazz.getDynamicImports().addAll(imports); } } catch (Exception e) { LOGGER.error("Error while weaving class {}", clazz.getClassName(), e); } }
@Override public void weave(WovenClass wovenClass) { if (weavingEnabled==0) return; try { String className = wovenClass.getClassName(); if (className.equals("org.eclipse.swt.custom.CLabel")) { transform(wovenClass); } } catch (ClassCircularityError cce) { // TODO } }
@Override public void weave(WovenClass clazz) { try { if (transformers.isEmpty()) return; BundleWiring wiring = clazz.getBundleWiring(); Bundle b = wiring.getBundle(); ClassTransformer trfs[]; synchronized (transformers) { List<ClassTransformer> list = transformers.get(b); if (list == null) return; trfs = list.toArray(empty); } System.out.println("transforming " + Arrays.toString(trfs) + " " + clazz); for (ClassTransformer ctf : trfs) { if (ctf != null) { ctf.transform(wiring.getClassLoader(), clazz.getClassName(), clazz.getDefinedClass(), clazz.getProtectionDomain(), clazz.getBytes()); } } if (!imports.isEmpty()) clazz.getDynamicImports().addAll(imports); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
@Override public void weave(WovenClass wovenClass) { BundleWiring bundleWiring = wovenClass.getBundleWiring(); Bundle bundle = bundleWiring.getBundle(); // ASUP project // TODO for performances reason, check a single file not directory if (bundle.getSymbolicName().startsWith("com.smeup.erp.gen") || bundle.getSymbolicName().startsWith("com.smeup.erp.ovr")) { completeClass(wovenClass); } }
@Override public void weave(WovenClass wovenClass) { // do nothing; just need to make sure there is a hook so the WovenClassListener will get called }
public void transform(WovenClass wovenClass) { byte[] bytes = wovenClass.getBytes(); ClassReader cr = new ClassReader(bytes); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); cr.accept(cw, 0); Method md = Method .getMethod("org.eclipse.swt.graphics.Color getForeground ()"); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, md.getName(), md.getDescriptor(), null, null); final GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, md, mv); final Label LABEL_SKIP_CALL_TO_SUPER = new Label(); final Label LABEL_LOOP_CMP = new Label(); final Label LABEL_LOOP_START = new Label(); mg.newInstance(Type.getType(Exception.class)); mg.dup(); mg.invokeConstructor(Type.getType(Exception.class), Method.getMethod("void <init> ()")); mg.invokeVirtual(Type.getType(Exception.class), Method.getMethod("StackTraceElement[] getStackTrace ()")); mg.storeLocal(1,Type.getType(StackTraceElement[].class)); mg.push(10); mg.storeLocal(2,Type.getType(int.class)); mg.goTo(LABEL_LOOP_CMP); mg.mark(LABEL_LOOP_START); mg.loadLocal(1); mg.loadLocal(2); mg.arrayLoad(Type.getType(StackTraceElement.class)); mg.invokeVirtual(Type.getType(StackTraceElement.class), Method.getMethod("String getClassName ()")); mg.push("Dialog"); mg.invokeVirtual(Type.getType(String.class), Method.getMethod("int indexOf (String)")); mg.push(-1); mg.ifICmp(GeneratorAdapter.EQ, LABEL_SKIP_CALL_TO_SUPER); // //XXX: DEBUG // mg.getStatic(Type.getType(System.class), "out", Type.getType(java.io.PrintStream.class)); // mg.push("2"); // mg.invokeVirtual(Type.getType(java.io.PrintStream.class), Method.getMethod("void println (String)")); // //XXX: DEBUG mg.loadThis(); mg.invokeConstructor(Type.getType("Lorg/eclipse/swt/widgets/Control;"), Method.getMethod("org.eclipse.swt.graphics.Color getForeground ()")); mg.returnValue(); mg.mark(LABEL_SKIP_CALL_TO_SUPER); mg.iinc(2, 1); mg.mark(LABEL_LOOP_CMP); mg.loadLocal(2); mg.loadLocal(1); mg.arrayLength(); mg.ifICmp(GeneratorAdapter.LT, LABEL_LOOP_START); mg.loadThis(); mg.invokeVirtual(Type.getType("Lorg/eclipse/swt/custom/CLabel;"), Method.getMethod("org.eclipse.swt.widgets.Display getDisplay ()")); mg.push(1); mg.invokeVirtual(Type.getType("Lorg/eclipse/swt/widgets/Display;"), Method.getMethod("org.eclipse.swt.graphics.Color getSystemColor (int)")); mg.returnValue(); mg.endMethod(); cw.visitEnd(); wovenClass.setBytes(cw.toByteArray()); }