Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with FlatLaf Look & Feel dependencies with Java 11 on Windows 10 #19

Closed
wjc-van-es opened this issue Jan 16, 2021 · 7 comments
Closed
Labels

Comments

@wjc-van-es
Copy link

Dear Gabor Bata,

first of all I would like to thank you for sharing this application. I have used it for quite some time on different platforms and it used to work without any effort. Now I have upgraded to your latest release to be able to work in a Java 11 environment.

On Windows 10, however, I have encountered a show stopping classloading problem with the com.formdev.flatlaf.FlatLaf look and feel, which stalled the applications at startup, no password prompting popup window will show up. Strange enough the stalling doesn't happen on my Linux Mint laptop (though the same java.lang.NoClassDefFoundError stacktrace is shown in the console). See below for a detailed description and work around.

Kind regards,
Willem van Es

Problem description

When building the latest snapshot with

  • maven 3.6.3 (mvn clean package)
  • Java 11, Oracle JDK 11.0.9

and running the resulting jpass-0.1.21-SNAPSHOT.jar from a command line terminal also with Java 11,
I see the following stacktrace logging in the console:

java -jar jpass-0.1.21-SNAPSHOT.jar mypasswords.jpass
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: com/formdev/flatlaf/util/MultiResolutionImageSupport$MappedMultiResolutionImage
        at com.formdev.flatlaf.ui.FlatTitlePaneIcon.create(FlatTitlePaneIcon.java:38)
        at com.formdev.flatlaf.ui.FlatTitlePane.updateIcon(FlatTitlePane.java:321)
        at com.formdev.flatlaf.ui.FlatTitlePane.addNotify(FlatTitlePane.java:351)
        at java.desktop/java.awt.Container.addNotify(Container.java:2800)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4783)
        at java.desktop/java.awt.Container.addNotify(Container.java:2800)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4783)
        at java.desktop/javax.swing.JRootPane.addNotify(JRootPane.java:733)
        at java.desktop/java.awt.Container.addNotify(Container.java:2800)
        at java.desktop/java.awt.Window.addNotify(Window.java:786)
        at java.desktop/java.awt.Frame.addNotify(Frame.java:490)
        at java.desktop/java.awt.Window.show(Window.java:1048)
        at java.desktop/java.awt.Component.show(Component.java:1716)
        at java.desktop/java.awt.Component.setVisible(Component.java:1663)
        at java.desktop/java.awt.Window.setVisible(Window.java:1031)
        at jpass.ui.JPassFrame.<init>(JPassFrame.java:207)
        at jpass.ui.JPassFrame.getInstance(JPassFrame.java:220)
        at jpass.JPass.lambda$main$0(JPass.java:75)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
        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.lang.ClassNotFoundException: com.formdev.flatlaf.util.MultiResolutionImageSupport$MappedMultiResolutionImage
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 31 more

There is one crucial difference in the behavior in my Linux Mint laptop and the Windows 10 Laptop from the company I work for:

  • under Linux I am still prompted for the master password and the application window opens and works normal, so no big deal
  • under Windows 10, however, the process stalls with the error stacktrace in the console and I am unable to continue with the application.

First analysis

Investigating the com.formdev:flatlaf:0.43 dependency reveals that the inner class com.formdev.flatlaf.util.MultiResolutionImageSupport$MappedMultiResolutionImage is indeed missing from both the flatlaf-043.jar and the resulting jpass-0.1.21-SNAPSHOT.jar.
Maybe this problem could easily be resolved with updating the com.formdev:flatlaf:0.43, but I did not pursue this possibility yet.

Work around

In my fork of this project at https://github.com/wjc-van-es/jpass I just disabled the use of the com.formdev.flatlaf.FlatLaf lookAndFeel in jpass.JPass#main and used the platform default instead.
I admit this is a rather quick and dirty solution, but it works fine for me as the application now starts normally with the default Windows 10 look and feel without any errors.

Here is what I changed to make it work:

public static void main(final String[] args) {
        try {
         //// Start of block of dead code - I left it in to demonstrate it didn't cause NoClassDefFoundError   
            FlatLaf lookAndFeel;
            if (Configuration.getInstance().is("ui.theme.dark.mode.enabled", false)) {
                FlatDarkLaf.install();
                lookAndFeel = new FlatDarkLaf();
            } else {
                FlatLightLaf.install();
                lookAndFeel = new FlatLightLaf();
            }
        //// End of block of dead code ///////////////////////////////////
            
            JFrame.setDefaultLookAndFeelDecorated(true);
            JDialog.setDefaultLookAndFeelDecorated(true);

            // Ultimately results in a java.lang.NoClassDefFoundError during the call to the 
            // jpass.ui.JPassFrame.JPassFrame constructor: 
            // com/formdev/flatlaf/util/MultiResolutionImageSupport$MappedMultiResolutionImage
            //UIManager.setLookAndFeel(lookAndFeel);
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); //falling back on system default
        } catch (Exception e) {
            LOG.log(Level.CONFIG, "Could not set look and feel for the application", e);
        }

        SwingUtilities.invokeLater(() -> JPassFrame.getInstance((args.length > 0) ? args[0] : null));
    }
wjc-van-es added a commit to wjc-van-es/jpass that referenced this issue Jan 16, 2021
Issue gaborbata#19: Problem with FlatLaf Look & Feel dependencies with Java 11 on Windows 10
@wjc-van-es
Copy link
Author

Small addition: on my Linux laptop the installed Java version is a bit older: Oracle jdk 11.0.5 (instead of the 11.0.9 installed on my Windows 10 laptop). This might account for the different behavior on the respective platforms.

@DevCharly
Copy link

Hi, I'm the author of FlatLaf.

Class com.formdev.flatlaf.util.MultiResolutionImageSupport$MappedMultiResolutionImage
is in jpass-0.1.20-RELEASE.jar (and flatlaf-043.jar) in directory META-INF/versions/9.
This is because this are multi-release JARs (https://openjdk.java.net/jeps/238)
So when running in Java 9 or later, the JRE first looks into META-INF/versions/9 and loads classes from there.

The inner class MultiResolutionImageSupport$MappedMultiResolutionImage is only used when the Java 9 version of MultiResolutionImageSupport form META-INF/versions/9 is used.
There is a second version of MultiResolutionImageSupport for Java 8 in the JAR (in default directory), which does not use the inner class.

So this is a strange exception...

You built JPass yourself, right?
Maybe there is a problem with the build on your machine.

Do you have the same problem with 0.1.20 from here:
https://github.com/gaborbata/jpass/releases/tag/v0.1.20

For me, JPass 0.1.20-RELEASE (downloaded from GitHub) works on Windows 10 with Oracle JDK 11.0.9:

image

@gaborbata gaborbata added the bug label Jan 18, 2021
@gaborbata
Copy link
Owner

Hi @wjc-van-es and @DevCharly, thanks for looking into the issue.

I could reproduce the issue when I build the application with JDK 11. Building with JDK 8 -- used for the release package -- does not have this issue, and as far as I know it runs well with Java 11.

I suspect, the issue must be in the build process, possibly during creating a fat/uber jar. But I have to dig deeper when time permits

@CatPlanet
Copy link

@wjc-van-es can you provide some details on:

  • do you have multiple java versions on you Windows?
  • what is default java version?
  • what version JAVA_HOME environmental variable points to
  • if PATH points to %JAVA_HOME%\bin
  • do you build project using your IDE or running just via commandline
  • if IDE: what version of java is your project set up to

@gaborbata
Copy link
Owner

gaborbata commented Jan 18, 2021

@wjc-van-es it seems upgrading maven assembly plugin has resolved the issue, could you please check #20 if it works for you?

Related issue: https://issues.apache.org/jira/browse/MASSEMBLY-891

@wjc-van-es
Copy link
Author

@wjc-van-es it seems upgrading maven assembly plugin has resolved the issue, could you please check #20 if it works for you?

Related issue: https://issues.apache.org/jira/browse/MASSEMBLY-891

@gaborbata building from your bugfix.jdk11-build branch with mvn clean package appears to solve the problem for me as well.
Both in Linux Mint and Windows 10 the resulting jar file could be run normally and without exceptions appearing in the console.
In conclusion I think this has fixed the issue.

Aside: probable cause for different behavior on my Linux and my Windows Laptop

In addition I may have discovered what caused the different behavior between Linux and Windows (the former continuing whilst the latter froze).
In windows I start the jar from a batch file that is in the same directory as the jar and the jpass.properties file.
In linux I had a bash file in a different location and in the bash file uses variables:
${java11Home}/bin/java -jar ${jpassDir}/${jarFile} ${jpassDir}/${jpFile}
Here the ${jpassDir} specifies the directory that contains the jar, the jpass.properties and the encrypted *.jpass file containing the password entries. I did this mainly because I was comparing different versions of jpass builds (different resulting jars) and run with different versions of the JDK, each configuration run with its own bash file. (In Windows I only have the JDK 11.0.9 installed).

Now I noticed that running jpass this way the jpass.properties is ignored. I took more notice because I changed the ui.theme.dark.mode.enabled=true to see if the FlatDarkLaf was really used with your fix. On Windows I saw the dark look and feel, but in Linux I didn't.
However, when I run in a console in the same directory where jar, jpass.properties and *.jpass file are in then the dark theme is enabled, which looks cool, by the way.
~/resources/pw/jpass$ /home/willem/App/Java/jdk-11.0.5/bin/java -jar jpass-0.1.21-SNAPSHOT.jar myPasswords.jpass 

@gaborbata
Copy link
Owner

@wjc-van-es thanks for the verification. I am closing this issue, and raise a new one for the jpass.properties loading issue.

Chaos-woo added a commit to Chaos-woo/random-studio that referenced this issue Sep 24, 2023
1. 修复多版本Java打包缺失类的问题(gaborbata/jpass#19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants