JetBrains / lets-plot

Multiplatform plotting library based on the Grammar of Graphics
https://lets-plot.org
MIT License
1.55k stars 49 forks source link

Getting errors while exporting image outside of Intellij IDEA #842

Closed vkupar closed 1 year ago

vkupar commented 1 year ago

Hi,

Exporting as png file works perfectly while running from Intellij IDEA.

I'm getting these errors when I run the code locally in terminal or in CI environment: An exception occurred while executing the Java class. Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found ... javax.xml.parsers.FactoryConfigurationError: Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found ... Can't export plot to raster formats: NoClassDefFoundError "Could not initialize class org.apache.batik.anim.dom.SAXSVGDocumentFactory". Please add "lets-plot-image-export-<version>.jar" to your classpath.

pom.xml:

<dependency>
  <groupId>org.jetbrains.lets-plot</groupId>
  <artifactId>lets-plot-kotlin-jvm</artifactId>
  <version>4.3.0</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.jetbrains.lets-plot</groupId>
  <artifactId>lets-plot-image-export</artifactId>
  <version>3.1.0</version>
  <scope>test</scope>
</dependency>

Code:

import org.jetbrains.letsPlot.export.ggsave
import org.jetbrains.letsPlot.geom.geomPoint
import org.jetbrains.letsPlot.letsPlot

fun main() {
  val xs = listOf(0,  0.5, 1, 2)
  val ys = listOf(0, 0.25, 1, 4)
  val data = mapOf<String, Any>("x" to xs, "y" to ys)

  val fig = letsPlot(data) + geomPoint(
    color = "dark-green",
    size = 4.0
  ) { x = "x"; y = "y" }

  ggsave(fig, "plot.png")
}

Command:

mvn clean dependency:go-offline test-compile exec:java -Dexec.classpathScope="test" -Dexec.mainClass="abc.TestFileKt"

Java version locally:

openjdk 17.0.8 2023-07-18
OpenJDK Runtime Environment Homebrew (build 17.0.8+0)
OpenJDK 64-Bit Server VM Homebrew (build 17.0.8+0, mixed mode, sharing)
alshan commented 1 year ago

Hi, upgrading to LP v3.2.0 and LPK v4.4.1 would be a good start :)

To the point, in addition to your existing dependencies, try to add the "org.jetbrains.lets-plot:lets-plot-batik" dependency as shown here.

vkupar commented 1 year ago

@alshan Thanks for your quick response.

This is what I'm getting after adding lets-plot-batik.

javax.xml.parsers.FactoryConfigurationError: Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found
    at javax.xml.parsers.SAXParserFactory.newInstance (Unknown Source)
    at org.apache.batik.dom.util.SAXDocumentFactory.<clinit> (SAXDocumentFactory.java:401)
    at org.apache.batik.transcoder.SVGAbstractTranscoder.createDocumentFactory (SVGAbstractTranscoder.java:152)
    at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode (XMLAbstractTranscoder.java:108)
    at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode (SVGAbstractTranscoder.java:158)
    at jetbrains.datalore.plot.PlotImageExport.buildImageFromRawSpecs (PlotImageExport.kt:117)
    at org.jetbrains.letsPlot.export.GgsaveKt.exportRasterImage (ggsave.kt:127)
    at org.jetbrains.letsPlot.export.GgsaveKt.ggsave (ggsave.kt:92)
    at org.jetbrains.letsPlot.export.GgsaveKt.ggsave$default (ggsave.kt:45)
    at ml.RunManualInspectionPipelineKt.main (runManualInspectionPipeline.kt:66)
    at ml.RunManualInspectionPipelineKt.main (runManualInspectionPipeline.kt)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
    at java.lang.Thread.run (Thread.java:1623)

My updated pom.xml:

<dependency>
  <groupId>org.jetbrains.lets-plot</groupId>
  <artifactId>lets-plot-kotlin-jvm</artifactId>
  <version>4.4.1</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.jetbrains.lets-plot</groupId>
  <artifactId>lets-plot-batik</artifactId>
  <version>3.2.0</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.jetbrains.lets-plot</groupId>
  <artifactId>lets-plot-image-export</artifactId>
  <version>3.2.0</version>
  <scope>test</scope>
</dependency>
alshan commented 1 year ago

Is this command line or IDEA Run?

vkupar commented 1 year ago

@alshan It works well when I run it from IntelliJ IDEA. The error comes from command line and Github Actions.

alshan commented 1 year ago

I've checked the actual classpath in the export_to_file.ipynb demo notebook. I've found the following Batik-related entries:

/Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-transcoder/1.16/batik-transcoder-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-anim/1.16/batik-anim-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-css/1.16/batik-css-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-ext/1.16/batik-ext-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-parser/1.16/batik-parser-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-svg-dom/1.16/batik-svg-dom-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-awt-util/1.16/batik-awt-util-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/xmlgraphics-commons/2.7/xmlgraphics-commons-2.7.jar /Users/Igor/.m2/repository/commons-io/commons-io/1.3.1/commons-io-1.3.1.jar /Users/Igor/.m2/repository/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-bridge/1.16/batik-bridge-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-script/1.16/batik-script-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-dom/1.16/batik-dom-1.16.jar /Users/Igor/.m2/repository/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-gvt/1.16/batik-gvt-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-shared-resources/1.16/batik-shared-resources-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-svggen/1.16/batik-svggen-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-util/1.16/batik-util-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-constants/1.16/batik-constants-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-i18n/1.16/batik-i18n-1.16.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-xml/1.16/batik-xml-1.16.jar /Users/Igor/.m2/repository/xml-apis/xml-apis-ext/1.3.04/xml-apis-ext-1.3.04.jar /Users/Igor/.m2/repository/org/apache/xmlgraphics/batik-codec/1.16/batik-codec-1.16.jar


Could you compare with yours?


Could you also check your environment variables? My concern is that you might have something like

javax.xml.parsers.SAXParserFactory = org.apache.xerces.jaxp.SAXParserFactoryImp

in your environment.

The thing is that JetBrainsRuntime seems to have "SAXParserFactoryImpl", otherwise it's not on the classpath.

vkupar commented 1 year ago

@alshan I found what was the problem.

I had this plugin in pom.xml:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>3.1.0</version>
</plugin>

I changed the version to 1.6.0 and I'm not getting this error anymore: An exception occurred while executing the Java class. Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found.

Now it works as expected. If in the future anyone had this issue, now you know how to solve it 🙌