I have been using Swig to create a Java wrapper for a a library written in C++. The wrappers get generated into a package and then jar'ed. The files are compiled correctly and work perfectly with java but I can't call it from MATLAB.
I tried adding the path to the jar in the static Java path file in MATLAB and then calling the classes in the jar file but I get the error "Undefined variable or class.." Or if I try using javaObject(...) "No class * can be located on Java class path".
I'm not sure what I am doing wrong.
EDIT:
To test calling a c++ library from MATLAB, I created a simple "data reader" class which contains a function that writes a randomly generated vector< vector<double> > to a text file and and a function that reads it.
The swig files generated are: SimpleReader.java, DoubleVector.java, exampleJNI.java, example.java, DoubleVector2.java in the package com.example.reader. These are compiled and packed into example.jar (the library dll generated is also packed into the jar).
It all works fine calling it from java so the problem must be specific to MATLAB. There is not much code for MATLAB as nothing seems to work. I get as far as
javaclasspath('c:/reader/reader.jar');
obj = com.example.reader.SimpleReader;
at which point I get 'Undefined variable "com" or class "com.example.reader.SimpleReader"'
In general you're supposed to be able to do this:
javaclasspath('/path/to/myjar.jar')
myobj = com.example.mypackage.MyObject;
myobj.someMethod(123);
I've been using this with MATLAB for quite a while now and have had no trouble. Perhaps you could post the exact MATLAB code you are using?
I get as far as
javaclasspath('c:/reader/reader.jar');
obj = com.example.reader.SimpleReader;
at which point I get 'Undefined variable "com" or class "com.example.reader.SimpleReader"'
Well, for starters, you mentioned your jarfile is called example.jar, but your MATLAB code references reader.jar -- are you sure the jar you're referencing in javaclasspath() exists? Have you tried looking at the contents of it? (e.g. with 7zip or any program that can read .zip-format files, since .jar files are just .zip-format files with additional specifications)
hmmm...
which version of MATLAB are you using?
are your classes public?
What do you get when you try typing the following:
javap -classpath c:/reader/example.jar com.example.reader.SimpleReader
You say you're using version 7.0.4 -- this is likely the problem. Earlier versions of MATLAB use an older version of the Java JRE:
MATLAB is only fully supported on the JVM that we ship with MATLAB. For example:
JVM 1.3.1 for MATLAB 6.5.1 (R13SP1)
JVM 1.4.2 for MATLAB 7.0.1 (R14SP1)
MATLAB 7.0.4 (R14SP2) and later versions till MATLAB 7.4 (R2007a) use JVM 1.5 and MATLAB 7.5 (R2007b) and later use JVM 1.6. There are components that may not work properly under a different version of the JVM.
You basically have three choices at this point.
(if possible) -- use only JAR files that are compatible with Java 5. In this case, since you're making your own library, you need to use the -target 1.5 option. (target="1.5" if you're using the ant <javac> task) This generally isn't a huge deal, since 1.6 is kind of an incremental improvement from 1.5 -- although if you're using some of the few Java 6 classes like ArrayDeque, or external libraries that depend on 1.6, you're out of luck.
use JRE 1.6 with Matlab 7.4 by changing the JVM. Not sure this is a good idea.
upgrade MATLAB to a version that runs on Java 6 (R2007b or later).
Remember this issue when you go to upgrade your Java development environment to Java 7 or Java 8.
Related
Im new to app development and was wondering if it would be possible to include another jdk. For example java 17 and run a jar that needs to be run in this exact version? I think termux has an api that you may use for these purposes but is there another possibility? These jars are only console based and without any gui.
I first tried to use the jar as a android library inside the app, which did not work since it was compiled in java version 17. I tried decompiling the jar and recompiling it with the version I was using. The problem is that all the libraries used are on other versions than I need them to be and so I could not recompile it. I also thought about writing the application in c# but I am not used to it at all, which would throw many new problems that I would be willing to take if it would be a possibility to work out my project.
Q: Is loading the code into your Android application an option?
A: No.
Android loads code from ".dex" files not ".class" files.
The ".class" files would need to be translated using dx.
The Android dx command doesn't understand Java 17 ".class" file format.
Also the code in the JAR is likely to depend on classes in the Java SE class library that the Android doesn't provide.
Q: What about running it in a separate Android VM?
A: No.
An Android VM requires ".dex" files; see above.
Also, the Java SE class library issue; see above.
Q: What about launching an OpenJDK or Oracle Java 17 JVM on the Android device to run the JAR?
A: In theory Yes, but in practice No. As far as I am aware, there is no port of OpenJDK Java SE to the Android OS platform.
Q: What about using Termux?
A: OK ... that might work. See Is it possible to install the JDK on an android device?.
I have no experience with this, and don't know what problems you may run into doing this. But I suspect that you wouldn't be able to distribute something that relies on Termux via the Google Playstore.
Another option is to download the source code1 for the application and try to build it in your Android dev environment
If the code uses Java classes / packages / libraries that are not available for Android, recode the relevant parts of the application to use Android equivalents instead.
Ditto if the code uses Java language features that are not yet supported in Android Java.
It probably won't be easy. It may turn out to be impractical.
1 - You said in a comment that the code your are trying to use is "open source". So the "download source and build it" option is available to you. I'm puzzled why you tried to decompile and recompile it instead ...
As I know, java source code is compiled into class files by the java compiler (javac.exe); then these class files are put into JVM to interpret using java.exe
But Eclipse is only using javaw.exe. So, I think javaw.exe is equivalent to javac + java
But some references say javaw.exe nearly equivalent java.exe. thus Eclipse only has the interpreter progress. Compiler process takes place where, how?
How should I understand this?
Eclipse does not compile files using javac. It has its own, independent implementation of a Java compiler, complete with its own set of error messages—and bugs.
Eclipse still needs access to all the standard library classes against which it compiles Java code.
The Java runtime which runs the Eclipse IDE process is not related to the JDK used to compile the code against. For all that matters, Eclipse could be a native application written in C++ and that wouldn't stop it from being able to compile Java.
I have a PowerMac and it is giving me bad version number on some .jars. I would love to make it seem like I am running Java 6. How would I spoof the version? Let me also say I am running PowerPC and Leopard
The most likely problem is that you have Java 6 JAR files and you are trying to run them on an old Java installation.
How would I spoof the version?
The answer to your question is that you can't. The way to run Java 6 specific JAR files it to use a Java 6 (or later) JRE or JDK.
The problem is that the format of Java class files has changed, and your installation can't cope with the new format. And this is not a gratuitous change that you can pretend doesn't exist. Java 6 (actually Java 5) has support for generic types, enums, annotations and other things. Assuming that the JARs contain code that uses these new language features, an older JRE simply won't know what to do with them.
There are two solutions:
Upgrade your Java installations to the required level on all machines. This is the best solution ... if it is an option ... because it means your users will get the benefit of security and bug fixes and performance enhancements. (And progress of your project won't be held back by the constraint of supporting legacy platforms.)
Compile all of your code for compatibility with the oldest version of Java that you still have to use. Either compile on the corresponding old JDK, or on a more recent JDK using appropriate -source / -target / -Xbootclasspath options ... as described by the javac manual page.
The catch with the second solution is that if the source code for the JAR files in question uses recently added Java language features or APIs, then recompiling for the older platform will fail. To fix this you will need to rewrite your code to replace the nice modern stuff with archaic stuff. Not a good solution, IMO.
The other possibility is that you are seeing corrupted JAR files. This is unlikely, but it can happen if you are using applets or webstart, and the server is delivering error pages instead of JAR files.
The third possibility is that you simply haven't configured your Mac's Java installation's correctly. Making Java 7 the default should allow you to run everything without class version problems. (Thanks #paulsm4) Note that I can't help you with that ... 'cos I don't use Java on a Mac.
There is Java tool (it is called Mallet)
http://mallet.cs.umass.edu/download.php
which I want to use in my .NET project.
To convert this tool to .NET library at first I've tried to build it in single .jar file using Apache Ant. I've done everything corresponding to instructions at link above.
Download Developer Release from Mercurial repository.
Download Apache Ant, install JDK, set JAVA_HOME var to use Apache Ant.
Using Ant I've built single mallet.jar file.
And then I would to convert mallet.jar to .NET library using IKVMC.
When converting, I've got a lot of warnings such as:
Warning IKVMC0108: not a class file "cc/mallet/util/tests/TestPriorityQueue$1.cl
ass", including it as resource
(class format error "51.0")
Despite of these warnings, mallet.dll was created. But when I try to reference to it from my .NET project, it looks "empty". It has not any classes or namespaces. I don't forget to reference to IKVM.OpenJDL.Core.
And this is unusual that I can't find any same problems in Google.
I think that problem is in warnings. And I have never worked with Ant and I don't understand all process exactly.
The class format version 51 was introduced with Java 7.
IKVM most likely doesn't support that version yet and the file name you quote (cc/mallet/util/tests/TestPriorityQueue$1.class) points at an anonymous inner class of TestPriorityQueue that certainly is needed for the library to work correctly.
My suggestion: compile Mallet using an older JDK or at least using the -source and -target switches set to 6 (to ensure that it's compile for Java 6).
FYI v8.1 (currently in RC) of IKVM supports Java 8:
http://weblog.ikvm.net/2015/08/26/IKVMNET81ReleaseCandidate0.aspx
http://sourceforge.net/p/ikvm/mailman/message/34502991/
I have a 3rd party JAR file that is compiled using Java 1.4. Is there a tool that can make the jar file compatible with Java 1.6? (Something like 'retrotranslator' but what does the reverse of it).
I tried decompiling the class files and re compile them in 1.6 but it fails.
Here is the issue:
My project uses 'rsadapter.jar' for was 5.1 and I had my project setup in Eclipse 2.0 + JDK 1.4 and it used to work fine. Now, I have migrated to Java 1.6 and Eclipse Ganymede (as per the requirements) and the same project (exactly same setup) started complaining about the missing class files in the 'rsadapter.jar'. I put the JAR in classpath explicitly too but it still could not load the classes. Then I changed the Java Compiler version to 1.4 and it started working.
Regards,
- Ashish
Classes compiled by JDK 1.4 should be usable in a Java 6 runtime as-is. If you have actually encountered a problem, please describe it.
Update: I can only reproduce this with types in the "default" package (that is, not in a package). Are the classes you are trying to use in the default package? Also, this happens to me regardless of the JDK version used to compile.
Update: Okay, after a little research, I realized that you can never reference a type in the unnamed package from a named package. Makes sense, but definitely not what you are running into.
I can compile code under JDK 1.4.2_19 and utilize it just fine in a Java 6 Eclipse project. I think that this problem is something specific to your environment. In this situation, I would backup Eclipse and recreate everything (JDK installation, workspace, projects) from scratch, to see if I could clear it up.
I had another issue with some legacy code written in Java 1.4.x: the authors loved enumerations and loved to name the corresponding variables 'enum'. They even used it for package names. And this prevents from compiling the code under Java 1.5 (or higher) quite successfully.
Changing that automatically is quite an issue.
May be you have defined Eclipse to throw compiler errors on use of deprecated methods or classes?