Aside from the difficulty of finding (i.e., seeing) the cursor because of it’s very small size, the X11 interface does appear to be easier and better to use for running vassal modules.
I’ve tried a number of times and ways (and hours) trying to increase the size of the cursor, with or without a mouse attached, and have given up. Evidently it is way beyond any ability that I have to figure out how to do it, and I’ll have to wait for someone with the expertise in termux to figure out if (or how) it can be done, and hopefully write an executable script for it (or at least know how to present it in a step by step process that I can follow.)
Hi guys,
I have successfully installed termux, termux widget, MultiVNC and Vassal 3.7.16 on my Android tablet under Android 8.0.0.
The widget shows the shortcut that allowed me to launch Vassal. I got the window that shows Vassal without its main menu along with an error window.
I got the same behaviour with 3.7.15.
I put the error log file content here:
2025-08-20 00:21:48,101 [12600-main] INFO VASSAL.launch.StartUp - Starting
2025-08-20 00:21:48,283 [12600-main] INFO VASSAL.launch.StartUp - OS Linux 3.4.113-g373a0b03332-dirty arm
2025-08-20 00:21:48,284 [12600-main] INFO VASSAL.launch.StartUp - Java version 21.0.8
2025-08-20 00:21:48,285 [12600-main] INFO VASSAL.launch.StartUp - Java home /data/data/com.termux/files/usr/lib/jvm/java-21-openjdk
2025-08-20 00:21:48,287 [12600-main] INFO VASSAL.launch.StartUp - VASSAL version 3.7.16
2025-08-20 00:21:49,081 [12600-AWT-EventQueue-0] INFO VASSAL.launch.ModuleManager - Manager
2025-08-20 00:21:54,381 [12600-AWT-EventQueue-0] ERROR VASSAL.tools.ErrorDialog -
java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
at java.desktop/sun.awt.image.SunVolatileImage.<init>(SunVolatileImage.java:75)
at java.desktop/sun.awt.image.SunVolatileImage.<init>(SunVolatileImage.java:122)
at java.desktop/java.awt.GraphicsConfiguration.createCompatibleVolatileImage(GraphicsConfiguration.java:305)
at java.desktop/java.awt.GraphicsConfiguration.createCompatibleVolatileImage(GraphicsConfiguration.java:206)
at java.desktop/sun.swing.CachedPainter.createImage(CachedPainter.java:269)
at java.desktop/sun.swing.CachedPainter.getImage(CachedPainter.java:160)
at java.desktop/sun.swing.CachedPainter$PainterMultiResolutionCachedImage.getResolutionVariant(CachedPainter.java:320)
at java.desktop/sun.java2d.SunGraphics2D.getResolutionVariant(SunGraphics2D.java:3311)
at java.desktop/sun.java2d.SunGraphics2D.drawHiDPIImage(SunGraphics2D.java:3139)
at java.desktop/sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:3482)
at java.desktop/sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:3459)
at java.desktop/javax.swing.plaf.metal.MetalUtils$GradientPainter.paintImage(MetalUtils.java:309)
at java.desktop/sun.swing.CachedPainter.paint0(CachedPainter.java:217)
at java.desktop/sun.swing.CachedPainter.paint(CachedPainter.java:114)
at java.desktop/javax.swing.plaf.metal.MetalUtils$GradientPainter.paint(MetalUtils.java:270)
at java.desktop/javax.swing.plaf.metal.MetalUtils.drawGradient(MetalUtils.java:223)
at java.desktop/javax.swing.plaf.metal.MetalMenuBarUI.update(MetalMenuBarUI.java:116)
at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:852)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:961)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1137)
at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:961)
at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5325)
at java.desktop/javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:255)
at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1336)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1114)
at java.desktop/java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at java.desktop/sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:75)
at java.desktop/sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:112)
at java.desktop/java.awt.Container.paint(Container.java:2005)
at java.desktop/java.awt.Window.paint(Window.java:3959)
at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:889)
at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:861)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:861)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:834)
at java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:784)
at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1897)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
2025-08-20 00:21:57,218 [12600-AWT-EventQueue-0] ERROR VASSAL.tools.BugDialog -
java.util.concurrent.ExecutionException: java.net.UnknownHostException: vassalengine.org
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:205)
at java.desktop/javax.swing.SwingWorker.get(SwingWorker.java:624)
at VASSAL.tools.BugDialog$CheckRequest.done(BugDialog.java:526)
at java.desktop/javax.swing.SwingWorker$4.run(SwingWorker.java:749)
at java.desktop/javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:847)
at java.desktop/sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
at java.desktop/javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:857)
at java.desktop/javax.swing.Timer.fireActionPerformed(Timer.java:311)
at java.desktop/javax.swing.Timer$DoPostEvent.run(Timer.java:243)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:117)
at java.desktop/java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:191)
at java.desktop/java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:236)
at java.desktop/java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:234)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:319)
at java.desktop/java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:234)
at java.desktop/java.awt.Dialog.show(Dialog.java:1079)
at java.desktop/java.awt.Component.show(Component.java:1728)
at java.desktop/java.awt.Component.setVisible(Component.java:1675)
at java.desktop/java.awt.Window.setVisible(Window.java:1036)
at java.desktop/java.awt.Dialog.setVisible(Dialog.java:1015)
at VASSAL.tools.BugDialog.setVisible(BugDialog.java:482)
at VASSAL.tools.ErrorDialog.lambda$bug$4(ErrorDialog.java:106)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.net.UnknownHostException: vassalengine.org
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:567)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:751)
at java.base/sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:304)
at java.base/sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:181)
at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:531)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:636)
at java.base/sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264)
at java.base/sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:377)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:193)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1253)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1139)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:179)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1691)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1615)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:223)
at java.base/java.net.URL.openStream(URL.java:1325)
at VASSAL.tools.version.LiveVersionInfo.getVersion(LiveVersionInfo.java:52)
at VASSAL.tools.version.LiveVersionInfo.getRelease(LiveVersionInfo.java:38)
at VASSAL.tools.version.VersionUtils.compareReportable(VersionUtils.java:38)
at VASSAL.tools.BugDialog$CheckRequest.compareReportable(BugDialog.java:491)
at VASSAL.tools.BugDialog$CheckRequest.doInBackground(BugDialog.java:518)
at VASSAL.tools.BugDialog$CheckRequest.doInBackground(BugDialog.java:485)
at java.desktop/javax.swing.SwingWorker$1.call(SwingWorker.java:305)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.desktop/javax.swing.SwingWorker.run(SwingWorker.java:342)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
2025-08-20 00:23:53,545 [12600-AWT-EventQueue-0] INFO VASSAL.launch.ModuleManagerWindow - Exiting
I tried with Termux-X11 but I had xcfe not found error.
The screenshots are for 3.7.15 but they are the same as 3.7.16.
Thank you for providing information on your system.
Android 8 is (Oreo) a little old (from 2017), which may be an issue. I guess you are using an older (Samsung) tablet. Perhaps it can be upgraded to a newer version of Android - possibly via a custom rom.
Again, thank you for providing the errorLog content.
So Java version 21.0.8 (OpenJDK) - great.
The error says that a zero-sized image dimensions was passed where it shouldn’t. This is probably the cause of the empty windows you see, but it is not necessarily the root cause.
This error says that Vassal (or more accurately the Java Virtual Machine) could not do a domain name look-up on the domain vassalengine.org. Is your device connected to the internet? Not that it should matter - Vassal should simply forfeit the attempt to look-up whether there’s a newer version available. There’s a bug in Vassal VASSAL.tools.version.LiveVersionInfo.getRelease in that it doesn’t specify that it may throw java.net.UnknownHostException and that exception isn’t handled higher up the chain.
Could you give the exact error? The scripts should not execute any xfce command but rather xfce4-session. You could try to use fluxbox instead by editing
~/.local/bin/xvassal
and replacing xfc4-vassal with fluxbox-vassal.
What I suspect is happening, is that Java is trying to measure the screen size and gets back width and height of 0, which is then passed to an image construction. This could be what causes the first error above. The second error comes from Vassal trying to be clever and check if there’s a newer version of Vassal and then instruct you to download that. However, when that look-up fails, it fails to catch the error and exit gracefully.
The question is then why does Java get 0x0 dimensions? Well, that could be because the window manager (XFCE) reports back a 0 size. So why would the window manager do that? That could be coming from the X server (tightvnc in your case), which gets a size wrong. And the X server may get this wrong because it is doing a call to the Android API which isn’t supported in Android 8.
Another possibility, is that the image that Java is trying to measure is corrupted or not there at all. As far as I can gather, it is the image /icons/48x48/bug.png which is the culprit. That image should live inside the Vassal jar archive.
So how to proceed.
Check that your device is connected to the internet and whether that makes a difference.
Try with X again. Perhaps you need to re-run the xvassal-setup.sh script again if something got partially installed. In fact, you may want to run the entireprocedure again. Note that log files are written, so you may want to check these for errors or the like too.
See if you can upgrade your device to a newer Android.
Other than those, I do not have any good ideas at the moment - sorry. The problem you are seeing, I believe, comes from some weird interaction between Java - VNC (window manager) - and Android Oreo.