I am running following code to create bmp image from pdf using Ghost4j
i have a commad which is executed by GhostScript generator to generate Bmp image of a page from pdf.
Code is:
package ghost;
import net.sf.ghost4j.Ghostscript;
import net.sf.ghost4j.GhostscriptException;
public class GhostDemo {
public static void main(String[] a){
Ghostscript gs = Ghostscript.getInstance(); //create gs instance
String[] gsArgs = new String[10];/*command string array*/
gsArgs[0] = "-dUseCropBox";/*use crop box*/
gsArgs[1] = "-dNOPAUSE";
gsArgs[2] = "-dBATCH";
gsArgs[3] = "-dSAFER";
gsArgs[3] = "-r300";
gsArgs[4] = "-sDEVICE=bmp16m";
gsArgs[6] = "-dTextAlphaBits=4";
gsArgs[5] = "-sOutputFile=C:/PagesWorkspace/1/masterData/1.bmp";/*bmp file location with name*/
gsArgs[6] = "C:/MasterWorkspace/pipeline.pdf";/*pdf location with name*/
try {
gs.initialize(gsArgs); /*initialise ghost interpreter*/
gs.exit();
} catch (GhostscriptException e) {
e.printStackTrace();
}
}
}
i am getting Exception
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'gsdll32': The specified module could not be found.
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:145)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:188)
at com.sun.jna.Library$Handler.<init>(Library.java:123)
at com.sun.jna.Native.loadLibrary(Native.java:255)
at com.sun.jna.Native.loadLibrary(Native.java:241)
at net.sf.ghost4j.GhostscriptLibraryLoader.loadLibrary(GhostscriptLibraryLoader.java:36)
at net.sf.ghost4j.GhostscriptLibrary.<clinit>(GhostscriptLibrary.java:32)
at net.sf.ghost4j.Ghostscript.initialize(Ghostscript.java:292)
at ghost.GhostDemo.main(GhostDemo.java:22)
Can any one tell me why i am getting this exception?
Do you have Ghostscript installed at all?
If yes, which version?
If yes, in which location?
Does it include a file gsdll32.dll?
If not, download the Ghostscript installer for Win32 and run it. After the installation, there should be a file gsdll32.dll in directory %your_install_dir%\gs\gs9.05\bin\
Pasting dll file in eclipse project made my program work!
For the SO community, another thing to check with this error is that you are using 32-bit Java. If your instance of Java is 64-bit, you will get the exact same message:
Unable to load library 'gsdll32': The specified module could not be found.
without any further explanation even if you are pointing to the correct dll.
Related
I am trying to use OpenVC and encounter an erorr that says that it is not in java.library.path. I have followed the github page for this version of OpenCV (https://github.com/openpnp/opencv) but still the probelm persisits, I tried using maven but it would still not locate the file.
I tried to use maven but the dependency would not work, I then used the inbuilt library system in IntelliJ but I am constantly getting this error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java460 in java.library.path: /Users/ranveerbehl/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2434)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:848)
at java.base/java.lang.System.loadLibrary(System.java:2015)
at Main.main(Main.java:13)
I am trying to compress video files as my previous library (IVCompressor) just plain stopped working one day and after days of troubleshooting, I was not able to fix it. Here is the code I wrote for reference:
public static void main(String[] args){
// Load the OpenCV library
nu.pattern.OpenCV.loadLocally();
System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);
// Define the input and output file paths
String inputFile = "input.mov";
String outputFile = "output.mov";
// Create a VideoCapture object to read the input video
VideoCapture capture = new VideoCapture(inputFile);
// Get the video frames per second
double fps = capture.get(Videoio.CAP_PROP_FPS);
// Get the video frame size
int frameWidth = (int) capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
int frameHeight = (int) capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
// Create a VideoWriter object to write the output video
VideoWriter writer = new VideoWriter(outputFile, VideoWriter.fourcc('M', 'P', '4', 'V'), fps, new Size(frameWidth, frameHeight));
// Read and write the video frames
Mat frame = new Mat();
while (capture.read(frame)) {
writer.write(frame);
}
// Release the resources
capture.release();
writer.release();
}
All imports are imported.
I feel the main probelm lies in these two lines of code if not with the library installation itself:
// Load the OpenCV library
nu.pattern.OpenCV.loadLocally();
System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);
OpenCV version 4.6.0.
Thank you.
I'm using Google OR-tools library (v6.4) for a project (though my question is not specific to this library). This consists of one jar, which has a few native dependencies (a bunch of ".so"/".dylib" object files, depending on the OS). This build for my project is being made on Ubuntu 14.04
The problem I'm facing: On trying to load a specific object file at runtime (using System.load()), I'm getting an UnsatisfiedLinkError with the message as "undefined symbol" (I've added the stacktrace below). However, I am loading the object file defining this symbol just before this, so I'm not sure why this error is being thrown.
I'm loading the dependencies in the following way: The object files are being packed into the jar created by Maven during build, and are being extracted and loaded (using System.load()) at runtime. The method for that is as follows:
public class EnvironmentUtils {
public static void loadResourceFromJar(String prefix, String suffix) {
String tempFilesDirectory = System.getProperty("java.io.tmpdir");
File tempFile = null;
try {
tempFile = new File(tempFilesDirectory + "/" + prefix + suffix);
tempFile.deleteOnExit();
try (final InputStream inputStream = EnvironmentUtils.class.getClassLoader().
getResourceAsStream(prefix+suffix)) {
if (inputStream == null) {
throw new RuntimeException(prefix + suffix + " was not found inside JAR.");
} else {
Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
System.load(tempFile.getAbsolutePath());
} catch (Exception e) {
//Log top 10 lines of stack trace
}
}
}
This method is being called inside a static block for all dependencies:
public class DummyClass {
static {
String sharedLibraryExtension = EnvironmentUtils.getSharedLibraryExtension(); //.so for linux, .dylib for Mac
String jniLibraryExtension = EnvironmentUtils.getJniLibraryExtension(); //.so for linux, .jnilib for Mac
EnvironmentUtils.loadResourceFromJar("libfap", sharedLibraryExtension);
EnvironmentUtils.loadResourceFromJar("libcvrptw_lib", sharedLibraryExtension);
EnvironmentUtils.loadResourceFromJar("libortools", sharedLibraryExtension);
EnvironmentUtils.loadResourceFromJar("libdimacs", sharedLibraryExtension);
EnvironmentUtils.loadResourceFromJar("libjniortools", jniLibraryExtension);
}
}
On running System.load() for libdimacs.so, an UnsatisfiedLinkError is thrown. Stacktrace:
java.lang.UnsatisfiedLinkError: /tmp/libdimacs.so: /tmp/libdimacs.so: undefined symbol: _ZN6google14FlagRegistererC1IbEEPKcS3_S3_PT_S5_
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at com.(PROJECT_NAME).utils.EnvironmentUtils.loadResourceFromJar(EnvironmentUtils.java:78)
at com.(PROJECT_NAME).DummyClass.<clinit>(DummyClass.java:28)
However, this symbol "_ZN6google14FlagRegistererC1IbEEPKcS3_S3_PT_S5_" is present in libortools.so, which is being loaded before libdimacs. I verified this by running the following command:
objdump -t (LIBRARY_PATH)/libortools.so | grep _ZN6google14FlagRegistererC1IbEEPKcS3_S3_PT_S5_
This gave me the following output:
0000000000ce12cc gw F .text 00000091 _ZN6google14FlagRegistererC1IbEEPKcS3_S3_PT_S5_
So it would seem that the symbol should have been defined at the time of the System.load() call, unless there was some issue in loading the containing object file. To check if the object file had been loaded correctly, I used the approach detailed in this solution. Apart from the class detailed in that answer, I added the following lines after System.load() call in EnvironmentUtils.loadResourceFromJar() to print the most recently loaded library name:
public class EnvironmentUtils {
public static void loadResourceFromJar(String prefix, String suffix) {
...
System.load(tempFile.getAbsolutePath());
final String[] libraries = ClassScope.getLoadedLibraries(ClassLoader.getSystemClassLoader());
System.out.println(libraries[libraries.length - 1]);
}
}
The output (till just before the UnsatisfiedLinkError) is as follows:
/tmp/libfap.so
/tmp/libcvrptw_lib.so
/tmp/libortools.so
So libortools.so seems to be loading correctly, which means the symbol should be loaded in memory. The exact same code is working perfectly with the corresponding Mac (".dylib") dependencies (Built on MacOS Sierra 10.12.5). Would appreciate any advice on resolving this. Thank you.
I'm apologize that the java artifact may be broken currently...
you can use c++filt to demangle the symbol ;)
c++filt _ZN6google14FlagRegistererC1IbEEPKcS3_S3_PT_S5_
google::FlagRegisterer::FlagRegisterer<bool>(char const*, char const*, char const*, bool*, bool*)
In fact gflag has recently change its namespace from google:: to gflags:: and glog or protobobuf? try to find the correct one and I guess it failed...
note: Still not completely sure whose is the bad guy who use the google:: namespace since libortools merge all its static dependencies but I guess now you understand the bug...
note2: I have a patch in mizux/shared branch https://github.com/google/or-tools/commit/805bc0600f4b5645114da704a0eb04a0b1058e28#diff-e8590fe6fb5044985c8bf8c9e73c0d88R114
warning: this branch is currently broken and not ready yet. I'm trying ,for unix, to move from static to dynamic dependencies, so I need to fix all rpath, transitives deps etc... and in the process I also had to fix this issue (that I didn't reproduced while using static dependencies)
If too long to finish (we should create a release 6.7.2 or 6.8 (i.e. new artifact) by the end of May 2018) which maybe only contains this fix and not my branch...
I want to use matlab function in java application. I create java package from my function by deploytool in matlab. Now, how can i use this package? Can only import the jar file created by deploytool in my java project and use its function?
After a lot of googling, I used this toturial but in the final step, i get error "could not load file".
Also i read about MatlabControl, but in this solution, we should have matlab environment in our system to java code running. But i will run my final app in systems that may not have matlab at all.
So i need a solution to run matlab function in java class even in absence of matlab environment.
Finally I solve my problem. the solution step by step is as follows:
write matlab function:
function y = makesqr(x)
y = magic(x);
Use deploytool in matlab and create java package.
3.create new java application in Eclipse and add main class. import javabuilde.jar and makesqr.jar:
import com.mathworks.toolbox.javabuilder.MWArray;
import com.mathworks.toolbox.javabuilder.MWClassID;
import com.mathworks.toolbox.javabuilder.MWNumericArray;
import makesqr.Class1;
and main.java:
public class main {
public static void main(String[] args) {
MWNumericArray n = null;
Object[] result = null;
Class1 theMagic = null;
try
{
n = new MWNumericArray(Double.valueOf(5),MWClassID.DOUBLE);
theMagic = new Class1();
result = theMagic.makesqr(1, n);
System.out.println(result[0]);
}
catch (Exception e)
{
System.out.println("Exception: " + e.toString());
}
finally
{
MWArray.disposeArray(n);
MWArray.disposeArray(result);
theMagic.dispose();
}
}
}
add javabuilder.jar and makesqr.jar to java build path of your project.
run it.
the Double.valueOf(3), define the input for our function and the output is as follows:
8 1 6
3 5 7
4 9 2
I didn't get properly your problem. Did you already compile the jar file from Matlab code and you are trying to use that, or you are at the last step of the tutorial?
If your answer is the latest case, most probably you forgot the "." before the class path.
From tutorial you linked:
You must be sure to place a dot (.) in the first position of the class path. If it not, you get a message stating that Java cannot load the class.
Also check if the matlab compiler path ("c:\Program Files\MATLAB\MATLAB Compiler Runtime\v82\toolbox\javabuilder\jar\javabuilder.jar" - in the tutorial) is correct for your system.
The code works fine when executing from Eclipse. I'm using OpenCV 2.4.11 and JavaFX for UI. When I export an Executable Jar from Eclipse and run it from cmd I get the following exception:
I followed many post here on SO and OpenCV forum(1, 2, 3, 4) but, none of the answers seems to help me.
I have added the OpenCV jar as library and Native Library is linked to /build/java/x64 as suggested in SO answers.
The exception occurs at the System.loadLibrary(Core.Native_Library_Name), I checked the Native_Library_Name and the OpenCV version is same as the one I imported in my project.
public class CustomFrame extends Application{
#Override
public void start(Stage primaryStage){
Group root = new Group();
Canvas canvas = new Canvas(1440, 840);
ImageView imageView = new ImageView();
imageView.setFitHeight(canvas.getHeight());
imageView.setFitWidth(canvas.getWidth());
new FrameController().startCamera(imageView);
root.getChildren().addAll(imageView, canvas);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args)
{
// load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
launch(args);
}
}
If anybody thinks that I have missed something please do let me know.
The UnsatisfiedLinkError is thrown when an application attempts to load a native library like
.so in Linux,
.dll on Windows or
.dylib in Mac
and that library does not exist.
Specifically, in order to find the required native library, the JVM looks in both the PATH environment variable and the java.library.path system property.
Sometimes if the native library was already loaded by an application
and the same application tries to load it again, this can cause this
error also.
How to deal with the UnsatisfiedLinkError?
First of all we must verify that the parameter passed in the System.loadLibrary method is correct and that the library actually exists. Notice that the extension of the library is not required. Thus, if your library is named SampleLibrary.dll, you must pass the SampleLibrary value as a parameter.
Moreover, in case the library is already loaded by your application and the application tries to load it again, the UnsatisfiedLinkError will be thrown by the JVM. Also, you must verify that the native library is present either in the java.library.path or in the PATH environment library of your application. If the library still cannot be found, try to provide an absolute path to the System.loadLibrary method.
In order to execute your application, use the -Djava.library.path argument, to explicitly specify the native library. For example, using the terminal (Linux or Mac) or the command prompt (Windows), execute your application by issuing the following command:
java -Djava.library.path= "<path_of_your_application>" –jar <ApplicationJAR.jar>
You have missed the actual command. Use the following
java -Djava.library.path="C:\Opencv2.1.11\opencv\build\java\x64" -jar BlurDetector.jar
or
java -Djava.library.path="C:\Opencv2.1.11\opencv\build\java" -jar BlurDetector.jar
instead of your command
java -Djava.library.path="C:\Users\vivek_elango\Desktop" -jar BlurDetector.jar // you have given wrong path of your application
It looks like you need to add the path containing the opencv-2411 native libraries to the -Djava.library.path when running from the command prompt.
So something like this:
java -Djava.library.path="C:\Opencv2.1.11\opencv\build\java\x64" -jar BlurDetector.jar
In opposite to the other answers, I rather suggest you never use absolute paths, instead use relative ones. When you give your software to another user, the user most certainly won't have the libraries in the same path as you do. By using relative paths in regards to your application you guarantee that the software runs on other users systems as well, without them having to set path variables, jvm directives and what not. They don't even have to have OpenCV installed if you give them the library dll this way.
Here's code to load the libraries in a relative way:
public static void initOpenCv() {
setLibraryPath();
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println("OpenCV loaded. Version: " + Core.VERSION);
}
private static void setLibraryPath() {
try {
System.setProperty("java.library.path", "lib/x64");
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
All you have to do is to
put the libraries into a lib/x64 folder relative to your jar file
in your application you have to invoke initOpenCv() at the start of your program
That's it. This way you can develop as before and maintain a distributable application.
Here's the full version:
import java.lang.reflect.Field;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import org.opencv.core.Core;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
initOpenCv();
HBox root = new HBox();
Label infoLabel = new Label();
infoLabel.setText("OpenCV loaded. Version: " + Core.VERSION);
root.getChildren().add(infoLabel);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void initOpenCv() {
setLibraryPath();
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println("OpenCV loaded. Version: " + Core.VERSION);
}
private static void setLibraryPath() {
try {
System.setProperty("java.library.path", "lib/x64");
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
public static void main(String[] args) {
launch(args);
}
}
With a folder structure like this:
.\application.jar
.\lib\x64\*.dll
Hint: I packaged the opencv jar into the application.jar
I am running a servlet program to read an image using opencv,
getting error :
java.lang.UnsatisfiedLinkError: Native Library C:\opencv\build\java\x64\opencv_java300.dll already loaded in another classloader . When restarting the IDE it works fine.
I loaded System.loadLibrary ( Core.NATIVE_LIBRARY_NAME ) ; in servlet only ones.
Can anybody suggest a solution for how to unload it. And also anybody know how to read an image from browser using opencv in java.?
It is because the library is not in the system path, it needs to first added to the system path, then load. First extract the OpenCV to C drive something like this c:\opencv\... then use this code below to during initializing, it will automatically load the OpenCV lib in windows environment.
public static void loadOpenCV_Lib() throws Exception {
String model = System.getProperty("sun.arch.data.model");
String libraryPath = "C:/opencv/build/java/x86/";
if(model.equals("64")) {
libraryPath = "C:/opencv/build/java/x64/";
}
System.setProperty("java.library.path", libraryPath);
Field sysPath = ClassLoader.class.getDeclaredField("sys_paths");
sysPath.setAccessible(true);
sysPath.set(null, null);
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
And also it will automatically detect the system model and load the lib according to the system model.