This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-bcel.git
The following commit(s) were added to refs/heads/master by this push: new 3c38bf6f Improve condy (constant dynamic) support (#139) 3c38bf6f is described below commit 3c38bf6ff295f82d619d078d836699e2b1377ad7 Author: Alexander Kriegisch <alexan...@kriegisch.name> AuthorDate: Mon Aug 15 19:53:28 2022 +0200 Improve condy (constant dynamic) support (#139) * [BCEL-362] Improve condy (constant dynamic) support Fixes https://issues.apache.org/jira/browse/BCEL-362. There was a problem when processing JaCoCo-instrumented code with BCEL, e.g. when passing it through example class JasminVisitor, causing java.lang.ClassCastException: class org.apache.bcel.classfile.ConstantMethodref cannot be cast to class org.apache.bcel.classfile.ConstantClass (org.apache.bcel.classfile.ConstantMethodref and org.apache.bcel.classfile.ConstantClass are in unnamed module of loader 'app') at org.apache.bcel.generic.ConstantPoolGen.<init>(ConstantPoolGen.java:153) at org.apache.bcel.generic.ConstantPoolGen.<init>(ConstantPoolGen.java:211) at de.example.JasminVisitor.<init>(JasminVisitor.java:70) * [BCEL-362] Add test case with JaCoCo-instrumented class file * We don't use author tags Instead, we document contributions in `changes.xml` which I'll update after I merge PR. Co-authored-by: Gary Gregory <garydgreg...@users.noreply.github.com> --- .../org/apache/bcel/classfile/ConstantPool.java | 6 ++++ .../org/apache/bcel/generic/ConstantPoolGen.java | 6 ++-- .../apache/bcel/generic/JiraBcel362TestCase.java | 38 +++++++++++++++++++++ src/test/resources/issue362/Bcel362.class | Bin 0 -> 903 bytes src/test/resources/issue362/Bcel362.java | 28 +++++++++++++++ 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/bcel/classfile/ConstantPool.java b/src/main/java/org/apache/bcel/classfile/ConstantPool.java index d8a5514f..b0531cfc 100644 --- a/src/main/java/org/apache/bcel/classfile/ConstantPool.java +++ b/src/main/java/org/apache/bcel/classfile/ConstantPool.java @@ -182,6 +182,12 @@ public class ConstantPool implements Cloneable, Node { + ":" + constantToString(cid.getNameAndTypeIndex(), Const.CONSTANT_NameAndType); break; + case Const.CONSTANT_Dynamic: + final ConstantDynamic cd = (ConstantDynamic) c; + str = cd.getBootstrapMethodAttrIndex() + + ":" + constantToString(cd.getNameAndTypeIndex(), + Const.CONSTANT_NameAndType); + break; case Const.CONSTANT_Module: i = ((ConstantModule) c).getNameIndex(); c = getConstant(i, Const.CONSTANT_Utf8); diff --git a/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java b/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java index eb6370e5..a016faf8 100644 --- a/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java +++ b/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java @@ -25,6 +25,7 @@ import org.apache.bcel.classfile.Constant; import org.apache.bcel.classfile.ConstantCP; import org.apache.bcel.classfile.ConstantClass; import org.apache.bcel.classfile.ConstantDouble; +import org.apache.bcel.classfile.ConstantDynamic; import org.apache.bcel.classfile.ConstantFieldref; import org.apache.bcel.classfile.ConstantFloat; import org.apache.bcel.classfile.ConstantInteger; @@ -170,8 +171,8 @@ public class ConstantPoolGen { if (c instanceof ConstantInvokeDynamic) { class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex()); - // since name can't begin with digit, can use - // METHODREF_DELIM with out fear of duplicates. + } else if (c instanceof ConstantDynamic) { + class_name = Integer.toString(((ConstantDynamic) m).getBootstrapMethodAttrIndex()); } else { final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; @@ -184,6 +185,7 @@ public class ConstantPoolGen { u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; final String signature = u8.getBytes(); + // Since name cannot begin with digit, we can use METHODREF_DELIM without fear of duplicates String delim = METHODREF_DELIM; if (c instanceof ConstantInterfaceMethodref) { delim = IMETHODREF_DELIM; diff --git a/src/test/java/org/apache/bcel/generic/JiraBcel362TestCase.java b/src/test/java/org/apache/bcel/generic/JiraBcel362TestCase.java new file mode 100644 index 00000000..53f06f27 --- /dev/null +++ b/src/test/java/org/apache/bcel/generic/JiraBcel362TestCase.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.bcel.generic; + +import org.apache.bcel.AbstractTestCase; +import org.apache.bcel.classfile.JavaClass; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verify that a constant pool containing dynamic constants (condy) - in this case created by JaCoCo - + * can be read and the corresponding constant is found after parsing. + */ +public class JiraBcel362TestCase extends AbstractTestCase { + @Test + public void testProcessConstantPoolWithCondyEntry() throws ClassNotFoundException { + final JavaClass clazz = getTestClass("issue362.Bcel362"); + ConstantPoolGen constantPoolGen = assertDoesNotThrow(() -> new ConstantPoolGen(clazz.getConstantPool())); + assertTrue(constantPoolGen.lookupUtf8("$jacocoData") != -1); + } +} diff --git a/src/test/resources/issue362/Bcel362.class b/src/test/resources/issue362/Bcel362.class new file mode 100644 index 00000000..b1e1415e Binary files /dev/null and b/src/test/resources/issue362/Bcel362.class differ diff --git a/src/test/resources/issue362/Bcel362.java b/src/test/resources/issue362/Bcel362.java new file mode 100644 index 00000000..736dd6c8 --- /dev/null +++ b/src/test/resources/issue362/Bcel362.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package issue362; + +/** + * Compile to Java 11 byte code, then instrument with JaCoCo in order to add + * condy (constant dynamic) instructions + */ +public class Bcel362 { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +}