nidi3 / graphviz-java

Use graphviz with pure java
Apache License 2.0
937 stars 107 forks source link

Lazily evaluate available engines. #159

Closed anuraaga closed 4 years ago

anuraaga commented 4 years ago

Currently, availableEngines() is always evaluated when GraphViz is class-loaded. This is wasteful if the user manually set an engine with useEngine(), and can be problematic if the JDK has been trimmed using jlink for whatever reason. In my normal docker base image, which is heavily trimmed, I get this message even though I have graphviz installed and don't really need the font functionality.

Caused by: java.lang.NullPointerException
    at sun.awt.FontConfiguration.getVersion(Unknown Source) ~[?:?]
    at sun.awt.FontConfiguration.readFontConfigFile(Unknown Source) ~[?:?]
    at sun.awt.FontConfiguration.init(Unknown Source) ~[?:?]
    at sun.awt.X11FontManager.createFontConfiguration(Unknown Source) ~[?:?]
    at sun.font.SunFontManager$2.run(Unknown Source) ~[?:?]
    at java.security.AccessController.doPrivileged(Unknown Source) ~[?:?]
    at sun.font.SunFontManager.<init>(Unknown Source) ~[?:?]
    at sun.awt.FcFontManager.<init>(Unknown Source) ~[?:?]
    at sun.awt.X11FontManager.<init>(Unknown Source) ~[?:?]
    at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[?:?]
    at java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source) ~[?:?]
    at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:?]
    at sun.font.FontManagerFactory$1.run(Unknown Source) ~[?:?]
    at java.security.AccessController.doPrivileged(Unknown Source) ~[?:?]
    at sun.font.FontManagerFactory.getInstance(Unknown Source) ~[?:?]
    at java.awt.Font.getFont2D(Unknown Source) ~[?:?]
    at java.awt.Font$FontAccessImpl.getFont2D(Unknown Source) ~[?:?]
    at sun.font.FontUtilities.getFont2D(Unknown Source) ~[?:?]
    at sun.font.StandardGlyphVector.initFontData(Unknown Source) ~[?:?]
    at sun.font.StandardGlyphVector.init(Unknown Source) ~[?:?]
    at sun.font.StandardGlyphVector.<init>(Unknown Source) ~[?:?]
    at java.awt.Font.createGlyphVector(Unknown Source) ~[?:?]
    at guru.nidi.graphviz.engine.FontMeasurer.charWidth(FontMeasurer.java:43) ~[graphviz-java-0.16.0.jar:?]
anuraaga commented 4 years ago

For additional reference, even without jlink and just openjdk:14-slim, can't load the class so doesn't only affect crazy people like me ;)

Caused by: java.lang.UnsatisfiedLinkError: /usr/java/openjdk-14/lib/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory
    at java.lang.ClassLoader$NativeLibrary.load0(Native Method) ~[?:?]
    at java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2452) ~[?:?]
    at java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2508) ~[?:?]
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2704) ~[?:?]
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:2658) ~[?:?]
    at java.lang.Runtime.loadLibrary0(Runtime.java:807) ~[?:?]
    at java.lang.System.loadLibrary(System.java:1907) ~[?:?]
    at sun.font.FontManagerNativeLibrary$1.run(FontManagerNativeLibrary.java:57) ~[?:?]
    at java.security.AccessController.doPrivileged(AccessController.java:312) ~[?:?]
    at sun.font.FontManagerNativeLibrary.<clinit>(FontManagerNativeLibrary.java:32) ~[?:?]
    at sun.font.SunFontManager$1.run(SunFontManager.java:272) ~[?:?]
    at java.security.AccessController.doPrivileged(AccessController.java:312) ~[?:?]
    at sun.font.SunFontManager.<clinit>(SunFontManager.java:268) ~[?:?]
    at java.lang.Class.forName0(Native Method) ~[?:?]
    at java.lang.Class.forName(Class.java:427) ~[?:?]
    at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:82) ~[?:?]
    at java.security.AccessController.doPrivileged(AccessController.java:312) ~[?:?]
    at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74) ~[?:?]
    at java.awt.Font.getFont2D(Font.java:497) ~[?:?]
    at java.awt.Font$FontAccessImpl.getFont2D(Font.java:237) ~[?:?]
    at sun.font.FontUtilities.getFont2D(FontUtilities.java:139) ~[?:?]
    at sun.font.StandardGlyphVector.initFontData(StandardGlyphVector.java:1132) ~[?:?]
    at sun.font.StandardGlyphVector.init(StandardGlyphVector.java:1121) ~[?:?]
    at sun.font.StandardGlyphVector.<init>(StandardGlyphVector.java:167) ~[?:?]
    at java.awt.Font.createGlyphVector(Font.java:2728) ~[?:?]
    at guru.nidi.graphviz.engine.FontMeasurer.charWidth(FontMeasurer.java:43) ~[graphviz-java-0.16.0.jar:?]
    at guru.nidi.graphviz.engine.FontMeasurer.<clinit>(FontMeasurer.java:29) ~[graphviz-java-0.16.0.jar:?]
    at guru.nidi.graphviz.engine.AbstractJsGraphvizEngine.<init>(AbstractJsGraphvizEngine.java:37) ~[graphviz-java-0.16.0.jar:?]
    at guru.nidi.graphviz.engine.GraphvizJdkEngine.<init>(GraphvizJdkEngine.java:27) ~[graphviz-java-0.16.0.jar:?]
    at guru.nidi.graphviz.engine.Graphviz.availableEngines(Graphviz.java:88) ~[graphviz-java-0.16.0.jar:?]
    at guru.nidi.graphviz.engine.Graphviz.<clinit>(Graphviz.java:44) ~[graphviz-java-0.16.0.jar:?]