osate / osate2

Open Source AADL2 Tool Environment
http://osate.org
Eclipse Public License 2.0
36 stars 8 forks source link

NPE when exporting diagrams as SVG #2410

Closed philip-alldredge closed 3 years ago

philip-alldredge commented 4 years ago

On certain platforms, exporting a diagram to SVG throws an exception. This appears to be caused by support for "image/png" being missing from batik's image writer registry. It is unclear whether this affects windows support. As noted in #1461, on Linux platforms, text can be converted to images and embedded in the SVG. This appears to be part of that process.

See: https://issues.apache.org/jira/browse/BATIK-1228

!ENTRY org.eclipse.graphiti 4 0 2020-08-11 14:24:20.877 !MESSAGE Cannot save image: !STACK 0 java.lang.reflect.InvocationTargetException at org.eclipse.graphiti.ui.features.DefaultSaveImageFeature$1.run(DefaultSaveImageFeature.java:281) at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:436) at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:352) at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:469) at org.eclipse.graphiti.ui.features.DefaultSaveImageFeature.save(DefaultSaveImageFeature.java:114) at org.eclipse.graphiti.features.impl.AbstractSaveImageFeature.execute(AbstractSaveImageFeature.java:100) at org.osate.ge.internal.ui.handlers.SaveImageHandler.execute(SaveImageHandler.java:92) at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:283) at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:97) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:58) at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:318) at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:252) at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:173) at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:156) at org.eclipse.core.commands.Command.executeWithChecks(Command.java:488) at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:487) at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:213) at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:438) at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.handleWidgetSelection(AbstractContributionItem.java:449) at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.lambda$2(AbstractContributionItem.java:475) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5687) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1423) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4955) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4448) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1160) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1049) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:658) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:557) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:154) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:150) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:657) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:594) at org.eclipse.equinox.launcher.Main.run(Main.java:1447) at org.eclipse.equinox.launcher.Main.main(Main.java:1420) Caused by: java.lang.NullPointerException at org.apache.batik.svggen.ImageHandlerBase64Encoder.encodeImage(ImageHandlerBase64Encoder.java:157) at org.apache.batik.svggen.ImageHandlerBase64Encoder.handleHREF(ImageHandlerBase64Encoder.java:133) at org.apache.batik.svggen.ImageHandlerBase64Encoder.handleHREF(ImageHandlerBase64Encoder.java:72) at org.apache.batik.svggen.DefaultImageHandler.handleImage(DefaultImageHandler.java:63) at org.apache.batik.svggen.SimpleImageHandler.handleImage(SimpleImageHandler.java:100) at org.apache.batik.svggen.SVGGraphics2D.drawImage(SVGGraphics2D.java:677) at org.apache.batik.svggen.SVGGraphics2D.drawImage(SVGGraphics2D.java:868) at org.eclipse.graphiti.export.batik.GraphicsToGraphics2DAdaptor.drawString(GraphicsToGraphics2DAdaptor.java:764) at org.eclipse.graphiti.export.batik.GraphicsToGraphics2DAdaptor.drawText(GraphicsToGraphics2DAdaptor.java:719) at org.eclipse.draw2d.Graphics.drawText(Graphics.java:426) at org.eclipse.draw2d.Label.paintFigure(Label.java:515) at org.eclipse.graphiti.ui.internal.figures.GFText.paintFigure(GFText.java:149) at org.eclipse.draw2d.Figure.paint(Figure.java:1118) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1170) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1205) at org.eclipse.draw2d.Figure.paint(Figure.java:1120) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1170) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1205) at org.eclipse.draw2d.Figure.paint(Figure.java:1120) at org.eclipse.graphiti.export.batik.SVGExporter.export(SVGExporter.java:50) at org.eclipse.graphiti.ui.features.DefaultSaveImageFeature$1.run(DefaultSaveImageFeature.java:278) ... 50 more Root exception: java.lang.NullPointerException at org.apache.batik.svggen.ImageHandlerBase64Encoder.encodeImage(ImageHandlerBase64Encoder.java:157) at org.apache.batik.svggen.ImageHandlerBase64Encoder.handleHREF(ImageHandlerBase64Encoder.java:133) at org.apache.batik.svggen.ImageHandlerBase64Encoder.handleHREF(ImageHandlerBase64Encoder.java:72) at org.apache.batik.svggen.DefaultImageHandler.handleImage(DefaultImageHandler.java:63) at org.apache.batik.svggen.SimpleImageHandler.handleImage(SimpleImageHandler.java:100) at org.apache.batik.svggen.SVGGraphics2D.drawImage(SVGGraphics2D.java:677) at org.apache.batik.svggen.SVGGraphics2D.drawImage(SVGGraphics2D.java:868) at org.eclipse.graphiti.export.batik.GraphicsToGraphics2DAdaptor.drawString(GraphicsToGraphics2DAdaptor.java:764) at org.eclipse.graphiti.export.batik.GraphicsToGraphics2DAdaptor.drawText(GraphicsToGraphics2DAdaptor.java:719) at org.eclipse.draw2d.Graphics.drawText(Graphics.java:426) at org.eclipse.draw2d.Label.paintFigure(Label.java:515) at org.eclipse.graphiti.ui.internal.figures.GFText.paintFigure(GFText.java:149) at org.eclipse.draw2d.Figure.paint(Figure.java:1118) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1170) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1205) at org.eclipse.draw2d.Figure.paint(Figure.java:1120) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1170) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1205) at org.eclipse.draw2d.Figure.paint(Figure.java:1120) at org.eclipse.graphiti.export.batik.SVGExporter.export(SVGExporter.java:50) at org.eclipse.graphiti.ui.features.DefaultSaveImageFeature$1.run(DefaultSaveImageFeature.java:278) at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:436) at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:352) at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:469) at org.eclipse.graphiti.ui.features.DefaultSaveImageFeature.save(DefaultSaveImageFeature.java:114) at org.eclipse.graphiti.features.impl.AbstractSaveImageFeature.execute(AbstractSaveImageFeature.java:100) at org.osate.ge.internal.ui.handlers.SaveImageHandler.execute(SaveImageHandler.java:92) at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:283) at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:97) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:58) at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:318) at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:252) at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:173) at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:156) at org.eclipse.core.commands.Command.executeWithChecks(Command.java:488) at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:487) at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:213) at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:438) at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.handleWidgetSelection(AbstractContributionItem.java:449) at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.lambda$2(AbstractContributionItem.java:475) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5687) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1423) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4955) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4448) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1160) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1049) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:658) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:557) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:154) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:150) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:657) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:594) at org.eclipse.equinox.launcher.Main.run(Main.java:1447) at org.eclipse.equinox.launcher.Main.main(Main.java:1420)

https://groups.google.com/g/osate/c/8RNrB32GQrw/m/M0xPCgupBQAJ

Environment

philip-alldredge commented 4 years ago

@lwrage any suggestions? sounds like this is an issue with resolving the batik codec plugin in the eclipse environment. It is included in the OSATE distro.

lwrage commented 4 years ago

Works for me on Linux with OSATE 2.8.0 or when run from the development environment: SVG file is created and is editable after (ungrouping twice) in Inkscape. Even text is editable. I tried with a fresh package diagram for an empty package.

philip-alldredge commented 4 years ago

It's like due to a different codepath being taken. In some cases, strings get rendered to images as in #1461. I don't really understand what is going on in the Graphiti code but it seems to be trying to detect when it can't draw a string properly. Not sure if this is due to the string contents, Java version, installed fonts, or what.

The branch in the Graphiti is below: https://git.eclipse.org/c/graphiti/org.eclipse.graphiti.git/tree/plugins/org.eclipse.graphiti.export.batik/src/org/eclipse/graphiti/export/batik/GraphicsToGraphics2DAdaptor.java#n735

jasonbelt commented 4 years ago

@philip-alldredge it could be an issue related to installed fonts. The SVG export works under Debian 10 if I first hide all the text labels in the diagram. Note that different output formats (e.g. PNG, GIF) work as expected under Debian/Mac.

fyi, here is how I reproduce the issue. Open the example ARINC653 arincexample2 project. Select arinc653system.impl in the Outline view and choose 'Open Diagram' then 'Structured Diagram'. Select arinc653system.impl in the diagram editor, select 'All' and SVG in 'Export Diagram' dialog box and then OK. I get a dialog saying "Cannot save image: null'. Switching to PNG/GIF/etc in the last step allows the diagram to be exported successfully.

lwrage commented 4 years ago

I tested on Ubuntu 20.04. The SVG file uses Arial for the text and I have Arial installed.

jasonbelt commented 4 years ago

@lwrage SVG exports work under Debian 10 and Ubuntu 20.04 after adding the contrib repo and then installing ms fonts via apt-get install ttf-mscorefonts-installer. I still experience the NPE on macOS 10.14.6 even though Arial is installed

philip-alldredge commented 3 years ago

Closing. Should be fixed by Fixed by dbefc8b. Re-open if issue persists in the next version.