square / wire

gRPC and protocol buffers for Android, Kotlin, Swift and Java.
https://square.github.io/wire/
Apache License 2.0
4.25k stars 570 forks source link

java.io.FileNotFoundException: /opt/app.jar!/BOOT-INF/lib/spring-boot-3.1.2.jar #3118

Open HelloRayDeng opened 1 month ago

HelloRayDeng commented 1 month ago

Hi, I got an exception when using SchemaLoader to load a proto file.

  1. Here is the detailed exception stack trace:
java.io.FileNotFoundException: /opt/app.jar!/BOOT-INF/lib/spring-boot-3.1.2.jar (No such file or directory)
        at java.base/java.io.RandomAccessFile.open0(Native Method) ~[na:na]
        at java.base/java.io.RandomAccessFile.open(RandomAccessFile.java:344) ~[na:na]
        at java.base/java.io.RandomAccessFile.<init>(RandomAccessFile.java:259) ~[na:na]
        at java.base/java.io.RandomAccessFile.<init>(RandomAccessFile.java:213) ~[na:na]
        at okio.JvmSystemFileSystem.openReadOnly(JvmSystemFileSystem.kt:83) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.internal.ZipFilesKt.openZip(ZipFiles.kt:66) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.internal.ResourceFileSystem.toJarRoot(ResourceFileSystem.kt:196) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.internal.ResourceFileSystem.toClasspathRoots(ResourceFileSystem.kt:179) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.internal.ResourceFileSystem.access$toClasspathRoots(ResourceFileSystem.kt:45) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.internal.ResourceFileSystem$roots$2.invoke(ResourceFileSystem.kt:50) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.internal.ResourceFileSystem$roots$2.invoke(ResourceFileSystem.kt:50) ~[okio-jvm-3.9.0.jar!/:na]
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) ~[kotlin-stdlib-1.8.22.jar!/:1.8.22-release-407(1.8.22)]
        at okio.internal.ResourceFileSystem.getRoots(ResourceFileSystem.kt:50) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.internal.ResourceFileSystem.<init>(ResourceFileSystem.kt:54) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.internal.ResourceFileSystem.<init>(ResourceFileSystem.kt:45) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.Okio__JvmOkioKt.asResourceFileSystem(JvmOkio.kt:227) ~[okio-jvm-3.9.0.jar!/:na]
        at okio.Okio.asResourceFileSystem(Unknown Source) ~[okio-jvm-3.9.0.jar!/:na]
        at com.squareup.wire.schema.CoreLoader.resourceFileSystem_delegate$lambda$0(CoreLoader.kt:34) ~[wire-schema-jvm-5.1.0.jar!/:na]
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) ~[kotlin-stdlib-1.8.22.jar!/:1.8.22-release-407(1.8.22)]
        at com.squareup.wire.schema.CoreLoader.getResourceFileSystem(CoreLoader.kt:33) ~[wire-schema-jvm-5.1.0.jar!/:na]
        at com.squareup.wire.schema.CoreLoader.load(CoreLoader.kt:39) ~[wire-schema-jvm-5.1.0.jar!/:na]
        at com.squareup.wire.schema.internal.CommonSchemaLoader.load(CommonSchemaLoader.kt:150) ~[wire-schema-jvm-5.1.0.jar!/:na]
        at com.squareup.wire.schema.Linker.getFileLinker$wire_schema(Linker.kt:95) ~[wire-schema-jvm-5.1.0.jar!/:na]
        at com.squareup.wire.schema.Linker.link(Linker.kt:117) ~[wire-schema-jvm-5.1.0.jar!/:na]
        at com.squareup.wire.schema.internal.CommonSchemaLoader.loadSchema(CommonSchemaLoader.kt:105) ~[wire-schema-jvm-5.1.0.jar!/:na]
        at com.squareup.wire.schema.SchemaLoader.loadSchema(SchemaLoader.kt:77) ~[wire-schema-jvm-5.1.0.jar!/:na]
        at com.kernelsoft.modeling.fastgrpc.starter.services.ProtobufImportServiceImpl.loadProtoSchema(ProtobufImportServiceImpl.java:229) ~[fastgrpc-starter-1.0.0-SNAPSHOT.jar!/:na]
        at com.kernelsoft.modeling.fastgrpc.starter.services.ProtobufImportServiceImpl.getProtobufSchemaFromContent(ProtobufImportServiceImpl.java:114) ~[fastgrpc-starter-1.0.0-SNAPSHOT.jar!/:na]
        at com.kernelsoft.modeling.fastgrpc.starter.services.ProtobufImportServiceImpl.handle(ProtobufImportServiceImpl.java:75) ~[fastgrpc-starter-1.0.0-SNAPSHOT.jar!/:na]
        at com.kernelsoft.modeling.ext.components.handler.ImportFileEventHandler.handle(ImportFileEventHandler.java:76) ~[kernelsoft-modeling-ext-components-1.0.0-SNAPSHOT.jar!/:na]
        at com.kernelsoft.modeling.ext.components.editingcontext.KsEditingContextEventProcessor.handleInput(KsEditingContextEventProcessor.java:396) ~[kernelsoft-modeling-ext-components-1.0.0-SNAPSHOT.jar!/:na]
        at com.kernelsoft.modeling.ext.components.editingcontext.KsEditingContextEventProcessor.doHandle(KsEditingContextEventProcessor.java:335) ~[kernelsoft-modeling-ext-components-1.0.0-SNAPSHOT.jar!/:na]
        at com.kernelsoft.modeling.ext.components.editingcontext.KsEditingContextEventProcessor.lambda$handle$2(KsEditingContextEventProcessor.java:266) ~[kernelsoft-modeling-ext-components-1.0.0-SNAPSHOT.jar!/:na]
        at org.eclipse.sirius.components.web.concurrent.DelegatingRequestContextRunnable.run(DelegatingRequestContextRunnable.java:40) ~[sirius-components-web-2024.3.3.jar!/:2024.3.3]
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
  1. And here is my current method to load schema:
private Schema loadProtoSchema(File tempProtoDir, File tempProtoFile) {
        try {
            // Create a file system instance using okio file system
            //  FileSystem fileSystem = FileSystem.SYSTEM;
            //
            //  Create a SchemaLoader instance
            //  SchemaLoader schemaLoader = new SchemaLoader(fileSystem);

            // Use the default nio FileSystem
            java.nio.file.FileSystem fileSystem = FileSystems.getDefault();

            // Create a SchemaLoader
            SchemaLoader schemaLoader = new SchemaLoader(fileSystem);

            // Define the source path (directory containing proto files)
            List<Location> sourcePaths = Collections.singletonList(Location.get(tempProtoDir.getAbsolutePath()));

            // If a specific proto file is provided, use it as protoPaths for single proto file handling
            List<Location> protoPaths = tempProtoFile != null
                    ? Collections.singletonList(Location.get(tempProtoFile.getAbsolutePath()))
                    : Collections.emptyList();

            // Initialize the SchemaLoader with source paths and proto paths
            schemaLoader.initRoots(sourcePaths, protoPaths);

            // Load and return the schema
            return schemaLoader.loadSchema();
        } catch (Exception exception) {
            log.error("Error loading proto schema", exception);
            return null;
        }
}

I have tried two constructors of SchemaLoader which use ikio filesystem and nio filesystem respectively. This error occurred but in both ways.

  1. Here is my working scenario: My application is a maven based spring boot project, which will be packaged into a jar file by deployment. While debugging in workspace there was no problem to load schema of proto files. Only after deployment when running through the jar file, this error occurred. I am using Wire 5.1.0 version, here is pom dependencies:
    <dependency>
        <groupId>com.squareup.wire</groupId>
        <artifactId>wire-runtime</artifactId>
        <version>5.1.0</version>
    </dependency>
    <dependency>
        <groupId>com.squareup.wire</groupId>
        <artifactId>wire-schema-jvm</artifactId>
        <version>5.1.0</version>
    </dependency>
    <!-- Kotlin dependencies -->
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-reflect</artifactId>
        <version>2.0.0</version>
    </dependency>

    I didn't find a way to solve it. Can someone please help me to address this problem? Thanks.

oldergod commented 1 month ago

I have not much knowledge about Spring. Can you open the file /opt/app.jar or up to /opt/app.jar!/BOOT-INF/lib/spring-boot-3.1.2.jar using vanilla Java after deployment?

HelloRayDeng commented 1 month ago

Yes, I can open the packaged jar file and the spring-boot-3.1.2.jar is indeed located inside the app.jar in /BOOT-INF/lib/. But at runtime it kept giving me this error message.

oldergod commented 1 month ago

Since you can open it with vanilla Java, can you spot a difference somewhere in what's happening? Wire delegates to Okio itself delegating to Java APIs java.io.RandomAccessFile. I'm curious as to what's difference if you can open it with JAVA APIs after deployment. What APIs does it work with?