Skip to content

Commit

Permalink
Transform DB2 driver to Jakarta APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
Sanne committed Sep 14, 2022
1 parent 6e10b21 commit ec6d2cf
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
5 changes: 5 additions & 0 deletions extensions/jdbc/jdbc-db2/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.transformer</groupId>
<artifactId>org.eclipse.transformer</artifactId>
<version>0.5.0</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String> 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<BytecodeTransformerBuildItem> 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<String, String> 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();
}
}

}

0 comments on commit ec6d2cf

Please sign in to comment.