This is an automated email from the ASF dual-hosted git repository. alien11689 pushed a commit to branch ARIES-2129-make-proxy-support-java-8-and-above-without-explicit-asm-opcodes in repository https://gitbox.apache.org/repos/asf/aries.git
commit 90cbd04a13a782a4d2f7310d89387ac69cabf08c Author: Dominik Przybysz <[email protected]> AuthorDate: Tue Sep 22 20:06:35 2026 +0200 ARIES-2129: Make proxy support Java 8 and above without explicit ASM Opcodes constant --- proxy/proxy-impl/pom.xml | 8 +- .../org/apache/aries/proxy/impl/ProxyUtils.java | 140 +++++---------------- .../impl/common/AbstractWovenProxyAdapter.java | 3 - .../proxy/impl/weaving/WovenProxyGenerator.java | 11 +- .../apache/aries/proxy/impl/ProxyUtilsTest.java | 63 ++++++++++ proxy/proxy-itests/pom.xml | 2 +- 6 files changed, 100 insertions(+), 127 deletions(-) diff --git a/proxy/proxy-impl/pom.xml b/proxy/proxy-impl/pom.xml index 96331085d..1ef31611d 100644 --- a/proxy/proxy-impl/pom.xml +++ b/proxy/proxy-impl/pom.xml @@ -172,9 +172,9 @@ <profiles> <profile> - <id>java9To25</id> + <id>java9To27</id> <activation> - <jdk>(8,26)</jdk> + <jdk>(8,28)</jdk> </activation> <build> <plugins> @@ -256,9 +256,9 @@ </build> </profile> <profile> - <id>java25</id> + <id>java25To27</id> <activation> - <jdk>25</jdk> + <jdk>(24,28)</jdk> </activation> <build> <plugins> diff --git a/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/ProxyUtils.java b/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/ProxyUtils.java index 258d9a33a..f8be7b4d5 100644 --- a/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/ProxyUtils.java +++ b/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/ProxyUtils.java @@ -24,116 +24,34 @@ import org.objectweb.asm.Opcodes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ProxyUtils -{ - private static Logger LOGGER = LoggerFactory.getLogger(ProxyUtils.class); - public static final int JAVA_CLASS_VERSION = new BigDecimal(System.getProperty("java.class.version")).intValue(); - private static int weavingJavaVersion = -1; // initialise an invalid number +/** + * Utility class for proxy generation. + */ +public class ProxyUtils { + private static final Logger LOGGER = LoggerFactory.getLogger(ProxyUtils.class); + /** + * The Java class version of the current JVM. + */ + public static final int JAVA_CLASS_VERSION = new BigDecimal(System.getProperty("java.class.version")).intValue(); + private static int weavingJavaVersion = -1; // initialise an invalid number + + /** + * Get the class file version to be used for weaving. + * + * @return the class file version, e.g. 69 for Java 25 + */ + public static int getWeavingJavaVersion() { + if (weavingJavaVersion == -1) { + weavingJavaVersion = verifyJavaClassVersion(JAVA_CLASS_VERSION); + } + return weavingJavaVersion; + } - /** - * Get the java version to be woven at. - * @return - */ - public static int getWeavingJavaVersion() { - if (weavingJavaVersion == -1 ) { - //In order to avoid an inconsistent stack error the version of the woven byte code needs to match - //the level of byte codes in the original class - switch(JAVA_CLASS_VERSION) { - case Opcodes.V25: - LOGGER.debug("Weaving to Java 25"); - weavingJavaVersion = Opcodes.V25; - break; - case Opcodes.V24: - LOGGER.debug("Weaving to Java 24"); - weavingJavaVersion = Opcodes.V24; - break; - case Opcodes.V23: - LOGGER.debug("Weaving to Java 23"); - weavingJavaVersion = Opcodes.V23; - break; - case Opcodes.V22: - LOGGER.debug("Weaving to Java 22"); - weavingJavaVersion = Opcodes.V22; - break; - case Opcodes.V21: - LOGGER.debug("Weaving to Java 21"); - weavingJavaVersion = Opcodes.V21; - break; - case Opcodes.V20: - LOGGER.debug("Weaving to Java 20"); - weavingJavaVersion = Opcodes.V20; - break; - case Opcodes.V19: - LOGGER.debug("Weaving to Java 19"); - weavingJavaVersion = Opcodes.V19; - break; - case Opcodes.V18: - LOGGER.debug("Weaving to Java 18"); - weavingJavaVersion = Opcodes.V18; - break; - case Opcodes.V17: - LOGGER.debug("Weaving to Java 17"); - weavingJavaVersion = Opcodes.V17; - break; - case Opcodes.V16: - LOGGER.debug("Weaving to Java 16"); - weavingJavaVersion = Opcodes.V16; - break; - case Opcodes.V15: - LOGGER.debug("Weaving to Java 15"); - weavingJavaVersion = Opcodes.V15; - break; - case Opcodes.V14: - LOGGER.debug("Weaving to Java 14"); - weavingJavaVersion = Opcodes.V14; - break; - case Opcodes.V13: - LOGGER.debug("Weaving to Java 13"); - weavingJavaVersion = Opcodes.V13; - break; - case Opcodes.V12: - LOGGER.debug("Weaving to Java 12"); - weavingJavaVersion = Opcodes.V12; - break; - case Opcodes.V11: - LOGGER.debug("Weaving to Java 11"); - weavingJavaVersion = Opcodes.V11; - break; - case Opcodes.V10: - LOGGER.debug("Weaving to Java 10"); - weavingJavaVersion = Opcodes.V10; - break; - case Opcodes.V9: - LOGGER.debug("Weaving to Java 9"); - weavingJavaVersion = Opcodes.V9; - break; - case Opcodes.V1_8: - LOGGER.debug("Weaving to Java 8"); - weavingJavaVersion = Opcodes.V1_8; - break; - case Opcodes.V1_7: - LOGGER.debug("Weaving to Java 7"); - weavingJavaVersion = Opcodes.V1_7; - break; - case Opcodes.V1_6: - LOGGER.debug("Weaving to Java 6"); - weavingJavaVersion = Opcodes.V1_6; - break; - case Opcodes.V1_5: - LOGGER.debug("Weaving to Java 5"); - weavingJavaVersion = Opcodes.V1_5; - break; - default: - if (JAVA_CLASS_VERSION > Opcodes.V25) { - // newer JVMs load older class files, so generate proxies at the highest level we know - LOGGER.debug("Weaving to Java 25 on newer Java class version {}", JAVA_CLASS_VERSION); - weavingJavaVersion = Opcodes.V25; - break; - } - //aries should work with Java 5 or above - throw new IllegalArgumentException("Invalid Java version " + JAVA_CLASS_VERSION); - } - } - return weavingJavaVersion; - } + static int verifyJavaClassVersion(int javaClassVersion) { + if (javaClassVersion < Opcodes.V1_8 || javaClassVersion == Opcodes.V1_1) { + throw new IllegalArgumentException("Unsupported Java class version: " + javaClassVersion); + } + LOGGER.debug("Weaving to Java {}", javaClassVersion - Opcodes.V1_8 + 8); + return javaClassVersion; + } } diff --git a/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java b/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java index 5b680da97..4bc4c5af4 100644 --- a/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java +++ b/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java @@ -196,9 +196,6 @@ public abstract class AbstractWovenProxyAdapter extends ClassVisitor implements protected boolean currentMethodDeclaringTypeIsInterface; - - public static final boolean IS_AT_LEAST_JAVA_6 = JAVA_CLASS_VERSION >= Opcodes.V1_6; - /** * Create a new adapter for the supplied class * diff --git a/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyGenerator.java b/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyGenerator.java index d23e2d772..899c06d6e 100644 --- a/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyGenerator.java +++ b/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyGenerator.java @@ -22,7 +22,6 @@ import static org.objectweb.asm.Opcodes.ACC_ANNOTATION; import static org.objectweb.asm.Opcodes.ACC_ENUM; import static org.objectweb.asm.Opcodes.ACC_INTERFACE; -import org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter; import org.apache.aries.proxy.impl.common.OSGiFriendlyClassVisitor; import org.apache.aries.proxy.impl.common.OSGiFriendlyClassWriter; import org.objectweb.asm.ClassReader; @@ -34,24 +33,20 @@ import org.objectweb.asm.ClassWriter; */ public final class WovenProxyGenerator { - public static final byte[] getWovenProxy(byte[] original, ClassLoader loader){ + public static byte[] getWovenProxy(byte[] original, ClassLoader loader){ ClassReader cReader = new ClassReader(original); //Don't weave interfaces, enums or annotations if((cReader.getAccess() & (ACC_INTERFACE | ACC_ANNOTATION | ACC_ENUM)) != 0) return null; - //If we are Java 1.6 + compiled then we need to compute stack frames, otherwise - //maxs are fine (and faster) - int computeVal = AbstractWovenProxyAdapter.IS_AT_LEAST_JAVA_6 ? - ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS; + int computeVal = ClassWriter.COMPUTE_FRAMES; ClassWriter cWriter = new OSGiFriendlyClassWriter(cReader, computeVal, loader); ClassVisitor cv = new OSGiFriendlyClassVisitor(cWriter, computeVal ); //Wrap our outer layer to add the original SerialVersionUID if it was previously being defaulted ClassVisitor weavingAdapter = new SyntheticSerialVerUIDAdder( new WovenProxyAdapter(cv, cReader.getClassName(), loader)); - // If we are Java 1.6 + then we need to skip frames as they will be recomputed - cReader.accept(weavingAdapter, AbstractWovenProxyAdapter.IS_AT_LEAST_JAVA_6 ? ClassReader.SKIP_FRAMES : 0); + cReader.accept(weavingAdapter, ClassReader.SKIP_FRAMES); return cWriter.toByteArray(); } diff --git a/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/impl/ProxyUtilsTest.java b/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/impl/ProxyUtilsTest.java new file mode 100644 index 000000000..dcce62834 --- /dev/null +++ b/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/impl/ProxyUtilsTest.java @@ -0,0 +1,63 @@ +/* + * 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.aries.proxy.impl; + +import org.objectweb.asm.Opcodes; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +public class ProxyUtilsTest { + @Test + public void testVerifyJavaClassVersion8AndAbove() { + assertEquals(Opcodes.V1_8, ProxyUtils.verifyJavaClassVersion(52)); + assertEquals(Opcodes.V9, ProxyUtils.verifyJavaClassVersion(53)); + assertEquals(Opcodes.V10, ProxyUtils.verifyJavaClassVersion(54)); + assertEquals(Opcodes.V11, ProxyUtils.verifyJavaClassVersion(55)); + assertEquals(Opcodes.V12, ProxyUtils.verifyJavaClassVersion(56)); + assertEquals(Opcodes.V13, ProxyUtils.verifyJavaClassVersion(57)); + assertEquals(Opcodes.V14, ProxyUtils.verifyJavaClassVersion(58)); + assertEquals(Opcodes.V15, ProxyUtils.verifyJavaClassVersion(59)); + assertEquals(Opcodes.V16, ProxyUtils.verifyJavaClassVersion(60)); + assertEquals(Opcodes.V17, ProxyUtils.verifyJavaClassVersion(61)); + assertEquals(Opcodes.V18, ProxyUtils.verifyJavaClassVersion(62)); + assertEquals(Opcodes.V19, ProxyUtils.verifyJavaClassVersion(63)); + assertEquals(Opcodes.V20, ProxyUtils.verifyJavaClassVersion(64)); + assertEquals(Opcodes.V21, ProxyUtils.verifyJavaClassVersion(65)); + assertEquals(Opcodes.V22, ProxyUtils.verifyJavaClassVersion(66)); + assertEquals(Opcodes.V23, ProxyUtils.verifyJavaClassVersion(67)); + assertEquals(Opcodes.V24, ProxyUtils.verifyJavaClassVersion(68)); + assertEquals(Opcodes.V25, ProxyUtils.verifyJavaClassVersion(69)); + assertEquals(Opcodes.V26, ProxyUtils.verifyJavaClassVersion(70)); + assertEquals(Opcodes.V27, ProxyUtils.verifyJavaClassVersion(71)); + assertEquals(72, ProxyUtils.verifyJavaClassVersion(72)); // supporting future versions of Java we don't know about yet + } + + @Test + public void testVerifyJavaClassVersionBelow8() { + int V1_0 = 45; // there is no Opcodes.V1_0 constant in ASM + for (int i = V1_0; i < Opcodes.V1_8; i++) { + int javaClassVersion = i; + assertThrows(IllegalArgumentException.class, () -> ProxyUtils.verifyJavaClassVersion(javaClassVersion)); + } + // special case for V1_1 which is 196653 + assertThrows(IllegalArgumentException.class, () -> ProxyUtils.verifyJavaClassVersion(Opcodes.V1_1)); + } +} diff --git a/proxy/proxy-itests/pom.xml b/proxy/proxy-itests/pom.xml index c70e9fe7c..d67674ff8 100644 --- a/proxy/proxy-itests/pom.xml +++ b/proxy/proxy-itests/pom.xml @@ -194,7 +194,7 @@ <profile> <id>java9To25</id> <activation> - <jdk>(8,26)</jdk> + <jdk>(8,28)</jdk> </activation> <build> <plugins>
