1

I want to build a fat jar for tesseract. With the following build settings I get a jar of about 68 MB with dependencies for all supported platforms:

dependencies {
    implementation group: 'org.bytedeco', name: 'tesseract-platform', version: '4.1.1-1.5.3'
}
jar {
    manifest { attributes 'Main-Class': 'BasicExample' }
    from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
}

In order to reduce this size, I tried to only include the dependencies for my platform following this guideline - but without success, see also this SO question and @Samuel Audet's answer to it (I want to stick with gradle). Therefore I decided to manually include only the required dependencies from the POM file:

dependencies {
    implementation group: 'org.bytedeco', name: 'tesseract', version: '4.1.1-1.5.3'
    implementation group: 'org.bytedeco', name: 'tesseract', version: '4.1.1-1.5.3', classifier: 'windows-x86_64'
    implementation group: 'org.bytedeco', name: 'leptonica', version: '1.79.0-1.5.3', classifier: 'windows-x86_64'
}

This reduces the size of the jar to about 7 MB and works fine (at least for the basic example). Nevertheless I get warnings:

Warning: Could not load ...: java.lang.UnsatisfiedLinkError: no jnijavacpp in java.library.path: ...

Comparing the two jars I found that the small jar lacks the lib path with all the so libs along with header, cmake and pkgconfig files and I assume that this is the reason for the warnings.

So my questions are:

  1. If these files are apparently not necessary to run the jar, why are they included normally?
  2. How can I prevent these warnings while keeping the jar size small?

Any other way to build a jar with just the required dependencies for one platform is of course also welcomed.

Stef
  • 28,728
  • 2
  • 24
  • 52

1 Answers1

3

I'll have to update that guide a little bit, thanks for reporting! We now also need javacpp-platform, which would give us something like this for windows-x86_64 in this case:

dependencies {
    implementation group: 'org.bytedeco', name: 'tesseract', version: '4.1.1-1.5.3'
    implementation group: 'org.bytedeco', name: 'tesseract', version: '4.1.1-1.5.3', classifier: 'windows-x86_64'
    implementation group: 'org.bytedeco', name: 'leptonica', version: '1.79.0-1.5.3', classifier: 'windows-x86_64'
    implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.3', classifier: 'windows-x86_64'
}

This is needed to fix some issues at load time as explained in this issue:
https://github.com/bytedeco/javacv/issues/1305

UPDATE: It's now possible to use Gradle JavaCPP to do this more easily this way:

plugins {
    id 'java-library'
    id 'org.bytedeco.gradle-javacpp-platform' version "$javacppVersion"
}

// We can set this on the command line too this way: -PjavacppPlatform=linux-x86_64,macosx-x86_64,windows-x86_64,etc
ext {
    javacppPlatform = 'linux-x86_64,macosx-x86_64,windows-x86_64,etc' // defaults to Loader.getPlatform()
}

dependencies {
    api "org.bytedeco:tesseract-platform:$tesseractVersion"
}
Samuel Audet
  • 4,964
  • 1
  • 26
  • 33
  • 1
    Thank you so much. Now I see that this is clearly explained in https://github.com/bytedeco/javacpp/issues/393. Although I searched the issues I didn't find this, my bad. – Stef May 15 '20 at 16:02