tensorflow / java

Java bindings for TensorFlow
Apache License 2.0
823 stars 201 forks source link

Caused by: java.lang.ClassNotFoundException: org.tensorflow.ndarray.NdArray #273

Open micosacak opened 3 years ago

micosacak commented 3 years ago

The maven project that I have works fine if run it as Java Application. It does not raise error if I build it eclipse. This a FiJi plugin. As a result, if I copy paste jar file into "FiJi/plugins" or use "install plugins" I still do not have any problem. However, when I choose the plugin, it raises the following error.

In brief, I have models (tensorflow) trained using Python. Then, I load the models in tensorflow/java (0.3.1) . As I wrote above I do not have any problem (if I run the project as Java Application) loading the models and predicting images using tensorflow/java.

I am using windows, but I have the same problem if I run it on Linux as well.


(Fiji Is Just) ImageJ 2.0.0-rc-69/1.53c; Java 1.8.0_172 [64-bit]; Windows 8.1 6.3; 69MB of 12155MB (<1%)

java.lang.NoClassDefFoundError: org/tensorflow/ndarray/NdArray
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
    at java.lang.Class.getConstructor0(Class.java:3075)
    at java.lang.Class.newInstance(Class.java:412)
    at org.scijava.plugin.PluginInfo.createInstance(PluginInfo.java:304)
    at org.scijava.command.CommandInfo.createInstance(CommandInfo.java:247)
    at org.scijava.command.CommandModule.instantiateCommand(CommandModule.java:248)
    at org.scijava.command.CommandModule.<init>(CommandModule.java:98)
    at org.scijava.command.CommandInfo.createModule(CommandInfo.java:325)
    at org.scijava.module.DefaultModuleService.createModule(DefaultModuleService.java:167)
    at org.scijava.module.DefaultModuleService.run(DefaultModuleService.java:206)
    at org.scijava.module.DefaultModuleService.run(DefaultModuleService.java:197)
    at org.scijava.module.DefaultModuleService.run(DefaultModuleService.java:182)
    at net.imagej.legacy.LegacyService.runLegacyCompatibleCommand(LegacyService.java:304)
    at net.imagej.legacy.DefaultLegacyHooks.interceptRunPlugIn(DefaultLegacyHooks.java:163)
    at ij.IJ.runPlugIn(IJ.java)
    at ij.Executer.runCommand(Executer.java:150)
    at ij.Executer.run(Executer.java:68)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.tensorflow.ndarray.NdArray
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 19 more
Craigacp commented 3 years ago

What jars are you copying in? It looks like it's not got any of the dependent jars, so you probably need to build an uberjar, or copy in all the dependencies.

micosacak commented 3 years ago

I did not build as uberjar. I am trying to learn how to do it now. Thanks.

micosacak commented 3 years ago

I converted it uberjar and still get exactly the same problem. I copy pasted mypackage-uberjar.jar file into Plugins and still have the same problem.

I added the folowing insrc/assembly/uberjar.xml file:

<assembly>
  <id>uberjar</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>true</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>false</unpack>
      <scope>runtime</scope>
      <useProjectArtifact>true</useProjectArtifact>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <directory>${project.build.outputDirectory}</directory>
      <outputDirectory>/</outputDirectory>
    </fileSet>
  </fileSets>
</assembly>

and the following in pom.xml in <build><plugins> ... <plugins> </build>


<plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>single</goal>
              </goals>
            </execution>
          </executions>

          <configuration>
            <includes>
            <include>org.tensorflow-core-platform</include>
            <version>0.3.1</version>
            <include>net.imagej</include>
            <include>org.scijava.*</include>
            <include>net.imglib2.*</include>
            <include>java.awt.*</include>
            <include>java.io.*</include>
            <include>java.util.*</include>
            </includes>
            <descriptors> 
              <descriptor>src/assembly/uberjar.xml</descriptor>
            </descriptors>
            <archive>
              <manifest>
                <mainClass>org.mic.imagej.qZeBRAIN</mainClass>
                <addClasspath>true</addClasspath>
              </manifest>
            </archive>
          </configuration>

        </plugin>
Craigacp commented 3 years ago

I don't think that's going to include the right dependencies. It doesn't mention ndarray or tensorflow-core-api. Why don't you use Maven's dependency resolution to figure out the set of necessary jars?

For example in Tribuo we build uberjars like this https://github.com/oracle/tribuo/blob/ba1bd30fd4d1cc96206bf7f4c306bcecfcdaa93a/Classification/SGD/pom.xml#L74

micosacak commented 3 years ago

I have 2 problems here; if I use the jar file jar-with-dependencies I cannot find my plugin in FiJi plugins. If use uberjar.jar file, I can see my plugin in FiJi plugins but this time it raises the same error.

Based on the file sizes I can say that uberjar and jar-wit-dependencies have dependencies.

I also posted my question here

Craigacp commented 3 years ago

Presumably there's a service descriptor in the uberjar which isn't present in the with deps jar. Try listing the contents of each one to figure out what's missing. They are just zip files you could merge them if necessary.

micosacak commented 3 years ago

I realized that jar-with-dependencies actually does not have all jar files required and the files inside are all folders as below. However, uberjar has many jar files that are dependecy required. The problem is if I use this uberjar in fiji it raises the same error.

I do not know where else to ask to get more help except here and SO.

thanks.

for jar-with-dependencies

04/07/2021  10:04    <DIR>          .
04/07/2021  10:04    <DIR>          ..
03/17/2016  12:55    <DIR>          assets
02/05/2016  17:16    <DIR>          bsh
01/19/2016  13:29    <DIR>          clojure
02/18/2017  22:51    <DIR>          com
12/05/2016  11:04               207 compiler.properties
09/17/2016  17:34    <DIR>          data
04/07/2021  09:46    <DIR>          de
11/25/2015  21:45    <DIR>          edu
09/17/2016  17:34    <DIR>          examples
12/13/2014  17:09    <DIR>          fr
06/03/2012  21:37    <DIR>          gnu
05/28/2019  16:38    <DIR>          google
01/10/2017  18:57    <DIR>          groovy
01/10/2017  18:57    <DIR>          groovyjarjarantlr
01/10/2017  18:57    <DIR>          groovyjarjarasm
01/10/2017  18:57    <DIR>          groovyjarjarcommonscli
05/09/2014  07:21    <DIR>          groovyx
08/01/2008  10:12    <DIR>          hidden
12/22/2018  20:44    <DIR>          icons
12/05/2016  11:04               207 interactive.properties
10/16/2018  16:09    <DIR>          io
06/17/2013  11:53    <DIR>          Jama
08/17/2017  12:57    <DIR>          jitk
05/30/2017  14:05    <DIR>          jni
04/20/2018  13:24    <DIR>          jnr
04/20/2018  13:24    <DIR>          jruby
05/09/2011  15:00    <DIR>          jsr166y
12/19/2018  12:32    <DIR>          Lib
12/05/2016  11:04               207 library.properties
12/19/2018  12:32            19,442 LICENSE
04/15/2015  13:32            16,780 LICENSE.txt
08/01/2008  10:12    <DIR>          licenses
03/13/2019  19:30    <DIR>          luts
04/07/2021  09:46    <DIR>          META-INF
11/16/2018  19:08               169 module-info.class
12/13/2014  17:09                34 module.properties
12/28/2018  15:51    <DIR>          net
09/26/2011  21:08           481,937 netlib-java-0.9.3-sources.jar
12/26/2013  21:10    <DIR>          org
01/10/2017  18:56             2,204 overview.html
01/10/2017  18:56             2,191 overviewj.html
12/05/2016  11:04               207 reflect.properties
12/05/2016  11:09               207 repl-jline.properties
12/05/2016  11:04               207 repl.properties
11/17/2016  02:45                40 rootdoc.txt
12/05/2016  11:10    <DIR>          scala
07/20/2016  14:33               120 scala-asm.properties
12/05/2016  11:04               497 scala-buildcharacter.properties
11/01/2016  10:20               112 scala-xml.properties
12/05/2016  11:04               207 scaladoc.properties
04/30/2017  14:13    <DIR>          script_templates
01/25/2018  14:48    <DIR>          tables
08/01/2013  16:00    <DIR>          ucar
              18 File(s)        524,975 bytes
              37 Dir(s)  241,894,510,592 bytes free

and for uberjar.jar there are too many jar file. I show the last ones which include jar files for tensorflow as well.

04/01/2021  09:16             4,616 modulator-1.0.jar
04/01/2021  09:16           246,777 multiverse-core-0.7.0.jar
04/01/2021  09:16            32,927 nailgun-server-0.9.1.jar
04/01/2021  09:14           229,132 ndarray-0.3.1.jar
04/01/2021  09:16           604,886 netlib-java-0.9.3-renjin-patched-2.jar
04/01/2021  09:16            25,501 object-inspector-0.1.jar
04/01/2021  09:13         1,763,194 ojalgo-45.1.1.jar
04/01/2021  09:16            14,188 options-1.4.jar
04/01/2021  09:13            44,517 parsington-1.0.4.jar
04/01/2021  09:16           250,546 plexus-utils-1.5.6.jar
04/01/2021  09:13           118,147 prettytime-4.0.1.Final.jar
04/01/2021  09:14         1,634,485 protobuf-java-3.8.0.jar
04/01/2021  09:16            25,429 regexp-1.3.jar
04/01/2021  09:16            23,134 renjin-appl-0.8.1906.jar
04/01/2021  09:16         3,211,680 renjin-core-0.8.1906.jar
04/01/2021  09:16            85,644 renjin-gnur-runtime-0.8.1906.jar
04/01/2021  09:16            17,452 renjin-script-engine-0.8.1906.jar
04/01/2021  09:17         1,188,593 rhino-1.7.6.jar
04/01/2021  09:16         1,155,639 rsyntaxtextarea-2.6.1.jar
04/01/2021  09:16         9,807,458 scala-compiler-2.12.1.jar
04/01/2021  09:16         5,272,325 scala-library-2.12.1.jar
04/01/2021  09:16         3,538,697 scala-reflect-2.12.1.jar
04/01/2021  09:16           547,860 scala-xml_2.12-1.0.6.jar
04/01/2021  09:13         1,034,927 scifio-0.37.3.jar
04/01/2021  09:13         1,007,491 scifio-jai-imageio-1.1.1.jar
04/01/2021  09:14           893,921 scijava-common-2.77.0.jar
04/01/2021  09:16            23,508 scijava-plugins-commands-0.2.3.jar
04/01/2021  09:16             9,431 scijava-plugins-platforms-0.3.1.jar
04/01/2021  09:16             4,362 scijava-plugins-text-markdown-0.1.3.jar
04/01/2021  09:16             4,301 scijava-plugins-text-plain-0.1.3.jar
04/01/2021  09:13            79,350 scijava-search-0.6.0.jar
04/01/2021  09:13            56,524 scijava-table-0.4.0.jar
04/01/2021  09:16            48,873 scijava-ui-awt-0.1.6.jar
04/01/2021  09:16           187,837 scijava-ui-swing-0.12.0.jar
04/01/2021  09:16           202,296 script-editor-0.5.0.jar
04/01/2021  09:16            12,063 scripting-beanshell-0.3.3.jar
04/01/2021  09:16             9,331 scripting-clojure-0.1.6.jar
04/01/2021  09:16            15,933 scripting-groovy-0.2.7.jar
04/01/2021  09:16            18,936 scripting-java-0.4.1.jar
04/01/2021  09:13             7,746 scripting-javascript-0.4.4.jar
04/01/2021  09:16             8,369 scripting-jruby-0.3.0.jar
04/01/2021  09:16             5,758 scripting-jython-0.4.2.jar
04/01/2021  09:16             7,212 scripting-renjin-0.2.2.jar
04/01/2021  09:16             7,082 scripting-scala-0.2.1.jar
04/01/2021  09:16           759,376 stats-0.8.1906.jar
04/01/2021  09:16             8,607 swing-checkbox-tree-1.0.2.jar
04/01/2021  09:14        62,309,419 tensorflow-core-api-0.3.1-linux-x86_64.jar
04/01/2021  09:14        74,368,558 tensorflow-core-api-0.3.1-macosx-x86_64.jar
04/01/2021  09:14        33,743,167 tensorflow-core-api-0.3.1-windows-x86_64.jar
04/01/2021  09:14         5,985,295 tensorflow-core-api-0.3.1.jar
04/01/2021  09:13             2,373 tensorflow-core-platform-0.3.1.jar
04/01/2021  09:13         2,523,218 trove4j-3.0.3.jar
04/01/2021  09:13           126,892 udunits-4.3.18.jar
04/01/2021  09:16             3,329 unsafe-fences-1.0.jar
04/01/2021  09:16           394,440 utils-0.8.1906.jar
04/01/2021  09:13            94,027 VectorGraphics2D-0.13.jar
04/01/2021  09:13           266,705 xchart-3.5.4.jar
04/01/2021  09:16               935 xerbla-0.8.jar
04/01/2021  09:16            94,672 xz-1.0.jar
             157 File(s)    318,987,051 bytes
               4 Dir(s)  241,892,950,016 bytes free
Craigacp commented 3 years ago

So I'd guess that the with-dependencies jar has clobbered the META-INF/json/org.scijava.plugin.Plugin file which is supposed to contain all the plugins inside a jar and is read on ImageJ startup. You can fix this by manually merging them, or appending the files during with-dependencies jar construction. I've done this before with a similar issue when using Apache Lucene, but it's a pain to specify.

It looks like Imagej doesn't really recommend single jar deployment (https://imagej.net/Uber-JAR) probably because it's tricky given their service discovery model. In which case run mvn dependencies:build-classpath and then copy all the jars it lists into wherever you're deploying and put them on your classpath. Note I think by default that build-classpath command will build a classpath that includes any test time dependencies which you might not need in a real deployment, so you should exclude those.