This is an automated email from the ASF dual-hosted git repository. github-bot pushed a commit to branch camel-main in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 23537cea0f669978ac5c19adc813b69d571e78fc Author: Jiri Ondrusek <ondrusek.j...@gmail.com> AuthorDate: Tue Jan 7 08:54:18 2025 +0100 Fixes #6889 - jt400 - disables GUI interaction for the native mode --- .../component/jt400/deployment/Jt400Processor.java | 67 ++++++++++++++++++++-- .../component/jt400/graal/JT400Substitutions.java | 6 -- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/extensions/jt400/deployment/src/main/java/org/apache/camel/quarkus/component/jt400/deployment/Jt400Processor.java b/extensions/jt400/deployment/src/main/java/org/apache/camel/quarkus/component/jt400/deployment/Jt400Processor.java index a666373483..efce11cfc3 100644 --- a/extensions/jt400/deployment/src/main/java/org/apache/camel/quarkus/component/jt400/deployment/Jt400Processor.java +++ b/extensions/jt400/deployment/src/main/java/org/apache/camel/quarkus/component/jt400/deployment/Jt400Processor.java @@ -26,17 +26,18 @@ import com.ibm.as400.access.ConvTable; import com.ibm.as400.access.NLSImplNative; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.builditem.CombinedIndexBuildItem; -import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.deployment.builditem.IndexDependencyBuildItem; -import io.quarkus.deployment.builditem.NativeImageEnableAllCharsetsBuildItem; +import io.quarkus.deployment.builditem.*; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem; +import io.quarkus.gizmo.Gizmo; import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; import org.jboss.logging.Logger; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; class Jt400Processor { @@ -105,4 +106,62 @@ class Jt400Processor { return new IndexDependencyBuildItem("net.sf.jt400", "jt400", "java11"); } + @BuildStep + BytecodeTransformerBuildItem patchToolboxSignonHandler() { + return new BytecodeTransformerBuildItem.Builder() + .setClassToTransform("com.ibm.as400.access.ToolboxSignonHandler") + .setCacheable(true) + .setVisitorFunction((className, classVisitor) -> new ToolboxSignonHandlerClassVisitor(classVisitor)).build(); + } + + /** + * ToolboxSignonHandler starts GUI dialogues from several methods. This is not supported in the native. + * Unfortunately the method AS400.isGuiAvailable does not disable every call to dialogue. + * Two methods `handleSignon` and `handlePasswordChange` has to be removed (they does not contain any logic, + * just the GUI interaction) + * + * ToolboxSignonHandler is a final class, therefore no substitutions can be added to this class + * and bytecode manipulation had to be used instead. + */ + static class ToolboxSignonHandlerClassVisitor extends ClassVisitor { + + private final Logger logger; + + protected ToolboxSignonHandlerClassVisitor(ClassVisitor classVisitor) { + super(Gizmo.ASM_API_VERSION, classVisitor); + + logger = Logger.getLogger("ToolboxSignonHandlerClassVisitor"); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, + String[] exceptions) { + MethodVisitor original = super.visitMethod(access, name, descriptor, signature, exceptions); + if ("handleSignon".equals(name) || "handlePasswordChange".equals(name)) { + logger.debug("GUI interaction enhancer for Quarkus: transforming " + name + " to avoid spawning dialogues"); + // Replace the method body + return new MethodVisitor(Gizmo.ASM_API_VERSION, original) { + @Override + public void visitCode() { + super.visitCode(); + // Load 'true' or `false` onto the stack and return + if ("handlePasswordChange".equals(name)) { + visitInsn(Opcodes.ICONST_0); // push false + } else { + visitInsn(Opcodes.ICONST_1); // push true + } + visitInsn(Opcodes.IRETURN); // return boolean from the method + } + + @Override + public void visitMaxs(int maxStack, int maxLocals) { + // Max stack is 1 (for the boolean), locals can remain unchanged + super.visitMaxs(1, 0); + } + }; + } + return original; + } + } + } diff --git a/extensions/jt400/runtime/src/main/java/org/apache/camel/quarkus/component/jt400/graal/JT400Substitutions.java b/extensions/jt400/runtime/src/main/java/org/apache/camel/quarkus/component/jt400/graal/JT400Substitutions.java index 221c070eea..96afbfd320 100644 --- a/extensions/jt400/runtime/src/main/java/org/apache/camel/quarkus/component/jt400/graal/JT400Substitutions.java +++ b/extensions/jt400/runtime/src/main/java/org/apache/camel/quarkus/component/jt400/graal/JT400Substitutions.java @@ -39,12 +39,6 @@ final class SubstituteAS400 { //skip verification, because it cen end with GUi dialog return false; } - - @Substitute - //workaround because of https://github.com/apache/camel-quarkus/issues/6889 - synchronized void signon(boolean keepConnection) throws AS400SecurityException, IOException { - throw new RuntimeException("Signon is not supported in the native mode."); - } } //even if gui is turned off, the presence of code in Dialogs, which references awt object, causes the java.lang.Thread