Is there a Java library of Unix functions? - java

I am looking for a Java library to interface with standard Unix functions, i.e. stat(), getpwuid(), readlink().
This used to exist, and was called javaunix. It was released back in 2000. See this announcement. But the project page is now gone.
Is there any modern replacement for these types of functions in Java today? One could make a system call to /bin/ls -l and parse the output, or write a custom JNI method, but these approaches are more work than simply using the old javaunix library.
Clarification -- In order to find out a file's owner, from a C program, it should call stat() which gives the UID of the owner, and then use getpwuid() to get the account's name from the UID. In Java this can be done through a custom JNI method, or the javaunix library which uses JNI.

I'm aware of two compelling projects:
posix for Java (based on JNI) [derived from Jython]
jna-posix (based on JNA) [derived from JRuby]
Personally I like very much JNA. Take a look at this example of mine, mapping link(2):
import com.sun.jna.Library;
import com.sun.jna.Native;
class Link {
private static final C c =
(C) Native.loadLibrary("c", C.class);
private static interface C extends Library {
/** see man 2 link */
public int link(String oldpath, String newpath);
}
#Override
protected void hardLink(String from, String to) {
c.link(to, from);
}
}

JNA-POSIX is stagnant currently, as far as I know.
The developers went on to create JNR-POSIX

I would be surprised to see one, considering it would almost necessarily be platform-specific. Java is not the best tool for that job. But you could certainly hook in via JNI or calls out to external programs if you insist. Or perhaps look into Groovy, which I understand is reasonably good for shell scripting, though I have no personal experience with it.

I don't know any library with the Unix functions.
for most of the functions, I believe, you can use the standard Java API to do what you want. for example, there's no need to use the command ls to read the files of some directory. but in some specific cases, like stat (to find out if a file is a link) you have to use JNI.

Related

Where are SetCommMask and WaitCommEvent in JNA? [duplicate]

I am in charge of porting Windows JNI code to Java, and have gone with JNA. Using the library is simple enough, as apparently it attempts to follow the structure and style of Windows' API (I do not know the API well, I follow the original JNI code).
I was able to find the JNA equivalent of most Windows API functions, but not EnableWindow.
This function is defined in winuser.h and logically, one should find it under com.sun.jna.platform.win32.WinUser, right? However there is no such function, and the only mention of EnableWindow is in the documentation of com.sun.jna.platform.win32.WinUser.WS_DISABLED:
[...] To change this after a window has been created, use the EnableWindow function.
That's it, no other reference, mention or indication towards the function. The rest of the documentation is equally terse and not very helpful when one does not know exactly what and where to look.
So where is JNA's EnableWindow, if it exists? And if it doesn't, what can be used in replacement?
There are two parts to JNA: the core functionality (in the jna artifact) and user-contributed platform mappings (in the jna-platform artifact). When users contribute mappings for functions and constants, they usually copy the Windows API documentation directly into the javadocs, so there are frequent references to values which have not (yet) been mapped.
As you have observed, no user has (yet) contributed a mapping for the EnableWindow function. That user could be you!
The JNA FAQ includes this tidbit:
JNA is missing function XXX in its platform library mappings
No, it's not, it's just waiting for you to add it :)
public interface MyUser32 extends User32 {
// DEFAULT_OPTIONS is critical for W32 API functions to simplify ASCII/UNICODE details
MyUser32 INSTANCE = (MyUser32)Native.load("user32", W32APIOptions.DEFAULT_OPTIONS);
void ThatFunctionYouReallyNeed();
}
That's basically the template for adding a function on your own: extend the existing library (if it's partially mapped) or create a new library if it hasn't been mapped (in which case, extend Library), then add the function you need.
WinUser is slightly different than most mappings; it doesn't include the library loading statement as it's just the header file, and in JNA, the DLL-loading library extends WinUser.
So you need to do a little bit more research to see which DLL to load to access the function natively. The docs indicate it's the user32.dll, just like the JNA FAQ example!
So the template is above, you just need the function mapping. Windows BOOL maps to Java's boolean so you just need to do this in your own codebase:
public interface MyUser32 extends User32 {
MyUser32 INSTANCE = (MyUser32) Native.load("user32", W32APIOptions.DEFAULT_OPTIONS);
boolean EnableWindow(HWND hWnd, boolean bEnable);
}
That will solve your immediate needs in your own project.
JNA is a user-maintained project. Please consider contributing your mapping to JNA so the next person can use your mapping and won't need to create it themselves!

JNA does not have a function from the Windows API

I am in charge of porting Windows JNI code to Java, and have gone with JNA. Using the library is simple enough, as apparently it attempts to follow the structure and style of Windows' API (I do not know the API well, I follow the original JNI code).
I was able to find the JNA equivalent of most Windows API functions, but not EnableWindow.
This function is defined in winuser.h and logically, one should find it under com.sun.jna.platform.win32.WinUser, right? However there is no such function, and the only mention of EnableWindow is in the documentation of com.sun.jna.platform.win32.WinUser.WS_DISABLED:
[...] To change this after a window has been created, use the EnableWindow function.
That's it, no other reference, mention or indication towards the function. The rest of the documentation is equally terse and not very helpful when one does not know exactly what and where to look.
So where is JNA's EnableWindow, if it exists? And if it doesn't, what can be used in replacement?
There are two parts to JNA: the core functionality (in the jna artifact) and user-contributed platform mappings (in the jna-platform artifact). When users contribute mappings for functions and constants, they usually copy the Windows API documentation directly into the javadocs, so there are frequent references to values which have not (yet) been mapped.
As you have observed, no user has (yet) contributed a mapping for the EnableWindow function. That user could be you!
The JNA FAQ includes this tidbit:
JNA is missing function XXX in its platform library mappings
No, it's not, it's just waiting for you to add it :)
public interface MyUser32 extends User32 {
// DEFAULT_OPTIONS is critical for W32 API functions to simplify ASCII/UNICODE details
MyUser32 INSTANCE = (MyUser32)Native.load("user32", W32APIOptions.DEFAULT_OPTIONS);
void ThatFunctionYouReallyNeed();
}
That's basically the template for adding a function on your own: extend the existing library (if it's partially mapped) or create a new library if it hasn't been mapped (in which case, extend Library), then add the function you need.
WinUser is slightly different than most mappings; it doesn't include the library loading statement as it's just the header file, and in JNA, the DLL-loading library extends WinUser.
So you need to do a little bit more research to see which DLL to load to access the function natively. The docs indicate it's the user32.dll, just like the JNA FAQ example!
So the template is above, you just need the function mapping. Windows BOOL maps to Java's boolean so you just need to do this in your own codebase:
public interface MyUser32 extends User32 {
MyUser32 INSTANCE = (MyUser32) Native.load("user32", W32APIOptions.DEFAULT_OPTIONS);
boolean EnableWindow(HWND hWnd, boolean bEnable);
}
That will solve your immediate needs in your own project.
JNA is a user-maintained project. Please consider contributing your mapping to JNA so the next person can use your mapping and won't need to create it themselves!

Running a piece of C code stored in a Java String

I am having a rather interesting scenario here. Let's say I have a piece of C code stored in a Java String. I need to run this code inside my Java program it self.
Case 1
class Main{
public static void main(String[] args) {
String cCode = "printf(\"Hello World\n\");"
// I need to run the cCode here.
// We are allowed to call a method with params.
}
}
What I think I should do is.
Create a native field in the Main
write the sCode to a file
Exceulte shell commands from Java to compile the c code.
invoke the native method from java
Case 2
I am thinking of doing the above procedure because I know how to do this with JNI if the source code is pre-defined.
class Main{
static {
System.loadLibrary("Main"); // Load native library at runtime
}
private native void sayHello();
public static void main(String[] args) {
new Main().sayHello();
}
}
In the case of pre-written C code. What we do is.
Compile the java class with javac Main.java
Generate the header for C lib. javah -jni Main
Complete the Main.c by writing the C code
Compile the C code with gcc -share -I/path/to/jni -I/path/to/jni_md -o Main.so
Run Main. java Main
Can anyone tell me whether I am taking the correct path (in Case 1) or not? or is there is a better way to do it?
** Note: The key point here is, I am allowed to compile the java code only once. (At the beginning).**
EDIT: After checking the comments and answer from #Dúthomhas I think I should explain one more thing. The reason why I am doing this for a machine learning project. It has been decided that the numeric computation part has a bottleneck and using C as the above-mentioned method is worth the risk of trying it. So security is off the book right now. We just need to do this as an experiment.
Non-answer answer: Don’t do that.
What you are asking to do is a pretty bad idea for several reasons, the two major ones are:
It potentially opens (serious) security holes
Cost to implement likely outweighs the benefit
Asking to embed an entirely different language means adding and linking a library and a lot of code to synchronize the library, plus code to perform static analysis and sandbox the code. In other words, you are asking to implement an entire language on top of what you already have.
It could be argued that C is the base system anyway, upon which the JVM may even be implemented (usually is), but that is not the point. The issue is not the C library, it is the C compiler/interpreter, which is a fairly complex code base as far as simple interpreted programming languages go.
Suggestion: Use Java
The ToolProvider class is specifically designed to provide you with dynamic compilation of Java code. Take a look through it.
Make sure to use the SecurityManager class to properly sandbox the code. (And, if possible, run it in a separate, restricted JVM.)
Suggestion: Use JavaScript/ECMAScript
The ScriptEngine classes are designed exactly for this. Again, Google around for examples. And, again, don’t forget security.
Suggestion: Use an existing library
FScript
Scheme
Tcl
Python
But I really want/must use C
Alas. It is possible to use C, but only with great difficulty. Google around “embedded c interpreter” for small C interpreters that you may be able to integrate into your source. (Good luck, though!)
Let me clarify your two Cases.
Case 1 refers to running a C program out of process. This is not what most people consider "invoke the native method from java". You cannot create a native field in Main. Actually, Java does not have native fields, only native methods. But in Case 1, you don't use native methods, either. You can compile and run any program, written in C or any other language (provided a compiler is available in the runtime environment). To do so, you use shell commands (Runtime.exec()) both to compile the program and to run it. Parameters for the C program can be passed 'on the command line' as specified in Runtime.exec(). It can communicate with your Java process with any IPC of your choice. Typically, we simply use a pipe to read the stdout of the child process.
Case 2 runs the native code in-process, using JNI (Java Native Interface). The flow that you describe here is correct, but you can modify it to use a shared library that is built at runtime. First of all, remove the native method and also loadLibrary() to a separate class. Make sure that the classloader loads this class only after your Main class runs the gcc -o libMain.so command (using the same Runtime.exec() as in Case 1). This way, the static constructor will load the freshly built library.
In both Cases you don't need to recompile your Java. You don't need to run javah to build libMain.so - this is a convenience step only, to guarantee that the C headers are in sync with the Java class. But in your situation, the Java class does not change - therefore the native method signature does not change, too.
Note that Case 1 is easier, especially if you must run different compiled C 'strings', but Case 2 may deliver better performance, if you must call the native method many times.

Different / better approaches for calling python function from Java

I am quite new to python and am trying to call python's function from java.
My primary requirements are these:
call should be transparent, in the sense that it should not require modifying .py file simply to enable it to be called from java. I might be given any python file with some functions inside it. I should be able to call any of these functions without requiring to modify .py file.
I want to be able to send arguments of both primitive types (int, String, floats etc.) or non primitive types (HashMap,ArrayList) from java to python function and receive back the returned object (which may of primitive types or non-primitive types) from python to java. I am also using pandas DataFrame and numpy ndarray and hence also want to be able to send and receive corresponding objects to and from java.
I preferably want to stick to CPython instead of Jython because I might need to use newer libraries that might not be available in Jython.
There are several options that I found online. Few are:
Use Jython's PythonInterpreter with which I am able to invoke python function without requiring any changes to .py script file:
py1.py
def square2(list):
squares = []
for i in list:
squares.append(i*i)
return squares
JythonTest.groovy
import org.python.util.PythonInterpreter
import org.python.core.*;
class JythonTest
{
static main(def args)
{
PythonInterpreter pi = new PythonInterpreter()
pi.exec("from py1 import square2")
PyFunction pf = (PyFunction)pi.get("square2")
println pf.__call__(new PyList([1,2,3,4]))[2] //9
}
}
I am very well able to satisfy my needs. But its not CPython.
Use ScriptEngine: This is very similar to PythonInterpreter. But agains its Jython. Also, unlike PythonInterpreter, we cannot work with Jython 2.5+ and cannot directly access PyObjects. So this option can be very well closed.
Use py4j: Cant find example which is as minimal as in case of Jython PythonInterpreter
Use java2python. But not much information is given about calling python from java so that I can conclude whether my above requirements can be satisfied. Can anyone shed more light on this? More specifically if we can write the code as minimal as the one in Jython PythonInterpreter.
Use JPype: However after quick go through I feel I will not be able to write as minimal code as in case of Jython PythonInterpreter. Also I felt the project somewhat not under developement. Is it?
It seems that Jython PythonInterpreter is the best choice if I have understood all above approaches correctly. Have I made mistakes while grasping them? Also is there any other better option?
#Mahesha999, regarding the ability to stick with CPython which seems important now from your last comment:
Jep is a good option to be able to run python code which uses calls to native, like pandas that you mentionned.
You'll need to write some wrapping code because Jep only implements automatic conversion between Java and Python between the most used types, which pandas.DataFrame is not.
However if your use case is not to complex, you can access your pandas objects as numpy.NDArray object by calling DataFrame.values on your dataframe instance, and Jep implement conversion to the Java class it embeds for NDArray.
You can get back to Java values from python code you execute by using Jep.getValue(String pythonVariableName, Class clazz)
For example
Jep jep = new Jep();
jep.eval("import my_script");
jep.eval("df = my_script.function_returning_a_dataframe()");
jep.eval("col = df.a_column.values");
NDArray myCol = jep.getValue("col", NDArray.class);
I do so on a project I coded in Python that I need to integrate as a plugin in a Java application, so far it works.
There is no current answer to this problem. Using CPython relies on the execution of Python bytecodes, which in turn requires that the Python interpreter be embedded in the execution environment. Since no Java runtime comes with an embedded Python interpreter, it really does look as though Jython is the best answer.
Sometimes the answer you want just isn't available!

Invoke Python modules from Java

I have a Python interface of a graph library written in C - igraph (the name of library). My need is to invoke the python modules pertaining to this graph library from Java code. It goes like this, the core of library is in c. This core has been imported into Python and interfaces to the functions embedded in core are available in Python. My project's rest of the code is in Java and hence I would like to call the graph functions by Java as well.
Jython - which lets you invoke python modules with in Java was an option.I went on trying Jython to discover that it will not work in my case as the core code is in C and Jython wont support anything that is imported as a c dll in python code.I also thought of opting for the approach of calling graph routines directly in c. That is without passing through Python code. I am assuming there must be something which lets you call c code from Java, how ever I am not good in C hence I did not go for it.
My last resort seems to execute Python interpreter from command line using Java. But that is a dirty and shameless. Also to deal with the results produced by Python code I will have to write the results in a file and read it back in java. Again dirty way.
Is there something that any one can suggest me? Thanks to every one giving time.
Thanks Igal for answering. I had a look at it. At first glance it appears as if it is simply calling the python script.
Jep jep = new Jep(false, SCRIPT_PATH, cl);
jep.set("query", query);
jep.runScript(SCRIPT_PATH + file);
jep.close();
Isnt it very similar to what we would do if called the python interpreter from command line through a Java code.
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("python test.py");
Concern is how do I use the results generated by Python script. The naive way is to write them to file and read it back in Java. I am searching for a smarter approach.Thanks for suggestion anyway.
Never tried it. But I recently stumbled on a project named Jepp that may be of interest to you.
Jepp embeds CPython in Java. It is safe to use in a heavily threaded environment, it is quite fast and its stability is a main feature and goal.
If you want to call C functions from Java, JNA (Java Native Access) is probably the way to go. JNA allows you to call functions in native libraries without having to write the C glue code (as you would have to when using JNI), and automatically maps between primitive data types in Java and C. A simple example might look like this:
import com.sun.jna.Native;
import com.sun.jna.Library;
public class PrintfWrapper {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)Native.loadLibrary("c", CLibrary.class);
void printf(String formatString, Object... args);
}
public static void main(String[] args) {
CLibrary.INSTANCE.printf("Hello, world\n");
}
}
However, things will get complicated with igraph because igraph uses many data structures that cannot be mapped directly into their Java counterparts. There is a project called JNAerator which should be able to generate the JNA source from igraph's header files, but I have never tried it and chances are that the results will still need some manual tweaking.
Also note that a Java interface for igraph is being developed slowly but steadily and it might become useful in a few months or so.
You can use jep.getValue() to retrieve a value from script's global dictionary.
There are caveats to that concerning scope levels in Python, so most people find it clearer to pass a Java class to python and set the return value in that instance in Python. After the script completes, the Java code will then have the result.
For example:
==> Java
class ReturnValueClass {
public int scriptResult;
};
ReturnValueClass value = new ReturnValueClass();
jep.set("retval", value);
==> Python
# do something
pass
# write the return value
retval.scriptResult = some_python_value
==> Java
System.out.println(value.scriptResult);
Hope that helps,
Mike (I wrote Jep)

Categories