Getting JNA to work under Java 1.4 - java

For reasons not germane to this question, I'm stuck with an old RHEL/CentOS 5 system with Java 1.4 (java version "1.4.2" gij (GNU libgcj) version 4.1.2 20080704 (Red Hat 4.1.2-44)). According to the JNA documentation, it's supposed to work. However the example provided is off to a rocky start since it uses a feature of Java 1.5, namely varargs (void printf(String format, Object... args)). So I figured I'd try with a simpler C library call, strerror.
package ca...cl_client;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
public class MainJNA {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
CLibrary.class);
Pointer strerror(int errno);
}
public static void main(String[] args) {
System.out.println("Hello, World");
System.out.println("err 22 : " + CLibrary.INSTANCE.strerror(22).getString(0)); //EINVAL
}
}
So I deploy jna-master.zip locally and hook it up:
$ sudo -- ln -s /home/user/Downloads/Java/jna-master/dist/jna.jar /usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre/lib/jna.jar
$ export CLASS_PATH=.:/home/user/Downloads/Java/jna-master/dist/jna.jar
This compiles fine:
$ cd ~/Java
$ javac ./ca/gc/drdc_rddc/linux/utilinux/cl_client/MainJNA.java
But it won't run:
$ java -cp $CLASS_PATH ca...cl_client.MainJNA
Hello, World
Exception in thread "main" java.lang.ClassFormatError: com.sun.jna.Library (unrecognized class file version)
at java.lang.VMClassLoader.defineClass(libgcj.so.7rh)
at java.lang.ClassLoader.defineClass(libgcj.so.7rh)
at java.security.SecureClassLoader.defineClass(libgcj.so.7rh)
at java.net.URLClassLoader.findClass(libgcj.so.7rh)
at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
at java.lang.VMClassLoader.defineClass(libgcj.so.7rh)
at java.lang.ClassLoader.defineClass(libgcj.so.7rh)
at java.security.SecureClassLoader.defineClass(libgcj.so.7rh)
at java.net.URLClassLoader.findClass(libgcj.so.7rh)
at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
at java.lang.ClassLoader.loadClass(libgcj.so.7rh)
at ca...cl_client.MainJNA.main(MainJNA.java:19)
Compiling with javac -cp $CLASS_PATH ... makes no difference.
I've tried this on both a 32-bit system and a 64-bit system (each RHEL 5.3), the error is the same.
What am I doing wrong?

1.)
I checked the official JNA library classes with the following result:
JNA 4.0.0 -> compiled with 1.6
JNA 3.5.0 -> compiled with 1.4
JNA 3.5.2 -> compiled with 1.4
And when looking exactly for that you'll find it, too:
Switch to 1.6 (In the release notes for version 4.0). Additionally there is an issue #109. So your last working version would be 3.5.2.
2.) Regarding the exotic java version you may read here. Some quotes to give you some ideas:
"gij hasn't passed the Sun compatability test, and should be
considered a separate platform for building, testing etc."
"GCJ is not equivalent to Sun's JDK or JRE, so you may find that
certain things you need aren't included in the API.
"gij is very ancient, and while I don't have references I doubt it's
reliable enough to support commercial applications."
Getting to run JNA correctly is sometimes tricky enough in a sun/oracle/open jdk - so this won't be a trivial task...

Related

Cannot compile simple "Hello World" Java application with native-image on Windows

I'm trying to compile a simple Java Hello World application to native code using the native-image utility provided by GraalVM on Windows but I always run into errors (see below).
HelloWorld.java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
First, I compile the code to a class file using the following command:
>javac HelloWorld.java
Next, I invoke the native-image command from the VS 2017 Developer Command Prompt:
>native-image -H:+ReportExceptionStackTraces HelloWorld
[helloworld:20420] classlist: 1,249.05 ms
[helloworld:20420] (cap): 704.71 ms
[helloworld:20420] setup: 997.16 ms
Error: Error compiling query code (in C:\Users\User\AppData\Local\Temp\SVM-2348968769537330415\JNIHeaderDirectives.cpp). Compiler command CL -IC:\GraalVM\include\win32 C:\Users\User\AppData\Local\Temp\SVM-2348968769537330415\JNIHeaderDirectives.cpp /FeC:\Users\User\AppData\Local\Temp\SVM-2348968769537330415\JNIHeaderDirectives.exe output included error: [Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27035 for x86, Copyright (C) Microsoft Corporation. All rights reserved., ]
com.oracle.svm.core.util.UserError$UserException: Error compiling query code (in C:\Users\User\AppData\Local\Temp\SVM-2348968769537330415\JNIHeaderDirectives.cpp). Compiler command CL -IC:\GraalVM\include\win32 C:\Users\User\AppData\Local\Temp\SVM-2348968769537330415\JNIHeaderDirectives.cpp /FeC:\Users\User\AppData\Local\Temp\SVM-2348968769537330415\JNIHeaderDirectives.exe output included error: [Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27035 for x86, Copyright (C) Microsoft Corporation. All rights reserved., ]
at com.oracle.svm.core.util.UserError.abort(UserError.java:114)
at com.oracle.svm.hosted.c.NativeLibraries.reportErrors(NativeLibraries.java:218)
at com.oracle.svm.hosted.NativeImageGenerator.processNativeLibraryImports(NativeImageGenerator.java:1518)
at com.oracle.svm.hosted.NativeImageGenerator.setupNativeLibraries(NativeImageGenerator.java:1006)
at com.oracle.svm.hosted.NativeImageGenerator.setupNativeImage(NativeImageGenerator.java:835)
at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:528)
at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:445)
at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
Error: Image build request failed with exit status 1
I also tried the Windows SDK 7.1 Command Prompt and the VS 2019 version but neither worked. How can this issue be fixed? It can't be the compiler since it works for regular C/C++ applications. Is there anything else you need to configure for this?
I managed to compile successfully using JDK 11 and the respective version of GraalVM. A visual guide for this can e.g. be found here (note: I'm the video uploader).

ACM Library simple example not working with jdk 1.7.0_79

Hi All java Experts!
When I tried a little example of acm library
import acm.program.*;
class prog extends ConsoleProgram {
public void run() {
int number = readInt("?");
println("You entered: " number);
}
}
It compiled successfully.
I used commandline like this:
javac -cp acm.jar; main.java
java -cp acm.jar; prog
But I got this error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: acm.util.DOSCommandLi
ne.getLine()Ljava/lang/String;
at acm.util.DOSCommandLine.getLine(Native Method)
at acm.util.DOSCommandLine.getCommandLine(JTFTools.java:1627)
at acm.util.JTFTools.getCommandLine(JTFTools.java:439)
at acm.util.JTFTools.getMainClass(JTFTools.java:464)
at acm.program.Program.main(Program.java:1320)
What does it mean... I think the JDK version problem.... however I am using JDK 'jdk1.7.0_79'
In my opinion It is throwing exception only for this JDK version. Request to try you and give feedback.
Thanks...
Solved!
It doesn't require any native library...
What I had to do was to Use main entry as:
public static void main(String[] args) {
new prog().start(args);
}
Adding after 'run' method it works now. Note: this line 'new prog().start(args);'
This solution found here:
http://www.dreamincode.net/forums/topic/240789-acmjar-package-problem-class-wasnt-find-in-project/
Thanks Choppy
But it took me considerable time Hushhhhh.....
UnsatisfiedLinkError at Native Method means that there is no native library (for windows it would be dll) loaded which could be called for your acm.util.DOSCommandLine.getLine() method.
With your library there should be native packages, which will contain native libraries for your system architecture. You have to put one of these into your classpath folder.

reportlab in Jython "import error"

I am using jdk 1.8 and Jython 2.7.0.jar to execute my python Code.
But It seems Jython does not support Python's 2.7 feature 'reportlab' module.
My Java Code :
package test;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Test{
public Test()
{
System.out.println("Done!");
engine.eval("import sys");
engine.eval("print sys");
engine.eval("import reportlab");
engine.eval("print reportlab");
System.out.println("Done Here");
}
catch (ScriptException ex)
{
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex);
}
}
public static void main(String args[])
{
Test t=new Test();
}
}
Error I got:
run:
Done!
<module 'sys' (built-in)>
javax.script.ScriptException: ImportError: No module named reportlab in <script> at line number 1
Dec 28, 2015 8:57:52 PM test.Test <init>
SEVERE: null
javax.script.ScriptException: ImportError: No module named reportlab in <script> at line number 1
at org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:202)
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:42)
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at test.Test.<init>(Test.java:28)
at test.Test.main(Test.java:40)
Caused by: Traceback (most recent call last):
File "<script>", line 1, in <module>
ImportError: No module named reportlab
at org.python.core.Py.ImportError(Py.java:328)
at org.python.core.imp.import_first(imp.java:877)
at org.python.core.imp.import_module_level(imp.java:972)
at org.python.core.imp.importName(imp.java:1062)
at org.python.core.ImportFunction.__call__(__builtin__.java:1280)
at org.python.core.PyObject.__call__(PyObject.java:431)
at org.python.core.__builtin__.__import__(__builtin__.java:1232)
at org.python.core.imp.importOne(imp.java:1081)
at org.python.pycode._pyx2.f$0(<script>:1)
at org.python.pycode._pyx2.call_function(<script>)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1386)
at org.python.core.__builtin__.eval(__builtin__.java:497)
at org.python.core.__builtin__.eval(__builtin__.java:501)
at org.python.util.PythonInterpreter.eval(PythonInterpreter.java:259)
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:40)
... 4 more
BUILD SUCCESSFUL (total time: 2 seconds)
If anyone could suggest me an Alternate way of remotely executing a Python script I'd be thankful to them.
Also I have a large code base in python of which rewriting in java is not feasible in scheduled time.
Jython is a completely different (and independent) Python interpreter than your system's Python. While most libraries from Python's standard library will exist in Jython, third party modules installed in your system's Python simply don't exist for the Jython version.
Jython is compatible enough that you can set a Python virtualenv with the Jython interpreter and install modules that are pure-python code (i.e. no binary modules) in that virtualenv - I don't think repotlab qualifies as such - but you might try. In a Java project setup, probably your project have its own instance of the Jython interpreter installed along other .jar files - it should feature a site-packages folder somewhere where you could try to copy pure Python third-party modules to, but again, I don't think reportlab will be jython compatible.
One option for you is to use Python itself (cPython) in an external process, and call it from Java (or Jython) using xmlrpc code - (A quickly googling didn't find me out a way to call cPython via xmlrpc from pure Java - but I know it works from Jython, if you use Python's stdlib xmlrpc as documented -
https://docs.python.org/3/library/xmlrpc.html?highlight=xmlrpc
I've got a solution on a stackExchange link - Jython embedded in Java -- ImportError: No module named yaml i.e I can simply add the packages I need under my Jython Installation directory E.g jython/Lib/site-packages I've got no Issues on reportlab for Python2.7.
most Important also append them in your program using sys.path.append()

Eclipse can't find my installed Ruby gems (JRuby)

So, I am trying to use my ruby scripts inside my java code with the help of JRuby. But there is a problem, eclipse is not being able to use the gems I have installed. For testing purposes, I've been trying to run a piece of code that requires the "nokogiri" ruby gem, which I have installed. When I try to run the java code, here's what I get:
LoadError: no such file to load -- nokogiri
require at org/jruby/RubyKernel.java:939
<top> at /home/amng/workspace/scripts/xx/x/getMSPatches:4
Exception in thread "main" org.jruby.embed.EvalFailedException: (LoadError) no such file to load -- nokogiri
at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:131)
at org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:1307)
at org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:1352)
at jobs.Teste.run(Teste.java:17)
at jobs.Teste.main(Teste.java:11)
Caused by: org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- nokogiri
at org.jruby.RubyKernel.require(org/jruby/RubyKernel.java:939)
at RUBY.(/home/amng/workspace/scripts/myPrecious/MSPatches/getMSPatches:4)
I downloaded the jruby.jar from the website and added to the build path of the project. I also pointed the eclipse to the JRuby binary using the Dynamic Languages Toolkit (DLTK) plugin. What do I have to do to make sure that eclipse can use the gems I have installed?
Edit: My java code:
import org.jruby.embed.ScriptingContainer;
import org.jruby.embed.LocalVariableBehavior;
import org.jruby.embed.PathType;
public class Main {
public static void main(String[] args) {
ScriptingContainer ruby = new ScriptingContainer(LocalVariableBehavior.PERSISTENT);
Object result = ruby.runScriptlet(PathType.ABSOLUTE, "/home/amng/workspace/scripts/myPrecious/MSPatches/getMSPatches");
System.out.println(result);
}
}
The first two lines of my (working) ruby code (getMSPatches) are:
# encoding: UTF-8
require 'nokogiri'
Try setting the jruby home directory
ScriptingContainer ruby = new ScriptingContainer(LocalVariableBehavior.PERSISTENT);
ruby.setHomeDirectory("/jruby-9.0.5.0");
This solved the issue for me.

Using JNA with IBM J9 JVM

The first difficulty in using JNA with J9 is that the J9 JVM does not include the java.awt package and the Native class imports a few classes from this package. This is easily overcome by downloading the JNA source, ripping out these imports and their dependent methods (which I am not using anyway), and building a new JNA jar.
Here is a simple test program:
public class TestJni {
public static void main(String[] args) {
CLibrary instance = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
instance.printf("Hello, World\n", new Object[] {});
}
// This is the standard, stable way of mapping, which supports extensive
// customization and mapping of Java to native types.
public interface CLibrary extends Library {
void printf(String format, Object[] args);
}
}
After correcting the java.awt problem, I receive the error:
Caused by: java.lang.UnsatisfiedLinkError: C:\DOCUME~1\TSO0112\LOCALS~1\Temp\jna72681.dll (Incompatible JNI version (not 1.1, 1.2 or 1.4))
at java.lang.ClassLoader.loadLibraryWithPath(ClassLoader.java:973)
at java.lang.System.load(System.java:459)
at com.sun.jna.Native.loadNativeLibraryFromJar(Native.java:696)
at com.sun.jna.Native.loadNativeLibrary(Native.java:620)
at com.sun.jna.Native.<clinit>(Native.java:104)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:187)
at TestJni.main(TestJni.java:8)
What does it mean by "Incompatible JNI version"? Has anybody out there got J9 to play nice with JNA?
UPDATE: I think JNA is suppressing the following NoClassDefFoundError on trying to load the java.nio.Buffer class because J9 apparently does not have the NIO package included:
JNA: Problems loading core IDs: java.nio.Buffer
Exception in thread "main" java.lang.NoClassDefFoundError: java.nio.Buffer
at java.lang.ClassLoader.loadLibraryWithPath(Native Method)
at java.lang.ClassLoader.loadLibraryWithPath(ClassLoader.java:965)
at java.lang.System.load(System.java:459)
at TestJni.main(TestJni.java:8)
I have been working with JNA on j9 for a couple of months now. I have had a few small niggles here and there but things mostly seem working fine.
First - The latest versions of JNA(3.2.7) seem to import awt. I am using 3.2.4 and the awt imports are commented out. I think that will work out of the box for you.
Second - THe version of J9 i am working with is for WinCE and it is a JVM for java 1.4. Latest JNA though is built off of java 1.5. So you might want to check which version of java your version of j9 is built on. JNA 3.2.4 is compatible with java 1.4 I believe.
You can also simply provide your own stub implementations of the java.nio/java.awt stuff and simply avoid using those features (mainly direct buffer stuff and obtaining a handle to a native window).

Categories

Resources