0

There's a strange issue I've never seen.

Adding a compile 'org.locationtech.spatial4j:spatial4j:0.7' to the dependencies list in my gradle project leads to a corrupt classpath. When I comment out that library and run java -verbose:class -jar sol_backend_full.jar > ok.log it outputs 4399 lines of class entries. However, with that library in classpath, java -verbose:class -jar sol_backend_full.jar > failed.log outputs only 953 lines, most of which are java.lang.* or sun.*.

It obviously results in Error: Could not find or load main class.

➥ Has anyone ever encountered that strange behaviour?


Of course, I can substitute that library with another spatial library, but what's happening is simply strange. It happens only with this library, removing/adding any other is fine.

Gradle version in question is 5.5.1, and that library manifest looks a bit long, but not suspicious at all. Falling back to 4.8 also reproduces it.

Here is the build script:

task customFatJar(type: Jar) {
    manifest {
        attributes          'Main-Class': 'ru.rxproject.sol.backend.BackendApplication',
                'Implementation-Version': version + System.getenv('BUILD_NUMBER').toString(),
                           'Commit-Hash': 'git-' + System.getenv('GIT_COMMIT'),
                            'Build-Date': java.time.LocalDateTime.now().toString()
    }
    archiveName = 'sol_backend_full.jar'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}
Xobotun
  • 1,121
  • 1
  • 18
  • 29

1 Answers1

1

The JAR dependancy org.locationtech.spatial4j:spatial4j:0.7 is a signed jar. When you create a fat jar, java Classloader is not able to load the other classes from your fat jar because these are not signed.

So, you can't create a fat jar with that dependancy without excluding the signatures.

Please refer - Gradle - FatJar - Could not find or load main class

Like mentioned in the above post, you may exclude the signatures like -

jar {
    manifest {
        attributes "Main-Class": mainClassName
    }

    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
    exclude 'META-INF/*.RSA'
    exclude 'META-INF/*.SF'
    exclude 'META-INF/*.DSA'
}

But, I would suggest to keep the jar dependancy out of the fat jar.

SKumar
  • 1,940
  • 1
  • 7
  • 12
  • I'm not sure if I follow, but you suspect `spatial4j-0.7.jar` library may have references to classes that are actually not on the classpath? Hmm, maybe it is some common api interface. I've just tried `implementation` scope, but it still breaks the startup. :/ – Xobotun Sep 05 '20 at 19:05
  • Here's the output for the failing build with the library included: https://pastebin.com/SUu8itKk. Here's the successful one, with the library import commented out: https://pastebin.com/0rP1xMDE. Second one has much more classes loaded. It feels like something has written "classpath=null" and broke the build. But I have never had such an issue. I'd gladly provide better logs, if you tell me how. :) – Xobotun Sep 05 '20 at 19:39
  • 1
    @Xobotun With the updated answer, is that issue resolved ? – SKumar Sep 06 '20 at 09:13
  • I have never heard of signed jars. Thank you for teaching me of their existence. :) Yes, I plan on moving all the dependencies out of the fat jar, but not soon. Makes sense that `java` does not want to launch my fat jar as it does not match the signatures. Thank you again, it worked like a charm! – Xobotun Sep 07 '20 at 12:39