@Override public void visitMethod( final Method method ) { final MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); _out.println(" InstructionList il = new InstructionList();"); _out.println(" MethodGen method = new MethodGen(" + printFlags(method.getAccessFlags(), FLAGS.METHOD) + ", " + printType(mg.getReturnType()) + ", " + printArgumentTypes(mg.getArgumentTypes()) + ", " + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true) + " }, \"" + method.getName() + "\", \"" + _clazz.getClassName() + "\", il, _cp);"); _out.println(); final BCELFactory factory = new BCELFactory(mg, _out); factory.start(); _out.println(" method.setMaxStack();"); _out.println(" method.setMaxLocals();"); _out.println(" _cg.addMethod(method.getMethod());"); _out.println(" il.dispose();"); }
@Test public void test() throws Exception { String classfile = getClass().getResource("Bug8003147Test.class").getPath(); JavaClass jc = new ClassParser(classfile).parse(); // rename class ConstantPool cp = jc.getConstantPool(); int cpIndex = ((ConstantClass) cp.getConstant(jc.getClassNameIndex())).getNameIndex(); cp.setConstant(cpIndex, new ConstantUtf8("Bug8003147TestPrime")); ClassGen gen = new ClassGen(jc); Method[] methods = jc.getMethods(); int index; for (index = 0; index < methods.length; index++) { if (methods[index].getName().equals("doSomething")) { break; } } Method m = methods[index]; MethodGen mg = new MethodGen(m, gen.getClassName(), gen.getConstantPool()); gen.replaceMethod(m, mg.getMethod()); String path = classfile.replace("Bug8003147Test", "Bug8003147TestPrime"); gen.getJavaClass().dump(new FileOutputStream(path)); try { Class.forName("Bug8003147TestPrime"); } catch (ClassFormatError cfe) { cfe.printStackTrace(); Assert.fail("modified version of class does not pass verification"); } }
BCELFactory(final MethodGen mg, final PrintWriter out) { _mg = mg; _cp = mg.getConstantPool(); _out = out; }
@Test public void test() throws Exception { // Note: Because BCEL library is always behind java version, to make sure // JavaClass can parse the class file, create a separate // Bug8003147TestClass.java, which only uses basic features. JAXPTestUtilities.tryRunWithTmpPermission(() -> { String classfile = getSystemProperty("test.classes") + "/parsers/Bug8003147TestClass.class"; JavaClass jc = new ClassParser(classfile).parse(); // rename class ConstantPool cp = jc.getConstantPool(); int cpIndex = ((ConstantClass) cp.getConstant(jc.getClassNameIndex())).getNameIndex(); cp.setConstant(cpIndex, new ConstantUtf8("parsers/Bug8003147TestClassPrime")); ClassGen gen = new ClassGen(jc); Method[] methods = jc.getMethods(); int index; for (index = 0; index < methods.length; index++) { if (methods[index].getName().equals("doSomething")) { break; } } Method m = methods[index]; MethodGen mg = new MethodGen(m, gen.getClassName(), gen.getConstantPool()); // @bug 8064516, not currently used directly by JAXP, but we may need // to modify preexisting methods in the future. InstructionFactory f = new InstructionFactory(gen); InstructionList il = mg.getInstructionList(); InstructionList newInst = new InstructionList(); newInst.append(f.createPrintln("Hello Sekai!")); il.insert(newInst); mg.setMaxStack(); gen.replaceMethod(m, mg.getMethod()); String path = classfile.replace("Bug8003147TestClass", "Bug8003147TestClassPrime"); gen.getJavaClass().dump(new FileOutputStream(path)); try { Class.forName("parsers.Bug8003147TestClassPrime"); } catch (ClassFormatError cfe) { cfe.printStackTrace(); Assert.fail("modified version of class does not pass verification"); } }, new FilePermission(getSystemProperty("test.classes") + "/-", "read,write")); }