----------------------------------------------- Capturing the changes for Running with JDK17 ----------------------------------------------- After a discussion with Gemini, webswing 20.2.5-gs's root pom.xml needed the following added on top of all the previous changes for compiling with JDK17: --add-opens=java.desktop/sun.font=ALL-UNNAMED ---- Discussing with Gemini, GS3's build.xml needed the following debug-start-tomcat set CLASSPATH=${tomcat.classpath} export CLASSPATH=${tomcat.classpath} --- force-start-tomcat set CLASSPATH=${tomcat.classpath} export CLASSPATH=${tomcat.classpath} -------------------------------------------------------------------------------------------- ChatGPT (uni account, in deep thinking mode) summary of the finalised changes: -------------------------------------------------------------------------------------------- Excellent. That confirms the patch is now being included through the normal WebSwing build and deployment process: sun/awt/PlatformGraphicsInfo.class It was not merely left over from the manual copy. A Tomcat restart removed the temporary release, and WebSwing regenerated it with the patched class present. The successful /phind launch confirms the complete fix is working. Current working changes The effective Java 17 compatibility changes are: Treat Java 17 like Java 11 in SwingProcessServiceImpl: } else if (javaVersion.startsWith("11") || javaVersion.startsWith("17")) { Add sun.awt.PlatformGraphicsInfo to modpatch-java-desktop, so Java 17 creates the WebSwing toolkit and graphics environment specified by: -Dawt.toolkit=org.webswing.toolkit.WebToolkit11 -Djava.awt.graphicsenv=org.webswing.toolkit.ge.WebGraphicsEnvironment11 Change WebGraphicsConfig to extend GraphicsConfiguration and delegate to BufferedImageGraphicsConfig, because Java 17 declares BufferedImageGraphicsConfig as final. Add these Java 17 module exports: --add-exports=java.desktop/java.awt.peer=ALL-UNNAMED --add-exports=java.base/sun.nio.cs=ALL-UNNAMED --add-exports=java.base/sun.security.util=ALL-UNNAMED Next single step: remove only the temporary class-loading diagnostics Now that the application works, remove these two temporary diagnostic JVM options from /phind’s vmArgs: -Xlog:class+load=info -Xshare:off Keep all three --add-exports options and all existing --add-opens options. Do not remove the GS DIAGNOSTIC code from Util.getWebToolkit() yet. Start one new /phind session without restarting Tomcat and confirm that it still opens and works normally. If it works, tell me simply that it succeeded. Then the next cleanup step will be to restore Util.getWebToolkit() to its original concise implementation. ---- 1. Created file: webswing-modpatch/modpatch-java-desktop/src/main/java/sun/awt/PlatformGraphicsInfo.java With contents: package sun.awt; import java.awt.GraphicsEnvironment; import java.awt.Toolkit; public class PlatformGraphicsInfo { public static GraphicsEnvironment createGE() { return instantiate( System.getProperty("java.awt.graphicsenv"), GraphicsEnvironment.class); } public static Toolkit createToolkit() { return instantiate( System.getProperty("awt.toolkit"), Toolkit.class); } private static T instantiate(String className, Class expectedType) { if (className == null || className.isEmpty()) { throw new IllegalStateException( "Required system property is not set for " + expectedType.getName()); } try { Class implementationClass = Class.forName(className); Object instance = implementationClass.getDeclaredConstructor().newInstance(); return expectedType.cast(instance); } catch (ReflectiveOperationException e) { throw new IllegalStateException( "Unable to instantiate " + className, e); } } public static boolean getDefaultHeadlessProperty() { String display = System.getenv("DISPLAY"); return display == null || display.trim().isEmpty(); } public static String getDefaultHeadlessMessage() { return "\nNo X11 DISPLAY variable was set,\n" + "or no headful library support was found,\n" + "but this program performed an operation which requires it."; } } The above is compiled through: mvn -pl webswing-modpatch/modpatch-java-desktop \ -am \ -DskipTests \ package ---- 2. Replaced contents of: webswing-app-toolkit/src/main/java/org/webswing/toolkit/ge/WebGraphicsConfig.java With contents: package org.webswing.toolkit.ge; import java.awt.AWTException; import java.awt.Component; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.Image; import java.awt.ImageCapabilities; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.VolatileImage; import java.awt.image.WritableRaster; import org.webswing.toolkit.util.Services; import org.webswing.toolkit.util.Util; import sun.awt.image.BufferedImageGraphicsConfig; import sun.awt.image.OffScreenImage; @SuppressWarnings("restriction") public class WebGraphicsConfig extends GraphicsConfiguration { private final BufferedImageGraphicsConfig delegate; WebScreenDevice device; private int width; private int height; public static WebGraphicsConfig getWebGraphicsConfig(int width, int height) { return new WebGraphicsConfig(width, height); } private WebGraphicsConfig(int width, int height) { BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); this.delegate = BufferedImageGraphicsConfig.getConfig(image); this.width = width; this.height = height; } @Override public GraphicsDevice getDevice() { if (device == null) { device = new WebScreenDevice(delegate.getDevice(), this); } return device; } @Override public ColorModel getColorModel() { return delegate.getColorModel(); } @Override public ColorModel getColorModel(int transparency) { return delegate.getColorModel(transparency); } @Override public AffineTransform getDefaultTransform() { return delegate.getDefaultTransform(); } @Override public AffineTransform getNormalizingTransform() { return delegate.getNormalizingTransform(); } @Override public Rectangle getBounds() { return new Rectangle(0, 0, width, height); } public Image createAcceleratedImage( Component target, int imageWidth, int imageHeight) { ColorModel colorModel = getColorModel(2); WritableRaster raster = colorModel.createCompatibleWritableRaster( imageWidth, imageHeight); return new OffScreenImage( target, colorModel, raster, colorModel.isAlphaPremultiplied()); } @Override public VolatileImage createCompatibleVolatileImage( int width, int height, ImageCapabilities caps, int transparency) throws AWTException { if (Util.isDD()) { return Services.getDirectDrawService() .createVolatileImage( width, height, caps, transparency); } return super.createCompatibleVolatileImage( width, height, caps, transparency); } @Override public boolean isTranslucencyCapable() { return true; } } ---- The webswing.config.in file for the 3 webswing applications (or whichever is being tested, I tested /phind originally) had logging information and more with the additional options "-Xlog:class+load=info -Xshare:off ": "vmArgs" : "--add-opens=java.desktop/sun.awt.image=ALL-UNNAMED --add-opens=java.desktop/sun.java2d=ALL-UNNAMED --add-opens=java.desktop/sun.awt=ALL-UNNAMED --add-opens=java.desktop/sun.awt.windows=ALL-UNNAMED --add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED --add-opens=java.desktop/sun.swing=ALL-UNNAMED --add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED --add-opens=java.desktop/sun.font=ALL-UNNAMED -Xlog:class+load=info -Xshare:off --add-exports=java.desktop/java.awt.peer=ALL-UNNAMED --add-exports=java.base/sun.nio.cs=ALL-UNNAMED --add-exports=java.base/sun.security.util=ALL-UNNAMED" 25 Sep 2026 To get file upload to work in the /gli webswing application when running against Java 17, the "/gli" application in webswing.config.in needed to have its "vmArgs" property expanded to contain: --add-exports=java.desktop/sun.awt.shell=ALL-UNNAMED ChatGPT suggested to documented this add-exports as: "Required for WebSwing isolated-filesystem file upload and shell-folder handling under Java 17." ---- UNUSED Diagnostics added to: webswing-20.2.5-gs/webswing-app-toolkit/src/main/java/org/webswing/toolkit/util/Util.java 1. Commented out original (and later restored to active) default public static WebToolkit getWebToolkit() { return ((WebToolkit) Toolkit.getDefaultToolkit()); } 2. Followed by inserting: /* public static WebToolkit getWebToolkit() { System.err.println("GS DIAGNOSTIC: awt.toolkit property = " + System.getProperty("awt.toolkit")); Toolkit toolkit = Toolkit.getDefaultToolkit(); System.err.println("GS DIAGNOSTIC: actual Toolkit class = " + toolkit.getClass().getName()); System.err.println("GS DIAGNOSTIC: loading WebToolkit"); try { Class clazz = Class.forName("org.webswing.toolkit.WebToolkit"); System.err.println("GS DIAGNOSTIC: WebToolkit loaded: " + clazz); Object instance = clazz.getDeclaredConstructor().newInstance(); System.err.println("GS DIAGNOSTIC: WebToolkit instantiated: " + instance); } catch (Throwable t) { System.err.println("GS DIAGNOSTIC: FAILED to load/instantiate WebToolkit"); t.printStackTrace(); } return ((WebToolkit) toolkit); }*/ public static WebToolkit getWebToolkit() { System.err.println("GS DIAGNOSTIC: awt.toolkit property = " + System.getProperty("awt.toolkit")); System.err.println("GS DIAGNOSTIC: java.awt.headless = " + System.getProperty("java.awt.headless")); System.err.println("GS DIAGNOSTIC: Toolkit class BEFORE getDefaultToolkit = " + Toolkit.class); /* System.err.println("GS DIAGNOSTIC: WebToolkit11 class = " + Class.forName("org.webswing.toolkit.WebToolkit11")); try { System.err.println("GS DIAGNOSTIC: WebToolkit17 class = " + Class.forName("org.webswing.toolkit.WebToolkit17")); } catch (Throwable t) { System.err.println("GS DIAGNOSTIC: WebToolkit17 NOT available"); t.printStackTrace(); }*/ Toolkit toolkit = Toolkit.getDefaultToolkit(); System.err.println("GS DIAGNOSTIC: actual Toolkit class = " + toolkit.getClass().getName()); System.err.println("GS DIAGNOSTIC: actual Toolkit = " + toolkit); return ((WebToolkit) toolkit); }