From ec6d2cf85fa023d4fb0411c05b781f5bc3aaa1e6 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Tue, 13 Sep 2022 17:28:18 +0100 Subject: [PATCH] Transform DB2 driver to Jakarta APIs --- extensions/jdbc/jdbc-db2/deployment/pom.xml | 5 ++ .../db2/deployment/JakartaEnablement.java | 82 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 extensions/jdbc/jdbc-db2/deployment/src/main/java/io/quarkus/jdbc/db2/deployment/JakartaEnablement.java diff --git a/extensions/jdbc/jdbc-db2/deployment/pom.xml b/extensions/jdbc/jdbc-db2/deployment/pom.xml index a412fa6bb6395..a803ad71c492f 100644 --- a/extensions/jdbc/jdbc-db2/deployment/pom.xml +++ b/extensions/jdbc/jdbc-db2/deployment/pom.xml @@ -48,6 +48,11 @@ assertj-core test + + org.eclipse.transformer + org.eclipse.transformer + 0.5.0 + diff --git a/extensions/jdbc/jdbc-db2/deployment/src/main/java/io/quarkus/jdbc/db2/deployment/JakartaEnablement.java b/extensions/jdbc/jdbc-db2/deployment/src/main/java/io/quarkus/jdbc/db2/deployment/JakartaEnablement.java new file mode 100644 index 0000000000000..c74ed6b81b965 --- /dev/null +++ b/extensions/jdbc/jdbc-db2/deployment/src/main/java/io/quarkus/jdbc/db2/deployment/JakartaEnablement.java @@ -0,0 +1,82 @@ +package io.quarkus.jdbc.db2.deployment; + +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.transformer.action.ActionContext; +import org.eclipse.transformer.action.ByteData; +import org.eclipse.transformer.action.impl.ActionContextImpl; +import org.eclipse.transformer.action.impl.ByteDataImpl; +import org.eclipse.transformer.action.impl.ClassActionImpl; +import org.eclipse.transformer.action.impl.SelectionRuleImpl; +import org.eclipse.transformer.action.impl.SignatureRuleImpl; +import org.eclipse.transformer.util.FileUtils; +import org.objectweb.asm.ClassReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.quarkus.bootstrap.classloading.QuarkusClassLoader; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.BytecodeTransformerBuildItem; + +/** + * The DB2 driver is compiled using references to classes in the javax.transaction + * package; we need to transform these to fix compatibility with jakarta.transaction. + * We do this by leveraging the Eclipse Transformer project during Augmentation, so + * that end users don't need to bother. + */ +public class JakartaEnablement { + + private static final List CLASSES_NEEDING_TRANSFORMATION = List.of( + "com.ibm.db2.jcc.t2zos.ab", + "com.ibm.db2.jcc.t2zos.T2zosConnection", + "com.ibm.db2.jcc.t2zos.T2zosConfiguration"); + + @BuildStep + void transformToJakarta(BuildProducer transformers) { + if (QuarkusClassLoader.isClassPresentAtRuntime("jakarta.transaction.Transaction")) { + JakartaTransformer tr = new JakartaTransformer(); + for (String classname : CLASSES_NEEDING_TRANSFORMATION) { + final BytecodeTransformerBuildItem item = new BytecodeTransformerBuildItem.Builder() + .setCacheable(true) + .setContinueOnFailure(false) + .setClassToTransform(classname) + .setClassReaderOptions(ClassReader.SKIP_DEBUG) + .setInputTransformer(tr::transform) + .build(); + transformers.produce(item); + } + } + } + + private static class JakartaTransformer { + + private final Logger logger; + private final ActionContext ctx; + + JakartaTransformer() { + logger = LoggerFactory.getLogger("JakartaTransformer"); + Map renames = new HashMap<>(); + //N.B. we enable only this transformation, not the full set of capabilities of Eclipse Transformer; + //this might need tailoring if the same idea gets applied to a different context. + renames.put("javax.transaction", "jakarta.transaction"); + ctx = new ActionContextImpl(logger, + new SelectionRuleImpl(logger, Collections.emptyMap(), Collections.emptyMap()), + new SignatureRuleImpl(logger, renames, null, null, null, null, null, Collections.emptyMap())); + } + + byte[] transform(final String name, final byte[] bytes) { + logger.info("Jakarta EE compatibility enhancer for Quarkus: transforming " + name); + final ClassActionImpl classTransformer = new ClassActionImpl(ctx); + final ByteBuffer input = ByteBuffer.wrap(bytes); + final ByteData inputData = new ByteDataImpl(name, input, FileUtils.DEFAULT_CHARSET); + final ByteData outputData = classTransformer.apply(inputData); + return outputData.buffer().array(); + } + } + +}