nidi3 / graphviz-java

Use graphviz with pure java
Apache License 2.0
930 stars 105 forks source link

NullPointerException thrown when invoking createDiagram(String svg) function in the SalamanderRasterizer #239

Closed Akagitsunee closed 1 year ago

Akagitsunee commented 1 year ago

When invoking the createDiagram(String svg) function in the SalamanderRasterizer class I get a NullPointerException.

When the function invokes final URI uri = universe.loadSVG(new StringReader(svg), "//graph/"); I get a null as response the first try it is invoked.

private SVGDiagram createDiagram(String svg) {
        final SVGUniverse universe = new SVGUniverse();
        final URI uri = universe.loadSVG(new StringReader(svg), "//graph/"); <-- NullPointer
        final SVGDiagram diagram = universe.getDiagram(uri); 
        diagram.setIgnoringClipHeuristic(true);
        return diagram;
    }

Oddly enough when debugging and invoking the same function again 2-4 times, I get a correct answer. This only works when debugging and never works in production mode.

Whole stacktrace (runs on docker):

 QualifiedName during linking.
web_1  | try to call: path=/tmp/GraphvizJava/DotEngine8656812800459846281; dotFile=/tmp/GraphvizJava/DotEngine8656812800
459846281/dotfile.dot; options=Options{engine=DOT, format=PNG, totalMemory=null, yInvert=null, basedir=/tmp/GraphvizJava
, images=[]}
web_1  | 1383634 [http-nio-8080-exec-3] INFO  raphviz.service.CommandLineExecutor  - executing command [/bin/sh, -c, dot
 -Tsvg /tmp/GraphvizJava/DotEngine8656812800459846281/dotfile.dot -ooutfile.svg]
web_1  | Sep 23, 2022 1:58:08 PM com.kitfox.svg.SVGUniverse loadSVG
web_1  | WARNING: Could not load SVG svgSalamander://graph/
web_1  | java.lang.InternalError: java.lang.reflect.InvocationTargetException
web_1  |        at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:86)
web_1  |        at java.base/java.security.AccessController.doPrivileged(Native Method)
web_1  |        at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
web_1  |        at java.desktop/sun.java2d.SunGraphicsEnvironment.getFontManagerForSGE(SunGraphicsEnvironment.java:190)
web_1  |        at java.desktop/sun.java2d.SunGraphicsEnvironment.getAvailableFontFamilyNames(SunGraphicsEnvironment.jav
a:224)
web_1  |        at java.desktop/sun.java2d.HeadlessGraphicsEnvironment.getAvailableFontFamilyNames(HeadlessGraphicsEnvir
onment.java:78)
web_1  |        at com.kitfox.svg.util.FontSystem.checkIfSystemFontExists(FontSystem.java:71)
web_1  |        at com.kitfox.svg.util.FontSystem.createFont(FontSystem.java:86)
web_1  |        at com.kitfox.svg.Text.buildText(Text.java:286)
web_1  |        at com.kitfox.svg.Text.build(Text.java:266)
web_1  |        at com.kitfox.svg.Text.updateTime(Text.java:610)
web_1  |        at com.kitfox.svg.Group.updateTime(Group.java:313)
web_1  |        at com.kitfox.svg.Group.updateTime(Group.java:313)
web_1  |        at com.kitfox.svg.Group.updateTime(Group.java:313)
web_1  |        at com.kitfox.svg.SVGRoot.updateTime(SVGRoot.java:409)
web_1  |        at com.kitfox.svg.SVGDiagram.updateTime(SVGDiagram.java:243)
web_1  |        at com.kitfox.svg.SVGUniverse.loadSVG(SVGUniverse.java:610)
web_1  |        at com.kitfox.svg.SVGUniverse.loadSVG(SVGUniverse.java:545)
web_1  |        at com.kitfox.svg.SVGUniverse.loadSVG(SVGUniverse.java:502)
web_1  |        at guru.nidi.graphviz.engine.SalamanderRasterizer.createDiagram(SalamanderRasterizer.java:45)
web_1  |        at guru.nidi.graphviz.engine.SalamanderRasterizer.doRasterize(SalamanderRasterizer.java:31)
web_1  |        at guru.nidi.graphviz.engine.SvgRasterizer.rasterize(SvgRasterizer.java:41)
web_1  |        at guru.nidi.graphviz.engine.Renderer.toImage(Renderer.java:115)
web_1  |        at guru.nidi.graphviz.engine.Renderer.toOutputStream(Renderer.java:93)
web_1  |        at guru.nidi.graphviz.engine.Renderer.lambda$toOutputStream$5(Renderer.java:88)
web_1  |        at guru.nidi.graphviz.engine.EngineResult.mapIO(EngineResult.java:61)
web_1  |        at guru.nidi.graphviz.engine.Renderer.toOutputStream(Renderer.java:86)
web_1  |        at org.contextmapper.contextmap.generator.ContextMapGenerator.generateContextMapGraphic(ContextMapGenera
tor.java:148)
web_1  |        at org.contextmapper.dsl.generator.ContextMapGenerator.generateFromContextMap(ContextMapGenerator.java:7
1)
web_1  |        at org.contextmapper.dsl.generator.AbstractContextMapGenerator.doGenerate(AbstractContextMapGenerator.ja
va:55)
web_1  |        at org.contextmapper.dsl.standalone.StandaloneContextMapper.callGenerator(StandaloneContextMapper.java:5
6)
web_1  |        at org.contextmapper.web.service.GeneratorService.generate(GeneratorService.java:29)
web_1  |        at org.contextmapper.web.api.GeneratorController.createCommunity(GeneratorController.java:29)
web_1  |        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
web_1  |        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     
web_1  |        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
43)
web_1  |        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
web_1  |        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:20
5)
web_1  |        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod
.java:150)
web_1  |        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(S
ervletInvocableHandlerMethod.java:117)
web_1  |        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMetho
d(RequestMappingHandlerAdapter.java:895)
web_1  |        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(Req
uestMappingHandlerAdapter.java:808)
web_1  |        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodA
dapter.java:87)
web_1  |        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
web_1  |        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
web_1  |        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
web_1  |        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
web_1  |        at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
web_1  |        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
web_1  |        at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)  
web_1  |        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
web_1  |        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:
201)
web_1  |        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
web_1  |        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
web_1  |        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
web_1  |        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
web_1  |        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
web_1  |        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
web_1  |        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
web_1  |        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
web_1  |        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
web_1  |        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
web_1  |        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789)
web_1  |        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
web_1  |        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
web_1  |        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
web_1  |        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
web_1  |        at java.base/java.lang.Thread.run(Thread.java:829)
web_1  | Caused by: java.lang.reflect.InvocationTargetException
web_1  |        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
web_1  |        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImp
l.java:62)
web_1  |        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAcc
essorImpl.java:45)
web_1  |        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
web_1  |        at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:84)
web_1  |        ... 82 more
web_1  | Caused by: java.lang.NullPointerException
web_1  |        at java.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
web_1  |        at java.desktop/sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:225)
web_1  |        at java.desktop/sun.awt.FontConfiguration.init(FontConfiguration.java:107)
web_1  |        at java.desktop/sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:719)
web_1  |        at java.desktop/sun.font.SunFontManager$2.run(SunFontManager.java:379)
web_1  |        at java.base/java.security.AccessController.doPrivileged(Native Method)
web_1  |        at java.desktop/sun.font.SunFontManager.<init>(SunFontManager.java:324)
web_1  |        at java.desktop/sun.awt.FcFontManager.<init>(FcFontManager.java:35)
web_1  |        at java.desktop/sun.awt.X11FontManager.<init>(X11FontManager.java:56)
web_1  |        ... 87 more
web_1  |
web_1  | Sep 23, 2022 1:58:08 PM org.apache.catalina.core.StandardWrapperValve invoke
web_1  | SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request proc
essing failed; nested exception is java.lang.NullPointerException] with root cause
web_1  | java.lang.NullPointerException
web_1  |        at guru.nidi.graphviz.engine.SalamanderRasterizer.createDiagram(SalamanderRasterizer.java:47)
web_1  |        at guru.nidi.graphviz.engine.SalamanderRasterizer.doRasterize(SalamanderRasterizer.java:31)
web_1  |        at guru.nidi.graphviz.engine.SvgRasterizer.rasterize(SvgRasterizer.java:41)
web_1  |        at guru.nidi.graphviz.engine.Renderer.toImage(Renderer.java:115)
web_1  |        at guru.nidi.graphviz.engine.Renderer.toOutputStream(Renderer.java:93)
web_1  |        at guru.nidi.graphviz.engine.Renderer.lambda$toOutputStream$5(Renderer.java:88)
web_1  |        at guru.nidi.graphviz.engine.EngineResult.mapIO(EngineResult.java:61)
web_1  |        at guru.nidi.graphviz.engine.Renderer.toOutputStream(Renderer.java:86)
web_1  |        at org.contextmapper.contextmap.generator.ContextMapGenerator.generateContextMapGraphic(ContextMapGenera
tor.java:148)
web_1  |        at org.contextmapper.dsl.generator.ContextMapGenerator.generateFromContextMap(ContextMapGenerator.java:7
1)
web_1  |        at org.contextmapper.dsl.generator.AbstractContextMapGenerator.doGenerate(AbstractContextMapGenerator.ja
va:55)
web_1  |        at org.contextmapper.dsl.standalone.StandaloneContextMapper.callGenerator(StandaloneContextMapper.java:5
6)
web_1  |        at org.contextmapper.web.service.GeneratorService.generate(GeneratorService.java:29)
web_1  |        at org.contextmapper.web.api.GeneratorController.createCommunity(GeneratorController.java:29)
web_1  |        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
web_1  |        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     
web_1  |        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
43)
web_1  |        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
web_1  |        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:20
5)
web_1  |        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod
.java:150)
web_1  |        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(S
ervletInvocableHandlerMethod.java:117)
web_1  |        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMetho
d(RequestMappingHandlerAdapter.java:895)
web_1  |        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(Req
uestMappingHandlerAdapter.java:808)
web_1  |        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodA
dapter.java:87)
web_1  |        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
web_1  |        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
web_1  |        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
web_1  |        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
web_1  |        at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
web_1  |        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
web_1  |        at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
web_1  |        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
web_1  |        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:
201)
web_1  |        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)    
web_1  |        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
web_1  |        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
web_1  |        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
web_1  |        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
web_1  |        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
web_1  |        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
web_1  |        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
web_1  |        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
web_1  |        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
web_1  |        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
web_1  |        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
web_1  |        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789)
web_1  |        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
web_1  |        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
web_1  |        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
web_1  |        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
web_1  |        at java.base/java.lang.Thread.run(Thread.java:829)
Akagitsunee commented 1 year ago

This happens if you use graphviz on a system without fonts (Alpine docker image for example). He tries to get all fonts of the system but gets a null pointer as there are none.

Took me some time to debug.