Skip to content

Commit

Permalink
ASM Separation (#1477)
Browse files Browse the repository at this point in the history
Refactor EL to allow usage booth ASM implementations (standard provided by org.ow2.asm and internal org.eclipse.persistence.asm).

Main reason behind this enhancement is quickly adopt new Java version as Java release cycle is quicker now.
Usage of ASM implementation should controlled by new system property `eclipselink.asm.service` . There are following values possible

    eclipselink - use ASM implementation from org.eclipse.persistence.asm project (DEFAULT)
    ow2 - use ASM implementation from org.ow2.asm project

    If there is no value EclipseLink ASM implementation is used and as a fallback OW2.
    Various EclipseLink tests should be executed with this system property e.g.

mvn verify -pl :org.eclipse.persistence.jpa.jse.test -P mysql -Declipselink.asm.service=ow2
mvn verify -pl :org.eclipse.persistence.jpa.jse.test -P mysql -Declipselink.asm.service=eclipselink

mvn test -pl :org.eclipse.persistence.moxy -P test-moxy-lrg -Declipselink.asm.service=ow2
mvn test -pl :org.eclipse.persistence.moxy -P test-moxy-lrg -Declipselink.asm.service=eclipselink

mvn clean verify -pl :org.eclipse.persistence.jpa.test -P test-jpa-lrg,mysql -Declipselink.asm.service=ow2
mvn clean verify -pl :org.eclipse.persistence.jpa.test -P test-jpa-lrg,mysql -Declipselink.asm.service=eclipselink

mvn verify -pl :org.eclipse.persistence.jpa.testapps -amd -P mysql -Declipselink.asm.service=ow2
mvn verify -pl :org.eclipse.persistence.jpa.testapps -amd -P mysql -Declipselink.asm.service=eclipselink

Code in this enhancement should be divided into following parts:

    Adapter/wrapper classes in org.eclipse.persistence.core module in org.eclipse.persistence.asm package. There are classes which translate calls from EclipseLink into ASM implementation.
    Code where is ASM used is pointed to org.eclipse.persistence.asm Java package.
    Required code changes in the rest of EclipseLink code base to use adapter/wrapper classes from the previous point. Major part of these changes is
    org.eclipse.persistence.internal.libraries.asm.Opcodes.ACC_PUBLIC -> org.eclipse.persistence.asm.Opcodes.valueInt("ACC_PUBLIC")
    or
    org.eclipse.persistence.internal.libraries.asm.Label l0 = new org.eclipse.persistence.internal.libraries.asm.Label(); -> org.eclipse.persistence.asm.Label l0 = org.eclipse.persistence.asm.ASMFactory.createLabel();
    Dependency changes in pom.xml. ASM implementation artifacts are used as a compilation dependency in org.eclipse.persistence.core module and in the others usually as a dependency in test scope.
    JPMS change as package org.eclipse.persistence.internal.libraries.asm and module org.eclipse.persistence.asm is not used directly in project submodules.
    OSGi part is open now. There are test changes only in OSGiBundleTest.java.

This change handle all scenarios how ASM is used in EclipseLink (sorted from most simple):

    Simple ASM method call or constant access without and in/out values conversion like
    org.eclipse.persistence.internal.libraries.asm.Opcodes.ACC_PUBLIC -> org.eclipse.persistence.asm.Opcodes.valueInt("ACC_PUBLIC")
    Method call with in/out value conversion like
    MethodVisitor mv = cw.visitMethod(....
    Most complex are classes from EclipseLink which instances are passed into ASM implementation and some methods are overriden there and some not. These classes inherits from ASM classes like ClassVisitor, ClassReader, ClassWriter.
    See org.eclipse.persistence.internal.jpa.weaving.ClassWeaver, org.eclipse.persistence.internal.jpa.weaving.ComputeClassWriter, org.eclipse.persistence.internal.jpa.weaving.MethodWeaver ...

Signed-off-by: Radek Felcman <radek.felcman@oracle.com>
  • Loading branch information
rfelcman committed Jan 9, 2023
1 parent a9dd680 commit b3924ac
Show file tree
Hide file tree
Showing 95 changed files with 6,180 additions and 1,187 deletions.
28 changes: 25 additions & 3 deletions bundles/eclipselink/pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -143,14 +143,36 @@
<artifactId>jakarta.json-api</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-tree</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-util</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.glassfish.corba</groupId>
<artifactId>glassfish-corba-omgapi</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -44,9 +44,15 @@ public class OSGiBundleTest {
// ASM bundle symbolic name
private static final String ASM_BUNDLE_NAME = "org.eclipse.persistence.asm";

// CORE bundle symbolic name
private static final String CORE_BUNDLE_NAME = "org.eclipse.persistence.core";

// MOXy bundle symbolic name
private static final String MOXY_BUNDLE_NAME = "org.eclipse.persistence.moxy";

// CORE bundle
private Bundle coreBundle;

// MOXy bundle
private Bundle moxyBundle;

Expand All @@ -59,120 +65,146 @@ public static Option[] config() {
}

@Test
public void testAsmVersion() {
Class<?> c = loadClass("org.eclipse.persistence.internal.libraries.asm.AnnotationVisitor");
public void testAsmELVersion() {
Class<?> c = loadClass(CORE_BUNDLE_NAME, "org.eclipse.persistence.internal.libraries.asm.AnnotationVisitor");
assertClassLoadedByBundle(c, ASM_BUNDLE_NAME);
}

@Test
public void testAsmCoreVersion() {
Class<?> c = loadClass(CORE_BUNDLE_NAME, "org.eclipse.persistence.asm.AnnotationVisitor");
assertClassLoadedByBundle(c, CORE_BUNDLE_NAME);
}

@Test
public void testInternalJaxb() {
Class<?> c = loadClass("org.eclipse.persistence.internal.jaxb.AttributeNodeImpl");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.internal.jaxb.AttributeNodeImpl");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testInternalJaxbMany() {
Class<?> c = loadClass("org.eclipse.persistence.internal.jaxb.many.ArrayValue");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.internal.jaxb.many.ArrayValue");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxb() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.JAXBContext");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.JAXBContext");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbAttachment() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.attachment.AttachmentMarshallerAdapter");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.attachment.AttachmentMarshallerAdapter");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbCompiler() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbDynamic() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbDynamicMetadata() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.dynamic.metadata.Metadata");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.dynamic.metadata.Metadata");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbJavamodel() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.javamodel.AnnotationProxy");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.javamodel.AnnotationProxy");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbJavamodelOxm() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.javamodel.oxm.OXMJavaClassImpl");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.javamodel.oxm.OXMJavaClassImpl");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbJavamodelReflection() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.javamodel.reflection.AnnotationHelper");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.javamodel.reflection.AnnotationHelper");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbMetadata() throws ClassNotFoundException {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.metadata.MetadataSource");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.metadata.MetadataSource");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbRs() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.rs.MOXyJsonProvider");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.rs.MOXyJsonProvider");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJaxbXmlmodel() {
Class<?> c = loadClass("org.eclipse.persistence.jaxb.xmlmodel.JavaAttribute");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.eclipse.persistence.jaxb.xmlmodel.JavaAttribute");
assertClassLoadedByBundle(c, MOXY_BUNDLE_NAME);
}

@Test
public void testJavaxXmlParsers() {
Class<?> c = loadClass("javax.xml.parsers.ParserConfigurationException");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "javax.xml.parsers.ParserConfigurationException");
assertClassLoadedBySystemBundle(c);
}

@Test
public void testJavaxNaming() {
Class<?> c = loadClass("javax.naming.InitialContext");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "javax.naming.InitialContext");
assertClassLoadedBySystemBundle(c);
}

@Test
public void testOrgXmlSaxHelpers() {
Class<?> c = loadClass("org.xml.sax.helpers.DefaultHandler");
Class<?> c = loadClass(MOXY_BUNDLE_NAME, "org.xml.sax.helpers.DefaultHandler");
assertClassLoadedBySystemBundle(c);
}

/**
* Loads a class from MOXy bundle. Fails the test if not loaded.
*/
private Class<?> loadClass(String className) {
private Class<?> loadClass(String bundleName, String className) {
try {
return getMoxyBundle().loadClass(className);
if (MOXY_BUNDLE_NAME.equals(bundleName)) {
return getMoxyBundle().loadClass(className);
} else if (CORE_BUNDLE_NAME.equals(bundleName)) {
return getCoreBundle().loadClass(className);
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(OSGiBundleTest.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
Assert.fail("Cannot find and load class: " + className);
}
return null;
}

/**
* Returns CORE bundle ('org.eclipse.persistence.core').
*/
private Bundle getCoreBundle() {
if (this.coreBundle != null) {
return this.coreBundle;
}
for (Bundle b : ctx.getBundles()) {
if (b.getSymbolicName().equals(CORE_BUNDLE_NAME)) {
this.coreBundle = b;
return b;
}
}
return null;
}

/**
* Returns MOXy bundle ('org.eclipse.persistence.moxy').
*/
Expand All @@ -186,7 +218,6 @@ private Bundle getMoxyBundle() {
return b;
}
}

return null;
}

Expand Down
8 changes: 7 additions & 1 deletion dbws/org.eclipse.persistence.dbws/pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -87,6 +87,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!--EclipseLink ASM Implementation-->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.asm</artifactId>
<scope>test</scope>
</dependency>
<!--JDBC driver (test dependency)-->
<dependency>
<groupId>${db.driver.groupId}</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -24,7 +24,6 @@

requires jakarta.servlet;

requires org.eclipse.persistence.asm;
requires org.eclipse.persistence.jpa;
requires org.eclipse.persistence.jpa.jpql;
requires transitive org.eclipse.persistence.moxy;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -20,13 +20,10 @@
// Java extension imports

// EclipseLink imports
import org.eclipse.persistence.internal.libraries.asm.EclipseLinkASMClassWriter;
import org.eclipse.persistence.internal.libraries.asm.MethodVisitor;
import static org.eclipse.persistence.internal.libraries.asm.Opcodes.ACC_PUBLIC;
import static org.eclipse.persistence.internal.libraries.asm.Opcodes.ACC_SUPER;
import static org.eclipse.persistence.internal.libraries.asm.Opcodes.ALOAD;
import static org.eclipse.persistence.internal.libraries.asm.Opcodes.INVOKESPECIAL;
import static org.eclipse.persistence.internal.libraries.asm.Opcodes.RETURN;
import org.eclipse.persistence.asm.ClassWriter;
import org.eclipse.persistence.asm.EclipseLinkASMClassWriter;
import org.eclipse.persistence.asm.MethodVisitor;
import org.eclipse.persistence.asm.Opcodes;

/**
* <p><b>INTERNAL</b>: A subclass of {@link ClassLoader} that exposes a build method to the hidden
Expand Down Expand Up @@ -60,13 +57,13 @@ protected byte[] generateClassBytes(String className) {
* }
* }
*/
EclipseLinkASMClassWriter cw = new EclipseLinkASMClassWriter();
cw.visit(ACC_PUBLIC + ACC_SUPER, className, null, SOAP_RESPONSE_CLASSNAME_SLASHES, null);
ClassWriter cw = new EclipseLinkASMClassWriter();
cw.visit(Opcodes.valueInt("ACC_PUBLIC") + Opcodes.valueInt("ACC_SUPER"), className, null, SOAP_RESPONSE_CLASSNAME_SLASHES, null);

MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, SOAP_RESPONSE_CLASSNAME_SLASHES, "<init>", "()V", false);
mv.visitInsn(RETURN);
MethodVisitor mv = cw.visitMethod(Opcodes.valueInt("ACC_PUBLIC"), "<init>", "()V", null, null);
mv.visitVarInsn(Opcodes.valueInt("ALOAD"), 0);
mv.visitMethodInsn(Opcodes.valueInt("INVOKESPECIAL"), SOAP_RESPONSE_CLASSNAME_SLASHES, "<init>", "()V", false);
mv.visitInsn(Opcodes.valueInt("RETURN"));
mv.visitMaxs(0, 0);
mv.visitEnd();

Expand Down

0 comments on commit b3924ac

Please sign in to comment.