I'm working on a java project that uses both Jogl and JInput, and I working in IntelliJ. I'm having some issues with the application not being able to find various DLLs. I know the recommended way is to extract the DLLs to a folder and then point the java.library.path at that folder. Is there a way to include those libraries in project configuration somehow? I'm pulling those files from jCenter, and I'd rather just point the jar files and let JNA do its work.
I use this method below to set the path dynamically just before the DLL is needed by some object. It is called as follows:
setDllLibraryPath("C:/yourPathToDLLs")
Method to set library path
public static void setDllLibraryPath(String resourceStr) {
try {
System.setProperty("java.library.path", resourceStr);
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);//next time path is accessed, the new path will be imported
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
Related
I am trying to fix this exception: Cannot load 64-bit SWT libraries on 32-bit JVM
My project is maven based and I declared both dependencies (SWT 32 bit and SWT 64 bit) in the pom.xml file.
I am trying to dynamically load the correct JAR based on the Java architecture data model (sun.arch.data.model property) using the following function:
private static synchronized void loadLibrary(File jar) {
try {
URLClassLoader loader = (URLClassLoader) ClassLoader.getSystemClassLoader();
URL url = jar.toURI().toURL();
for (URL it : Arrays.asList(loader.getURLs())) {
if (it.equals(url)) {
return;
}
}
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
method.invoke(loader, new Object[]{url});
} catch (Exception e) {
System.out.println("error");
}
}
The problem is that I don't know how to specify the path to the JAR. I see the JAR is downloaded in the .m2 folder but I guess that I can't specify that path. My guess is that I should specify the path to the Java cache were JNLP will download the JARs. Am I correct?
I would create separate 32-bit and 64-bit versions of your artifact. This can be achieved by wrapping the swt dependencies into profiles (you could call them 32bit and 64bit) and then activate the suitable profile. You can then produce two artifacts of different name or version (or classifier).
I solved the problem by doing this: I have downloaded the 32 and 64 bit jars and put them in the resource folder of my project (/swt/swt_x86.jar and /swt/swt_x86_64.jar). Then, in the places where I needed the jar I used the function mentioned in the subject to load it based on the Java architecture.
I'm trying to use Tesseract OCR in a web application. The code runs fine when I run it as a JAVA application. But as soon as I put the same code in my web application, it doesn't work anymore. If put the function in the servlet, tomcat doesnt start at all. If I call it from a separate class by creating an object, On debugging I find that the object does not get created at all. I have included all the jars necessary.
Code in servlet
OCRFullTrial ot = new OCRFullTrial();
ot.imgOCR();
Inside other class
public void imgOCR(){
File imageFile = new File("D:\\OCRTesting\\0.jpg");
try {
ITesseract instance = new Tesseract(); //
System.out.println("1");
} catch (Exception e) {
System.err.println(e.getMessage());
}
Just some pointers I think you should check, in case if you are using Tess4j in Web Based Project:
1) Put all your jars in WEB-INF > lib folder.
2) The *.dll files that are provided along Tess4j must be in system32 folder (Windows). I don't know for other OS.
3) Set the instance path using instance.setDataPath() method. It must point to folder containing tessdata folder.
4) Set the language using instance.setLanguage() incase your tessdata has multiple languages training data in them.
Crosscheck above steps and try running again. Hope it works
I'm having this problem where none of the resources load when I run a JAR of the program. I've changed code and checked that it is indeed both the code that loads images and the code that loads sounds do not work. It works perfectly fine when I run it in eclipse. I checked with 7-Zip and the sounds and images files aren't in a res folder anymore. I tried changing the path files and the location of the resources in my program before I exported it, but that didn't work. I also have the res folder as a source folder in the build path. I'm exporting the JAR with eclipse, and then adding my libraries into it with JarSplicer. Here are the codes that load images and sound resources:
-Load Sound-
public static WaveData LoadSound(String path){
WaveData sound = null;
try {
sound = WaveData.create(new BufferedInputStream(new FileInputStream(path)));
} catch (Exception e) {
e.printStackTrace();
}
return sound;
}
-Load Images-
public static Texture LoadTexture(String path, String fileType){
Texture tex = null;
InputStream in = ResourceLoader.getResourceAsStream(path);
try{
tex = TextureLoader.getTexture(fileType,in);
}catch(IOException e){
e.printStackTrace();
}
return tex;
}
Here's my error in the command prompt:
Here are the files in the jar every time I exported it (regardless of whether the resources were in res or not):
I'm stumped here. If someone knows how to fix this, then please help me out.
I found the answer to my problem.
ResourseLoader.getResourceStreamAs() does not work inside of JAR files, so you need to do getClass().getResourceStreamAs(), or [ClassName].class.getResourceStreamAs(), if it's static.
Also, I had to change the location of the files from res/[resource file]/[resource] to /[resource file]/[resource] because when you export, it takes out all of the files in res. Also, you have to make sure that you have that / at the beginning of the path there in order to designate it to search in the source folder, or else it will search in the folder of the class that called getResourceStreamAs(). And also, new FileInputStream() doesn't work in JAR files, so you have to use [ClassName].class.getResourceStreamAs() instead. Oh, and on top of that, I had a few files that somehow got the extension part its name in all capitals for no reason. So that gave me some confusion. I basically just had to do a bunch of fiddling with code, but I got it working!
One more thing: make sure you add your resources folder to the sources tab in the build path, or else eclipse won't export it. And if you want your libraries to be exported in your JAR, then you'll have to add them manually by making a fat jar with JarSplicer.
Turns out that paths to resources are case sensitive and do not work in jar files if there is a single misstyped letter in the path.
I am attempting to deploy a swing application that uses a dll to facilitate a database connection (using sqljdbc4 jar that depends on sqljdbc_auth.dll). My deployment strategy is creating an executable jar file. The problem is that I cannot get the functions that rely on the sqljdbc_auth.dll to work in the executable jar I create.
I can get the project working fine in eclipse by using any of the following methods:
Reference the folder containing the dll in the build path configuration by specifying a Native library location on the Source folder
Put the dll in C:\Windows\System32 directory
Add the following VM argument referencing the relative path of the dll folder in my project "-Djava.library.path=path/to/dllfolder"
The 4th method I have tried is to load the dll directly in code via the following line. System.load("C:/Users/Me/Desktop/sqljdbc_auth.dll");
I have been unsuccessful with this approach and get the following error.
Mar 20, 2015 4:18:44 PM com.microsoft.sqlserver.jdbc.AuthenticationJNI <clinit>
WARNING: Failed to load the sqljdbc_auth.dll cause : no sqljdbc_auth in java.library.path
However, that error doesn't come directly from the line of code that loads the library, it seems to come afterwards when the sqljdbc library is trying to load the dll for use in making the connection.
Either way, I cannot get anything of the above methods working when I deploy the app as an executable jar file via the export functionality of eclipse. The only thing I can get is the previously mentioned error message.
The following sample application produces the same result.
public class TestApp {
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JFrame mainFrame = new JFrame();
mainFrame.setSize(300,300);
mainFrame.setLocationRelativeTo(null);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
try{
//System.load("C:/Users/Me/Desktop/sqljdbc_auth.dll");
String serverName = "local";
String databaseName = "test_database";
String connString = "jdbc:sqlserver://" + serverName + "; databaseName=" + databaseName + ";integratedSecurity=true";
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection(connString);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("select distinct name from test_table");
rs.next();
JOptionPane.showMessageDialog(null, "From db: " + rs.getString(1), "Test", JOptionPane.INFORMATION_MESSAGE);
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e.getMessage(), "Test", JOptionPane.INFORMATION_MESSAGE);
} catch (ClassNotFoundException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e.getMessage(), "Test", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e){
e.printStackTrace();
JOptionPane.showMessageDialog(null, e.getMessage(), "Test", JOptionPane.INFORMATION_MESSAGE);
}
}
});
}
}
I've read tons of posts on using dlls with executable jars and they all seem to reference using this System.load method. Ironically, that is the one thing I can't get working. I know I have the right dll; however, because I can get other methods to work in the IDE environment. I don't care if the dll is packaged with the executable jar or not, I just want it to work!
I would presume this has something to do with putting the dll's in your library
(In Eclipse, Properties->Java Build Path->Libraries).
When you export the jar, you also will have the option of exporting the library files into a folder.
If you decompile the Jar after that, you'll notice that there's a manifest file, and in it, paths to where your library files are (based on the export, which created a library folder for you, generally jarname_lib).
When you export, you have the option to save as ANT file, which you can then edit to change the export location of the library files to a folder name of your choice. You can then add this edited ANT file to your build so that it happens whenever you build the project:
(In Eclipse, Properties->Builders->New)
I have an application which uses one native library "libSample.so" which is depend upon another .so file.I am trying to load that library using following code
File File1 = new File("libSample.so");
static
{
try {
System.load(File1.getAbsolutePath());
} catch (UnsatisfiedLinkError e) {
System.out.println("Link Error");
}
}
Before loading library I have tried setting up LD_LIBRARY_PATH where the library is located using command line.
export LD_LIBRARY_PATH=/home/usb:${LD_LIBRARY_PATH}
But still the library not get load.
What should I do now?
Please help.
static {
System.loadLibrary("libSample.so");
}
I assumed that you have your jars in /libs directory and .so file in /libs/armeabi directory so the system finds them. You do not have to add .so files in your eclipse build path.