css4j / echosvg

SVG implementation in the Java™ Language, fork of Apache Batik, supporting level 4 selectors and colors.
Apache License 2.0
39 stars 2 forks source link

Build size, options, documentation #106

Closed rschmunk closed 2 months ago

rschmunk commented 2 months ago

The overall README describes some possibilities for different builds, with example gradle specifications. But not what I need, alas.

The problem I have is that the only option described that produces a jar that I immediately find useful is the "uber jar" or fat jar. And unfortunately it is 8 MB in size. By comparison the Batik "all" jar is about 4 MB.

My use case is that I would like a single jar that I can add to my product classpath, for a couple applications that users have said that they would like SVG output (in addition to the already provided PS or PDF). The Batik 4 MB jar seemed like bloat compared to my app sizes, but then I encountered Echo's uber jar.

So is there a way to produce a smaller Echo jar, rather than try to figure out which pieces and parts I need from the multiple-module build? It would be even better if as a Gradle build option I could specify "just give me the modules I need for writing an SVG file to disk, but in a single jar".

carlosame commented 2 months ago

The problem I have is that the only option described that produces a jar that I immediately find useful is the "uber jar" or fat jar. And unfortunately it is 8 MB in size. By comparison the Batik "all" jar is about 4 MB.

The uber jar is larger because it includes all the dependencies. You'll also need those dependencies if you use Batik, so the situation is similar.

EchoSVG, including the css4j engine and all its dependencies, is 4.52MB compressed. But you also need the org.w3c packages, the various Apache dependencies like xmlgraphics-commons, Mozilla Rhino for the Javascript, etc. Which sums 7.66MB.

A fat jar with Batik would be a bit smaller because the CSS engine is much simpler, but would be like 7.5MB anyway.

So is there a way to produce a smaller Echo jar, rather than try to figure out which pieces and parts I need from the multiple-module build? It would be even better if as a Gradle build option I could specify "just give me the modules I need for writing an SVG file to disk, but in a single jar".

Which build tool are you using? If you only need some echosvg module and its dependencies (from your description it isn't clear which module you need), your build tool should be able to do that. From a quick Google search:

1) Creating a Fat Jar in Gradle. 2) with Maven you have the Shade plugin and others, see https://www.baeldung.com/executable-jar-with-maven

Tailoring the build of downstream applications is something that should be done at downstream level, not in EchoSVG's build.

rschmunk commented 2 months ago

@carlosame, I'm building using the sample gradle commands from the shell. The simple "./gradlew uberjar" command is what's resulting in an 8 MB jar when I do so.

If I go to the Batik website and download their built release, the included "batik-all-1.17.jar" is 4 MB. I can slot that jar right in with one of my apps and be able to write out an SVG document to disk using the same Graphics2D calls that the app uses for rendering in the UI on-screen.

carlosame commented 2 months ago

So you are using the svggen module. I just added the ability to create fat jars for individual modules, it is now explained in the README as well as the wiki.

So if you execute:

./gradlew echosvg-svggen-jar-with-deps

you obtain echosvg-svggen/build/libs/echosvg-svggen-1.1-SNAPSHOT-with-deps.jar which is what you want (and it is only 1.7MB).

rschmunk commented 2 months ago

@carlosame, I found that just the echosvg-svggen-1.1-SNAPSHOT-with-deps.jar was not enough to write an SVG file to disk as a GenericDOMImplementation object is required to construct a SVGGraphics2D. That meant adding echosvg-dom to the classpath, and it needed to be the with-deps jar.

Also, for cases where my need to write SVG output with a bitmap embedded, then it was necessary to replace echosvg-svggen with echosvg-svgrasterizer---width-deps. Which is a hefty 7 MB.

carlosame commented 2 months ago

@carlosame, I found that just the echosvg-svggen-1.1-SNAPSHOT-with-deps.jar was not enough to write an SVG file to disk as a GenericDOMImplementation object is required to construct a SVGGraphics2D. That meant adding echosvg-dom to the classpath, and it needed to be the with-deps jar.

Are you sure? AFAIK it can use any DOM implementation, not necessarily EchoSVG's. I mean you could use the default DOM provided by the JDK (haven't tested that though).

BTW if you prefer to use a SVGOM or any other DOM, that's up to you to add it to the classpath. That's why I wrote that this should be handled by the build process of your (downstream) application and not by EchoSVG's.

Also, for cases where my need to write SVG output with a bitmap embedded, then it was necessary to replace echosvg-svggen with echosvg-svgrasterizer---width-deps. Which is a hefty 7 MB.

As explained in my first reply, the dependencies of EchoSVG are essentially the same as Batik's (except for the CSS engine and its dependencies). In fact you save a couple of Batik dependencies that this project does not need. You may be fine without Rhino, xmlgraphics-commons, etc., but your users could be a keystroke away from a ClassNotFoundException.

I'm moving this to Discussions, as little more can be done by the EchoSVG build system.