-----------------------------------------------
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);
}