Open CristianPi opened 1 year ago
Sounds like it's just not getting bundled in dist.jar for some reason? Someone's going to need to figure out why Spring Boot doesn't want to bundle that file...
@saudet it's strange, because that file exists.. the jar is like 1.5GB /BOOT-INF/lib/
So it must be a spring problem?
Maybe related to this spring issue
Sprint Boot does override the default JAR handler as you saw per https://github.com/spring-projects/spring-boot/issues/14011. So I guess this means we can't call JarURLConnection.getJarFile() on nested jar files. Hum, how should we be getting the name of the JAR file? @wilkinsona
Actually, we should be able to get the name from JarURLConnection.getJarFileURL(), but then JavaCPP also needs to list the entries in the file. I don't see an equivalent to JarFile.entries() that doesn't require JarFile... I'm starting to think that this is the same kind of issue as with jlink, GraalVM Native Image, and OSGi that offer no standard way to list resources, see https://github.com/bytedeco/javacpp/issues/506#issuecomment-883796393. If Spring Boot offers some way to list resources though, we can integrate that into JavaCPP. Contributions are welcome!
I'm not sure that I fully understand what the Loader
code intends to do. Hopefully the following will show how to find a particular "directory" on the classpath (from within a jar or nested jar) and then list all of its entries:
package com.example.demo;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class JarContentsApplication {
public static void main(String[] args) throws IOException {
String location = "org/bytedeco/cpython/linux-x86_64/";
URL classResource = JarContentsApplication.class.getClassLoader().getResource(location);
URLConnection connection = classResource.openConnection();
JarFile jarFile = ((JarURLConnection)connection).getJarFile();
String name = jarFile.getName().substring(jarFile.getName().lastIndexOf("/") + 1);
System.out.println(name);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().startsWith(location)) {
System.out.println(" " + entry.getName());
}
}
}
}
Here's a zip of a complete application containing the above code. ./gradlew bootRun
will run the application with cpython-3.10.8-1.5.8-linux-x86_64.jar
directly on the classpath as a file on the filesystem. ./gradlew bootJar
will produce an executable jar file with cpython-3.10.8-1.5.8-linux-x86_64.jar
nested within. You can run the application using java -jar build/libs/jar-contents-0.0.1-SNAPSHOT.jar
. You should see the same output for each run, i.e. the code works irrespective of the structure of the classpath.
This should be fixed with pull https://github.com/bytedeco/javacpp/pull/685.
@CristianPi Please give it a try with the snapshots: http://bytedeco.org/builds/
Thanks @huazai023!!
Spring boot 3.0.2 app. build with spring-boot-maven-plugin.
stack
I imagine this is a config problem, as it works locally without building the jar.
Any direction?