Unsatisfied link error inside intellij - java

I am using JNI (Java-Native-Interface) to acess some code that was written in c++. Everything works fine when I run the code from the command line but when I add the code to my Intellij project (class, header-file and dll) it gives the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\Robin\Desktop\egdb_example\end.dll: Can't find dependent libraries
My Java Code looks like this :
public class EndGame {
public static native void openDataBase(int maxPieces, int buffer);
public static native void test();
public static native int lookUp(int condition, int BP, int WP, int K, int color);
public static native void close();
static {
System.load("C:\\Users\\Robin\\Desktop\\egdb_example\\end.dll");
}
public static void main(String[] args) {
System.out.println("Kleiner Test");
openDataBase(8, 2000);
int value = lookUp(0, 0, 0, 0, 0);
close();
}
}
I checked whether the path is actually correct running this piece of code
File test = new File("C:\\Users\\Robin\\Desktop\\egdb_example");
for (File file : test.listFiles()){
System.out.println(file.getName());
}
which produces the outcome:
.git
.gitattributes
.gitignore
egdb.h
egdb.lib
egdb64.dll
egdb64.lib
egdb_example.cpp
egdb_example.vcxproj
egdb_example.vcxproj.filters
end.dll
EndGame.class
EndGame.h
EndGame.java
jni.h
jni_md.h
main.cpp
Readme.pdf
robin.cpp
robin.exe
Would appreciate any help

Take a look here to see how to setup IntelliJ and CLion to debug code.
http://jnicookbook.owsiak.org/recipe-No-D002/
If you don't use CLion, simply skip that part and take a look solely at IntelliJ configuration.

Related

Error in the webapp while connecting with JVM using jni4net from C#

I'm trying to access a simple java code from inside my C# webapp using jni4net, but it is throwing some errors.
Generated all proxies and dlls to access the java class.
I wrote the code for connecting with JVM inside the 'Program.cs' file.
Later on the custom java function ie. display_msg() is called from the testfunc() which can be called from anywhere inside the bot using Program.testfunc().
I'm attaching the Program.cs file and the exception occurring.
Also I've named my java file as Test.java and it's inside package mypack.
Program.cs
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using net.sf.jni4net;
using System;
using mypack;
namespace ValidationBot
{
public class Program
{
public static void Main(string[] args)
{
var setup = new BridgeSetup();
setup.Verbose = true;
setup.AddAllJarsClassPath("./");
Bridge.CreateJVM(setup);
Bridge.RegisterAssembly(typeof(Test).Assembly);
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging((logging) =>
{
logging.AddDebug();
logging.AddConsole();
}).UseStartup<Startup>();
public static void testfunc()
{
Test test = new Test();
test.display_msg();
Console.WriteLine("\nPress any key to quit.");
Console.ReadKey();
}
}
}
Test.java
package mypack;
import java.io.*;
public class Test
{
public static void main(String args[])
{
int s =10;
System.out.println(s);
}
public void display_msg()
{
System.out.println("Hello, I'm inside a java program");
}
}
Exception
Exception thrown: 'System.MissingMethodException' in jni4net.n-0.8.8.0.dll
Exception thrown: 'System.Reflection.TargetInvocationException' in System.Private.CoreLib.dll
Exception thrown: 'System.TypeInitializationException' in jni4net.n-0.8.8.0.dll
An unhandled exception of type 'System.TypeInitializationException' occurred in jni4net.n-0.8.8.0.dll
The type initializer for 'net.sf.jni4net.utils.Registry' threw an exception.
I'm a beginner to C# so please help me out with this.
From the comments we deduced that .NET core 2.1 does not support this method: (and maybe others)
System.Reflection.Emit.AssemblyBuilder System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess)

How to provide java program with external files when executing the run command in console?

So it might seem like a trivial question, but I cannot find any information out there that answers my question. Nonetheless, it is a very general coding question.
Suppose you have a java program that reads a file and creates a data structure based on the information provided by the file. So you do:
javac javaprogram.java
java javaprogram
Easy enough, but what I want to do here is to provide the program with a file specified in the command line, like this:
javac javaprogram.java
java javaprogram -file
What code do I have to write to conclude this very concern?
Thanks.
One of the best command-line utility libraries for Java out there is JCommander.
A trivial implementation based on your thread description would be:
public class javaprogram {
#Parameter(names={"-file"})
String filePath;
public static void main(String[] args) {
// instantiate your main class
javaprogram program = new javaprogram();
// intialize JCommander and parse input arguments
JCommander.newBuilder().addObject(program).build().parse(args);
// use your file path which is now accessible through the 'filePath' field
}
}
You should make sure that the library jar is available under your classpath when compiling the javaprogram.java class file.
Otherwise, in case you don't need an utility around you program argument, you may keep the program entry simple enough reading the file path as a raw program argument:
public class javaprogram {
private static final String FILE_SWITCH = "-file";
public static void main(String[] args) {
if ((args.length == 2) && (FILE_SWITCH.equals(args[0]))) {
final String filePath = args[1];
// use your file path which is now accessible through the 'filePath' local variable
}
}
}
The easiest way to do it is using -D, so if you have some file, you could call
java -Dmy.file=file.txt javaprogram
And inside you program you could read it with System.getProperty("my.file").
public class Main {
public static void main(String[] args) {
String filename = System.getProperty("my.file");
if (filename == null) {
System.exit(-1); // Or wharever you want
}
// Read and process your file
}
}
Or you could use third a party tool like picocli
import java.io.File;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
#Command(name = "Sample", header = "%n#|green Sample demo|#")
public class Sample implements Runnable {
#Option(names = {"-f", "--file"}, required = true, description = "Filename")
private File file;
#Override
public void run() {
System.out.printf("Loading %s%n", file.getAbsolutePath());
}
public static void main(String[] args) {
CommandLine.run(new Sample(), System.err, args);
}
}
You can pass file path as argument in two ways:
1)
public class Main {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("File path plz");
return;
}
System.out.println("File path: " + args[0]);
}
}
2) Use JCommander
Let's go step by step. First you need to pass the file path to your program.
Lets say you execute your program like this:
java javaprogram /foo/bar/file.txt
Strings that come after "javaprogram" will be passed as arguments to your program. This is the reason behind the syntax of the main method:
public static void main(String[] args) {
//args is the array that would store all the values passed when executing your program
String filePath = args[0]; //filePath will contain /foo/bar/file.txt
}
Now that you were able to get a the file path and name from the command-line, you need to open and read your file.
Take a look at File class and FileInputStream class.
https://www.mkyong.com/java/how-to-read-file-in-java-fileinputstream/
That should get you started.
Good luck!

Compile .java file with external dependecy into .class file

I have the following External.java file that has an external dependency on JAsioHost.jar file placed in folderWhereMyJarIs:
package external;
import com.synthbot.jasiohost.*;
public class External {
public External(){
System.out.println("Class CONSTRUCTOR");
}
public int operateAdd(int a, int b){
int res = a+b;
return res;
}
public static void main(String[] args) {
System.out.println("Hello world");
}
}
I am having trouble compiling the .java file into .class file from my Windows command line because when I type
javac -cp .;/folderWhereMyJarIs/JAsioHost.jar External.java
it gives me the following error:
package com.synthbot.jasiohost does not exist
What am I doing wrong?
As suggested by #shadowsheep in his helpful comment, I answer my own question posting the solution that works just fine:
javac -cp .;./folderWhereMyJarIs/JAsioHost.jar External.java
Hope this will help others

How to get path to class file in eclipse and linux in java?

In eclipse for windows, when I run
public class HelloWorld {
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir"));
}
}
It gives me the path of the project root folder (which contains the bin folder which has the class file). For example
SampleProject
and the class file is actually located at
SampleProject\bin\myclass.class
But if I run the same program in linux with
javac myclass.java
java myclass
it gives me the directory that has the .class file, which is the same as pwd command. This is what I want in eclipse for windows. I want some code that will give me the path to the class file in both eclipse for windows and linux.
Does anyone know how do this?
Thanks
If I understand you correctly, you'd like a method that retrieves a class' path on disk. This is easily achievable, like so:
public String getClassPath(Class c) {
try {
return c.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
NOTE this will work even if the class is contained in a jar file. It will return the path to the jar in this case.
The easiest way is to do this:
public class HelloWorld {
public static void main(String[] args) {
System.out.println(HelloWorld.class.getResource("HelloWorld.class"));
}
}

Runtime Error: Main method not found in class ImageTool, please define the main method as: public static void main(String[] args)

Why does my code (compiles fine) gives me the following error?
Main method not found in class ImageTool, please define the main method as: public static void main(String[] args)
Code:
public class ImageTool {
public static void main(String[] args) {
if (args.length <1) {
System.out.println("Please type in an argument");
System.exit(-1);
}
if (args[0].equals("--dump")) {
String filename = args[1];
int[][] image = readGrayscaleImage(filename);
print2DArray(image);
} else if (args[0].equals("--reflectV")) {
String filename = args[1];
int[][] image = readGrayscaleImage(filename);
int[][] reflect = reflectV(image); //reflectV method must be written
String outputFilename = args[2];
writeGrayscaleImage(outputFilename,reflect);
}
}
Your main method looks fine.
1) Probably your .class file does not correspond to your .java file.
I would try to clean up my project (if I was using an IDE and getting this).
That is: delete the .class file, regenerate it from the .java file.
2) Seems you're not running ImageFile but some other class,
even though you think you're running ImageFile. Check what
your IDE is running behind the scenes.
I hope one of these two suggestions would help.

Categories

Resources