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

[Substance] Crash during initialization on null desktop hints #184

Closed
maxbaird opened this issue Jun 10, 2019 · 8 comments

Comments

@maxbaird
Copy link

commented Jun 10, 2019

Version of Radiance (current development is 2.5-SNAPSHOT)

2.5-SNAPSHOT

Version of Java (current minimum is 9)

java version "12.0.1" 2019-04-16
Java(TM) SE Runtime Environment (build 12.0.1+12)
Java HotSpot(TM) 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)

Version of OS

Description: Fedora release 28 (Twenty Eight)
Release: 28
Codename: TwentyEight

The issue you're experiencing (expected vs actual, screenshot, stack trace etc)

I'm going through the document for getting started with Substance Look And Feel. I'm doing the manual process of building Radiance with gradle using the Walkthrough example. I use the following script to run the frame under Substance:
java -Dswing.defaultlaf=org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel -cp .:/home/max/tmp/radiance-substance-2.5-SNAPSHOT.jar:/home/max/tmp/radiance-trident-2.5-SNAPSHOT.jar:/home/max/tmp/radiance-neon-2.5-SNAPSHOT.jar Walkthrough

But this still results with:

Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot load org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel
	at java.desktop/javax.swing.UIManager.initializeDefaultLAF(UIManager.java:1406)
	at java.desktop/javax.swing.UIManager.initialize(UIManager.java:1517)
	at java.desktop/javax.swing.UIManager.maybeInitialize(UIManager.java:1483)
	at java.desktop/javax.swing.UIManager.getUI(UIManager.java:1056)
	at java.desktop/javax.swing.JPanel.updateUI(JPanel.java:126)
	at java.desktop/javax.swing.JPanel.<init>(JPanel.java:86)
	at java.desktop/javax.swing.JPanel.<init>(JPanel.java:109)
	at java.desktop/javax.swing.JPanel.<init>(JPanel.java:117)
	at java.desktop/javax.swing.JRootPane.createGlassPane(JRootPane.java:521)
	at java.desktop/javax.swing.JRootPane.<init>(JRootPane.java:348)
	at java.desktop/javax.swing.JFrame.createRootPane(JFrame.java:279)
	at java.desktop/javax.swing.JFrame.frameInit(JFrame.java:258)
	at java.desktop/javax.swing.JFrame.<init>(JFrame.java:225)
	at Walkthrough.<init>(Walkthrough.java:7)
	at Walkthrough.lambda$main$0(Walkthrough.java:23)
	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(AccessController.java:389)
	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)

What am I missing? Thanks.

@kirill-grouchnikov

This comment has been minimized.

Copy link
Owner

commented Jun 10, 2019

This works for me:

java -cp .:drop/2.5-SNAPSHOT/core/radiance-substance-2.5-SNAPSHOT.jar:drop/2.5-SNAPSHOT/core/radiance-trident-2.5-SNAPSHOT.jar:drop/2.5-SNAPSHOT/core/radiance-neon-2.5-SNAPSHOT.jar -Dswing.defaultlaf=org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel Walkthrough

You can use "jar tvf" to inspect the contents of /home/max/tmp/radiance-substance-2.5-SNAPSHOT.jar to verify that it was built properly - that is, that it contains the org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel class.

@maxbaird

This comment has been minimized.

Copy link
Author

commented Jun 10, 2019

All right, just wanted to make sure I wasn't missing anything. I guess its some problem on my end. Thanks.

@maxbaird maxbaird closed this Jun 10, 2019

@kirill-grouchnikov

This comment has been minimized.

Copy link
Owner

commented Jun 10, 2019

I tried those steps with Java 9 and Java 12. Worked for me under both.

I would start by inspecting the contents of the jars that you've built locally to see what's inside - and comparing the contents with the prebuilt binaries from https://github.com/kirill-grouchnikov/radiance/tree/master/drop/2.5-SNAPSHOT/core

@maxbaird

This comment has been minimized.

Copy link
Author

commented Jun 10, 2019

Right, I forgot to mention that I did look into the jar using "jar tvf", it does contain the org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel class. I'll try comparing the contents with the prebuilt binaries.

@maxbaird

This comment has been minimized.

Copy link
Author

commented Jun 12, 2019

As a follow-up in case this is somehow important/interesting, I managed to get it working. When running the default look and feel, I observed that the font was not anti-aliased by default on my machine (Fedora 28, using i3-gaps as a window manager). I wondered if this was somehow related and did some reading on Java runtime environment fonts. In essence the fonts looked like this:

default_no_aa

But launching the application with this system property: -Dawt.useSystemAAFontSettings=on fixed things:
default_with_aa

It turns out that setting this property when launching Walkthrough with Radiance makes it work:

java -Dawt.useSystemAAFontSettings=on -Dswing.defaultlaf=org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel -cp .:tmp/radiance-substance-2.5-SNAPSHOT.jar:tmp/radiance-trident-2.5-SNAPSHOT.jar:tmp/radiance-neon-2.5-SNAPSHOT.jar Walkthrough

radiance_with_aa

Removing this property results in the error of Java being unable to load org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel.

Reading here has more information. I assume because I have customised my Fedora 28 setup (I don't use gnome) is the reason I don't have an gnome-settings-daemon running from which Java uses to get the system defaults and this is somehow a problem for Radiance...? Not sure.

@kirill-grouchnikov

This comment has been minimized.

Copy link
Owner

commented Jun 13, 2019

Is there anything in the stack that is a bit more informative than just "Cannot load ..."? It very may well be a bug in Substance that is then converted to a more generic stack trace that masks away the original exception.

Can't say for sure without being able to reproduce this on my machine. Substance definitely uses desktop hints to configure font rendering during its initialization. Maybe there's a bug there that is only reproduced under very specific conditions.

@maxbaird

This comment has been minimized.

Copy link
Author

commented Jun 13, 2019

Setting the look and feel via code also throughs an exception if I don't use -Dawt.useSystemAAFontSettings=on. Below is the script used to launch the application and a printing of the stack trace when the exception is caught:

$ java -cp .:tmp/radiance-substance-2.5-SNAPSHOT.jar:tmp/radiance-trident-2.5-SNAPSHOT.jar:tmp/radiance-neon-2.5-SNAPSHOT.jar Walkthrough
Substance Graphite failed to initialize
java.lang.NullPointerException
	at org.pushingpixels.substance.api.SubstanceLookAndFeel.initComponentDefaults(SubstanceLookAndFeel.java:179)
	at java.desktop/javax.swing.plaf.basic.BasicLookAndFeel.getDefaults(BasicLookAndFeel.java:150)
	at org.pushingpixels.substance.api.SubstanceLookAndFeel.getDefaults(SubstanceLookAndFeel.java:196)
	at java.desktop/javax.swing.UIManager.setLookAndFeel(UIManager.java:587)
	at Walkthrough.lambda$main$0(Walkthrough.java:26)
	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(AccessController.java:389)
	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)

The source used for this execution is as follows:

import java.awt.*;
import javax.swing.*;

import org.pushingpixels.substance.api.skin.SubstanceGraphiteLookAndFeel;

import java.awt.image.*;

public class Walkthrough extends JFrame {
  public Walkthrough() {
    super("Sample app");
    this.setLayout(new FlowLayout());
    this.add(new JButton("button"));
    this.add(new JCheckBox("check"));
    this.add(new JLabel("label"));

    this.setIconImage(new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR));
    this.setSize(new Dimension(250, 80));
    this.setLocationRelativeTo(null);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

  public static void main(String[] args) {
      JFrame.setDefaultLookAndFeelDecorated(true);
      SwingUtilities.invokeLater(() -> {
          try {
            UIManager.setLookAndFeel(new SubstanceGraphiteLookAndFeel());
          } catch (Exception e) {
            System.out.println("Substance Graphite failed to initialize");
            e.printStackTrace();
          }
          Walkthrough w = new Walkthrough();
          w.setVisible(true);
      });
    }
}

What's different this time is that the JFrame is somewhat rendered with substance, just not completely, see below:

substance_exception_no_aa

Hope this helps, happy to do further digging if you have suggestions.

@kirill-grouchnikov

This comment has been minimized.

Copy link
Owner

commented Jun 13, 2019

This is in https://github.com/kirill-grouchnikov/radiance/blob/master/substance/src/main/java/org/pushingpixels/substance/api/SubstanceLookAndFeel.java#L179

The assumption is that the relevant desktop property is never null. Apparently that's a wrong assumption. Will fix.

@kirill-grouchnikov kirill-grouchnikov changed the title Trouble getting started with Substance look and feel [Substance] Crash during initialization on null desktop hints Jun 14, 2019

@kirill-grouchnikov kirill-grouchnikov self-assigned this Jun 14, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.