Menu

FATAL ERROR: Class net/sf/sevenzipjbinding/IInStream not found

Help
2020-04-22
2020-04-27
  • Silas De Munck

    Silas De Munck - 2020-04-22

    Hello,

    I'm trying to create an encrypted 7z archive. Everything works fine with the build from me IDE (eclipse). However, when I build a jar, with sevenzipjbinding incluced, I get the following error:

    FATAL ERROR: Class net/sf/sevenzipjbinding/IInStream not found
    Crash jvm to get a stack trace

    I'm using a RandomAccessFileInStream for reading the files from the filesystem and put them in the archive.

    When I run the jar with -verbose, I see that it is sucessfully loading other classes from the same jar:
    [Loaded net.sf.sevenzipjbinding.IOutItemBase from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.impl.OutItemFactory from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.IOutItem7z from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.IOutItemZip from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.IOutItemBZip2 from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.IOutItemGZip from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.IOutItemTar from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.IOutItemAllFormats from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.impl.OutItem from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.impl.OutItemFactory$1 from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]
    [Loaded net.sf.sevenzipjbinding.impl.RandomAccessFileInStream from jar:file:/D:/Devel/bsaf/bsaf-process/build/libs/process-0.0.4-SNAPSHOT.jar!/BOOT-INF/lib/sevenzipjbinding-16.02-2.01.jar!/]

    From my own code, I can load the IInStream.class sucessfully.

    So I wonder what is happening, and how I can investigate this furter?

    Kind Regards,
    Silas

     
  • Silas De Munck

    Silas De Munck - 2020-04-22

    The difference in execution environments is that from eclipse, the complete list of jar-dependencies is in the classpath, whereas when executing the bundled jar, it only has that in the classpath. How can I make it find the IInStream in that case?

     
  • Boris Brodski

    Boris Brodski - 2020-04-22

    Hello Silas,

    how are you creating your JAR file?

    • Eclipse export dialog?
    • Maven?
    • Gradle?
    • ...?

    This is a fat jar, right?

    Kind regards,
    Boris

     
    • Silas De Munck

      Silas De Munck - 2020-04-22

      Hello,

      It's a spring boot jar, built with gradle.

      I managed to work around it by specifying the sevenzip jars in the classpath

      java -cp
      process-0.0.4-SNAPSHOT.jar;sevenzipjbinding-16.02-2.01.jar;sevenzipjbinding-all-platforms-16.02-2.01.jar
      -Dloader.main=be.fed.minfin.bsaf.ProcessApplication
      org.springframework.boot.loader.PropertiesLauncher

      Is it possible that the classes loaded from your cpp binding code are not
      using the same classloader as the java side?

      If you need further info, or if I need to test some things, I'm happy to
      help.

      Kind regards,
      Silas

      Op wo 22 apr. 2020 om 14:39 schreef Boris Brodski boris_brodski@users.sourceforge.net:

      Hello Silas,

      how are you creating your JAR file?

      • Eclipse export dialog?
      • Maven?
      • Gradle?
      • ...?

      This is a fat jar, right?

      Kind regards,
      Boris


      FATAL ERROR: Class net/sf/sevenzipjbinding/IInStream not found
      https://sourceforge.net/p/sevenzipjbind/discussion/757965/thread/0c15f4aa32/?limit=25#040c


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/sevenzipjbind/discussion/757965/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
  • Boris Brodski

    Boris Brodski - 2020-04-23

    Hello,

    you are right. This looks like classloader issue to me. From JNI specification:

    Since Java 2 SDK release 1.2, when FindClass is called through the Invocation Interface, there is no current native method or its associated class loader. In that case, the result of ClassLoader.getSystemClassLoader is used. This is the class loader the virtual machine creates for applications, and is able to locate classes listed in the java.class.path property.

    (https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FindClass)

    So, if you can't load a class through "ClassLoader.getSystemClassLoader()" classloader you can't load it from native close. At least, you can't do it using FindClass().

    I suppose, I could build a more sophisticated initialization routine awared of advanced classloading.

    Is this workaround ok for you?

    Kind regards,
    Boris

     
    • Silas De Munck

      Silas De Munck - 2020-04-23

      Hello Boris,

      Thanks for your response.
      This workaround is kind of ok, but would it be possible to give a more
      sensible error or exception?
      Currently, this issue crashes the JVM, and I saw in your source code that
      you do that to get a stacktrace from the jvm? However, here it only crashes
      with that text "Crash jvm to get a stack trace" and then the process exits.
      Would be nice to have an exception, or initialization check, or callback to
      handle this properly from the java side?

      Kind regards,
      Silas

      Op do 23 apr. 2020 om 09:41 schreef Boris Brodski boris_brodski@users.sourceforge.net:

      Hello,

      you are right. This looks like classloader issue to me. From JNI
      specification:

      Since Java 2 SDK release 1.2, when FindClass is called through the
      Invocation Interface, there is no current native method or its associated
      class loader. In that case, the result of ClassLoader.getSystemClassLoader
      is used. This is the class loader the virtual machine creates for
      applications, and is able to locate classes listed in the java.class.path
      property.

      (
      https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FindClass
      )

      So, if you can't load a class through "ClassLoader.getSystemClassLoader()"
      classloader you can't load it from native close. At least, you can't do it
      using FindClass().

      I suppose, I could build a more sophisticated initialization routine
      awared of advanced classloading.

      Is this workaround ok for you?

      Kind regards,
      Boris


      FATAL ERROR: Class net/sf/sevenzipjbinding/IInStream not found
      https://sourceforge.net/p/sevenzipjbind/discussion/757965/thread/0c15f4aa32/?limit=25#ed45


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/sevenzipjbind/discussion/757965/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
  • Boris Brodski

    Boris Brodski - 2020-04-27

    Hello,

    you are right. A better error message is needed here. Although there are also other reasons possible.

    If no classes can be found, not crashing JVM and returning control to the java code can be very tricky. I could add an simple class loading test in the initialization routine, where detecting such errors is easier.

    Any idea how I could test it in a simple way and without using spring?

    (I could implement my own classloader, but may be you are aware of some existing simple implementations)

    Thank you!

    Kind regards,
    Boris

     
    • Silas De Munck

      Silas De Munck - 2020-04-27

      Hello Boris,

      I think you can just use an URLClassloader (to load the sevenzip jars), set
      it as the context classloader from the current thread and then let it load
      SevenZip things from another class afterwards?
      Just make sure your classes are not on the system classloader classpath?
      That should trigger the crash without spring? If you want, I can try to
      come up with something as well.

      A check in the init routines would definitely be a good start to prevent
      the jvm crashing afterwards.
      Can the 'no class found' maybe trigger an exception instead?

      The better solution would be something like this:
      https://stackoverflow.com/questions/13263340/findclass-from-any-thread-in-android-jni

      -> Let the user set (or initialize from the initialization routines) a
      custom classloader.
      Getting the classloader from the current (Java) thread would not be
      possible I suppose.

      This is of course a lot of work from your side. Strange thing is that this
      is not supported by JNI out of the box ;-)

      Kind regards,
      Silas

      Op ma 27 apr. 2020 om 10:07 schreef Boris Brodski boris_brodski@users.sourceforge.net:

      Hello,

      you are right. A better error message is needed here. Although there are
      also other reasons possible.

      If no classes can be found, not crashing JVM and returning control to the
      java code can be very tricky. I could add an simple class loading test in
      the initialization routine, where detecting such errors is easier.

      Any idea how I could test it in a simple way and without using spring?

      (I could implement my own classloader, but may be you are aware of some
      existing simple implementations)

      Thank you!

      Kind regards,
      Boris


      FATAL ERROR: Class net/sf/sevenzipjbinding/IInStream not found
      https://sourceforge.net/p/sevenzipjbind/discussion/757965/thread/0c15f4aa32/?limit=25#5543


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/sevenzipjbind/discussion/757965/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

Log in to post a comment.