Java Native Interface loading dll file - java

I am trying to load a DLL file in java program. I do not get an error. However, the DLL library is not loaded. Here is the code snippet:
final class TJLoader {
static void load() {
//System.loadLibrary("#TURBOJPEG_DLL_NAME#");
String path = "C:/Eclipse2/mozpeg-master/bin";
try {
System.out.println("before loading");
//System.loadLibrary("cygjpeg-62");
System.load("C:/image_test/mozjpeg-master/.libs/cygjpeg-62.dll");
System.out.println("2");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("exception="+e);
}catch(Error e){
System.out.println("error="+e.getMessage());
}
}
}
On the console I will get "before loading". However, there is nothing printed after that and the program ends abruptly. Please note the DLL is a 62 bit library and I am using 62 bit JVM

Failure in DLL Loading actually produce java errors. Native errors are produced when you try to invoke a native method. I got java error like "Library not found" when my program failed to load the DLL. You should make sure that your DLL is a 64-bit build and also,try to avoid Cygwin. I used Visual studio to build the DLL and it works fine.Also keep in mind to take the release version instead of the debug version.

Related

Compiling JD2XX for Raspberry Pi

For Openhab2 there is a binding add-on called RFXCOM. The problem however is that this add-on uses JD2XX which is not compatible with the ARM architecture of the Raspberry Pi.
I have found a Github repository with the source that you can use to compile a *.so file: https://github.com/0x6a77/JD2XX
A little change to the Makefile to use the correct Java path (zulu-8-armhf-embedded instead of (oracle-7).
Running sudo make jni creates a *.so file which I copied to /usr/lib (inside the java library path). However I still get the error that the Raspberry Pi can't open the shared library due to it being 32-bit. How can you compile a shared library that works for ARM with the source provided by the Github repository.
Error message:
java.lang.UnsatisfiedLinkError:
/var/lib/openhab2/tmp/libjd2xx5892592723514582617.so:
/var/lib/openhab2/tmp/libjd2xx5892592723514582617.so: cannot open shared object file:
No such file or directory (Possible cause: can't load IA 32-bit .so on a ARM-bit platform)
The Raspberry Pi has a fresh installation of Openhabian.
Link to the issue on Github: https://github.com/openhab/openhab2-addons/issues/2316#issuecomment-304795652
EDIT:
11:00:52.291 [ERROR] [rnal.discovery.RFXComBridgeDiscovery] - Error occurred during discovery
java.io.IOException: device not found (2)
at jd2xx.JD2XX.listDevices(Native Method)
at jd2xx.JD2XX.listDevicesByDescription(JD2XX.java:785)
at org.openhab.binding.rfxcom.internal.discovery.RFXComBridgeDiscovery.discoverRfxcom(RFXComBridgeDiscovery.java:89)
at org.openhab.binding.rfxcom.internal.discovery.RFXComBridgeDiscovery.startScan(RFXComBridgeDiscovery.java:66)
at org.eclipse.smarthome.config.discovery.AbstractDiscoveryService.startScan(AbstractDiscoveryService.java:199)
at org.eclipse.smarthome.config.discovery.internal.DiscoveryServiceRegistryImpl.startScan(DiscoveryServiceRegistryImpl.java:382)
at org.eclipse.smarthome.config.discovery.internal.DiscoveryServiceRegistryImpl.startScans(DiscoveryServiceRegistryImpl.java:358)
at org.eclipse.smarthome.config.discovery.internal.DiscoveryServiceRegistryImpl.startScan(DiscoveryServiceRegistryImpl.java:216)
at org.eclipse.smarthome.io.rest.core.discovery.DiscoveryResource.scan(DiscoveryResource.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_121]
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)[157:org.glassfish.jersey.core.jersey-common:2.22.2]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)[157:org.glassfish.jersey.core.jersey-common:2.22.2]
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)[157:org.glassfish.jersey.core.jersey-common:2.22.2]
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)[157:org.glassfish.jersey.core.jersey-common:2.22.2]
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)[157:org.glassfish.jersey.core.jersey-common:2.22.2]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)[157:org.glassfish.jersey.core.jersey-common:2.22.2]
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)[158:org.glassfish.jersey.core.jersey-server:2.22.2]
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)[155:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)[155:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)[155:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)[155:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)[155:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
at com.eclipsesource.jaxrs.publisher.internal.ServletContainerBridge.service(ServletContainerBridge.java:76)[10:com.eclipsesource.jaxrs.publisher:5.3.1.201602281253]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)[81:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)[81:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71)[172:org.ops4j.pax.web.pax-web-jetty:4.3.0]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)[79:org.eclipse.jetty.security:9.2.19.v20160908]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:287)[172:org.ops4j.pax.web.pax-web-jetty:4.3.0]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)[81:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)[172:org.ops4j.pax.web.pax-web-jetty:4.3.0]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.Server.handle(Server.java:499)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)[80:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)[72:org.eclipse.jetty.io:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)[83:org.eclipse.jetty.util:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)[83:org.eclipse.jetty.util:9.2.19.v20160908]
at java.lang.Thread.run(Thread.java:745)[:1.8.0_121]
11:01:02.868 [WARN ] [e.sshd.server.channel.ChannelSession] - Unknown pty opcode value: 42
In the JD2XX.java file, you can see the mechanism how to load a dll, so or some other type of library depending on OS.
static {
String dataModel = System.getProperty("sun.arch.data.model");
String osName = System.getProperty("os.name").toLowerCase();;
StringBuilder lib = new StringBuilder("/jni/");
if (osName.contains("win"))
lib.append("win/");
else if (osName.contains("linux"))
lib.append("linux/");
else if (osName.contains("mac"))
lib.append("mac/");
else
throw new UnsatisfiedLinkError("Loading JD2XX JNI: Unsupported operating system ("+osName+")");
if (dataModel.equals("32"))
lib.append("x86_32/");
else if (dataModel.equals("64"))
lib.append("x86_64/");
else
throw new UnsatisfiedLinkError("Loading JD2XX JNI: Unknown runtime data model ("+dataModel+")");
if (osName.contains("win"))
lib.append("jd2xx.dll");
else if (osName.contains("linux"))
lib.append("libjd2xx.so");
else if (osName.contains("mac"))
lib.append("libjd2xx.jnilib");
try {
NativeUtils.loadLibraryFromJar(lib.toString());
} catch (IOException e) {
throw new UnsatisfiedLinkError(e.getMessage());
}
}
The loadLibraryFromJar method from NativeUtils creates temp directory and copy the right library for OS to temp directory then call the System.load method eventually.
So, I think you should modify this part of source code like the code as follows, if possible.
static
{
System.load("/var/lib/openhab2/tmp/libjd2xx5892592723514582617.so");
}
or
static
{
System.load("/usr/lib/libjd2xx5892592723514582617.so");
}
There are several ways to make this job work re-setting the 'java.library.path' order to indicate the /usr/lib directory first then use the code below.
Or you can rename the library name, libjd2xx5892592723514582617.so to libjd2xx.so in the /usr/lib which is usually in the 'LD_LIBRARY_PATH' variable.
then, our code in the JD2XX.java can be used instead,
static
{
System.loadLibrary("jd2xx");
}
I think it works..

How to call a jar file from a java program using relfection api

i have an application which parse some file which is in zip format and results some csv files.So now i have a requirement that i have to make a jar file from the application and call that jar from a java program so that it can do the same work as it is used to.So my application program have the following structure i am attaching pic of it...
I am trying to use reflection api a to do the work ,basically i am trying to load the reckoner class dynamically.In my approach i think it is loading the class,because if i misspell the class name it is giving error.But when i am writing this code and trying to run
nothing is happening.i am trying the next code..
public class Driver {
/**
* #param args
*/
public static void main(String[] args) {
try{
ClassLoader myClassLoader = ClassLoader.getSystemClassLoader();
String classNameToBeLoaded="com.gamma.Reckoner";
Class myClass = myClassLoader.loadClass(classNameToBeLoaded);
Object whatInstance = myClass.newInstance();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
so when i will make jar of it can try to call it from another program the directory structure should be there..so have made according to the actual skybin parser.Now how i will call the jar.please help me.I have to call the Reconer.java class of the skybin.jar which is the driver of the application.So using reflection can i call it
This is a possible answer, really not sure what your asking. looks like you have a jar and want to know how to run it?
How did you get that jar? Maven/ ant? IDE cliks?
Anyway from comment line:
if jar is at c:\prjs\skybin\skybin.jar
open a cmd prompt, cd to that folder
cd c:\prjs\skybin\
give command
java -cp c:\prjs\skybin\skybin.jar com.gamma.Reckoner
If Reckoner does not have a package then
java -cp c:\prjs\skybin\skybin.jar Reckoner
java should be in classpath else give full path like
c:\program files\etcjava\v77\bin\java -cp c:\prjs\skybin\skybin.jar Reckoner
This is a sample path on your computer might be different or add the java bin folder to path
Do a few tutorials on starting java and using jars
If on linux/ mac need to use / in paths and not \
To find out of your jar is made properly can un jar it.
In command prompt make a new dir
mkdir c:\prjs\tmp2
cd to that and give command
jar xf c:\prjs\skybin\skybin.jar
now check the output in explorer should see your package strcture and classes inside it, no extra folders
Per your image you should see com/gamma/mail and other folders like that
You can add your jar in your Classpath :
http://www.wikihow.com/Add-JARs-to-Project-Build-Paths-in-Eclipse-%28Java%29

Opening a TCL gui within Java code

I have a TCL file which uses Tcl's BWidget package that I've been using as a GUI for my program. I now want to be able to load up this GUI from a separate Java program. I've looked into Jacl and Swank, but they don't seem to do exactly what I want.
I've tried the following with Jacl but it's unable to evaluate the file. While debugging, I can see that it completes parsing my tcl file, but it throws an exception while parsing through the BWidget package tcl files. Here's my Java code:
Interp interp = new Interp();
try {
interp.evalFile("C:\\CTP\\Tcl\\LuxonCtp32.tcl");
} catch (TclException ex) {
int code = ex.getCompletionCode();
System.err.println("command returned bad error code: " + code);
} finally {
interp.dispose();
}
Any ideas on how I can accomplish what I want to do? Is it even possible?
Tcl itself can not display a GUI. It uses a plugin called Tk for that.
In the C reference implementation of Tcl you get Tk as well.
Tk has not been ported to Java, Tcl has.
You can not use Jacl to display Tk widgets, but TclBlend could do that, because TclBlend uses the C reference implementation of Tcl. That means that the user needs a working Tcl/Tk installation.
There are some problems with TclBlend and Tcl > 8.5 through, which result in a segfault.
IIRC you have to remove the conditional if around Tcl_FindNameOfExecutable in TclBlends C code (and compile it yourself).
Go to this site http://jtcl-project.github.io/jtcl/ and download now for the binary zip. Its a recent java tcl on github called Jtcl.
Unzip it and you will find a jar called jtcl-2.7.0.jar.
I am using Netbeans 8 my preference.
I add the jar into Project Library.
I create a java file called JTclHallo.java and this is the code.
package jtclhallo;
// import tcl.lang it belongs to jtcl-2.7.0 jar a must
import tcl.lang.*;
// Java wrapper to test JACL or JTCL.
public class JTclHallo {
public static void main(String []args) {
//Interp is a java class belonging to tcl.lang. Unrar the jtcl-2.7.0
Interp i = new Interp();
try {
//call your tcl file mine was swing.tcl from the E drive
i.eval("source E:/private/swing.tcl");
} catch (TclException e) {
System.out.println("Exception: " + e.getMessage());
}
}
}
For swing.tcl
package require java
set window [java::new javax.swing.JFrame]
$window setSize 600 400
$window setVisible true

Why do I get NoClassDefFoundError: java/awt/Desktop?

I'm trying to open an URI with Swing that I get above error.
What is the reason and how can I fix it?
When I do it in console everything is OK but when I do in GUI I get this error.
I should say that I use Weblogic as server.
Code
private static void open(URI uri) {
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().browse(uri);
} catch (IOException e) { /* TODO: error handling */ }
} else { /* TODO: error handling */ }
}
Stack trace:
Exception in thread "AWT-EventQueue-1" java.lang.NoClassDefFoundError: java/awt/Desktop
at be.azvub.ext.bcfidownloder.BcfiDownloadPanel.open(BcfiDownloadPanel.java:230)
at be.azvub.ext.bcfidownloder.BcfiDownloadPanel.access$000(BcfiDownloadPanel.java:37)
at be.azvub.ext.bcfidownloder.BcfiDownloadPanel$7.actionPerformed(BcfiDownloadPanel.java:147)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:5517)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3129)
at java.awt.Component.processEvent(Component.java:5282)
at java.awt.Container.processEvent(Container.java:1966)
at java.awt.Component.dispatchEventImpl(Component.java:3984)
at java.awt.Container.dispatchEventImpl(Container.java:2024)
at java.awt.Component.dispatchEvent(Component.java:3819)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
at java.awt.Container.dispatchEventImpl(Container.java:2010)
at java.awt.Window.dispatchEventImpl(Window.java:1791)
Doc on NoClassDefFoundError
The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.
You do have some incorrect classloading happening. Mostly due to wrong class loader chaining.
NoClassDefFoundError can only be caused by a classpath problem.
Because Desktop is part of jre, make sure that your classpath contains a reference to the jre library.
In Eclipse, you can go to run configurations --> Classpath and check there
UPDATE:
As Andrew suggested, you can also check you have at least java 1.6
java.awt.Desktop has been introduced in Java 6. Chances are high you're running your code on different JRE versions.

java.awt.Desktop.open doesn’t work with PDF files?

It looks like I cannot use Desktop.open() on PDF files regardless of location. Here's a small test program:
package com.example.bugs;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
public class DesktopOpenBug {
static public void main(String[] args)
{
try {
Desktop desktop = null;
// Before more Desktop API is used, first check
// whether the API is supported by this particular
// virtual machine (VM) on this particular host.
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
for (String path : args)
{
File file = new File(path);
System.out.println("Opening "+file);
desktop.open(file);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
If I run DesktopOpenBug with arguments c:\tmp\zz1.txt c:\tmp\zz.xml c:\tmp\ss.pdf (3 files I happen to have lying around) I get this result: (the .txt and .xml files open up fine)
Opening c:\tmp\zz1.txt
Opening c:\tmp\zz.xml
Opening c:\tmp\ss.pdf
java.io.IOException: Failed to open file:/c:/tmp/ss.pdf. Error message:
The parameter is incorrect.
at sun.awt.windows.WDesktopPeer.ShellExecute(Unknown Source)
at sun.awt.windows.WDesktopPeer.open(Unknown Source)
at java.awt.Desktop.open(Unknown Source)
at com.example.bugs.DesktopOpenBug.main(DesktopOpenBug.java:21)
What the heck is going on? I'm running WinXP, I can type "c:\tmp\ss.pdf" at the command prompt and it opens up just fine.
edit: if this is an example of Sun Java bug #6764271 please help by voting for it. What a pain. >:(
I never knew about this Desktop command, untill recently through this post:
would Java's Runtime.getRuntime().exec() run on windows 7?
Previously i have been using:
Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL "+ myfile);
And it has always worked for me. If your method does not work, may be you can think about try this command.
If you switch the order of your arugments does that cause one of the other files to get that same error. I wonder if you need to trim the end of the path before calling the File constructor.
umm...yeah ignore that... check the documentation of Desktop.open. open throws an IO exception "if the specified file has no associated application or the associated application fails to be launched " ... also from the top of the page... "The mechanism of registereing, accessing, and launching the associated application is platform-dependent. "
code for the Desktop class: http://fuseyism.com/classpath/doc/java/awt/Desktop-source.html
The open method calls DesktopPeer.open.
DesktopPeer source: http://www.jdocs.com/javase/7.b12/java/awt/peer/DesktopPeer.html
DesktopPeer is implementation specific.
Here is source for a Windows-specific implementation:
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Platform/windows/sun/awt/windows/WDesktopPeer.java.htm
open->ShellExecute->(Native)ShellExecute
Native ShellExecute is a wrapper for Win32 ShellExecute. Here is info on the function.
http://msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx
My suggestion for a work around would be to write your own implmentation of the ShellExecute function. Here is source from someone who did it. http://www.heimetli.ch/shellexec.html

Categories

Resources