Executing command line programs from Java - java

I have to execute several command line executables in Windows through Java. Rather than using Runtime.exec, I thought of using Ant Tasks to do these invocations, hoping it would be a better way.
Is there any other better approach or any popular library to do this?

What exactly is wrong with using Runtime.exec()? It's in the API for a good reason...

Runtime.exec is the way of doing this in Java. Any other library would likely be platform specific. You'd need a very good reason not to use Runtime.exec.
I've currently got several programs that make use of this feature and it hasn't caused any trouble.
With Runtime.exec you can optionally block while waiting for the call to complete. You can capture return codes and anything the command line program writes to the console. And I'm sure there are many other features, those are just the ones that were useful to me.
And you can always have it invoke an ant task if you really want to use ant! :)

I have a similar situation now. I use Runtime and Process classes. They work just fine.

Related

What to do first when porting library

I want to access Java library within Ruby, in example Kafka already give jar for every operation, what things I need to do if I want to use it from Ruby?
Like maybe I just need to run shell command to run the Jar within Ruby, or do I need to port the library in Ruby? If it comes down to porting the library, how to do that too?
Thank you in advance
PS: The Java, Ruby, or Kafka are just examples. What I need to know is the big picture how to porting a library. Of course if you add some code example too I'll be more than happy :)
I agree with Aetherus that the fastest and most convenient way is to use JRuby. However I believe there other options than communicating with external Java processes. What to choose probably depends on what code you want to call. I see at least two other options.
Wrap the Java code you want to call in a main program and call it on the command line. This will be slow since Java needs to start and that takes forever but may be a fast way forward in some cases.
Call the Java code from C code that you compile with your Ruby. This will still need to load the JVM but you could probably make it happen only once. I found an article outlining how to get around doing it with JNI.
Both these paths will probably cause you a lot of pain but if it is important to stay on MRI it may be worth the trip. Have fun!
With JRuby, you can import the jar file, then include the classes you need in that jar:
require 'java'
require '/path/to/your.jar'
include_class 'com.really.long.ClassName'
But with Ruby implementations other than JRuby, you have no choice but to communicate with external java processes (through socket, IPC, kill, ...).

How can I tell what processes are using a file under Java in Windows?

We have a scheduled task written in Java that is failing on Windows platforms because sometimes the files it needs to delete are still in use. Is there a way from within Java that I can see what processes are using a file and get information on them?
I thought I would add that I am willing to use JNA or JNI if necessary, and I assume it is going to be.
I asked a similar question on Github for the JNA project and #matthiasblaesing wrote a code to accomplish this.
The code is here.
It prints a list with all the running processes in the format: <exe>: <type>: <path>.
One dirty way to do it is to run your application with administrative privileges and invoke a command utility such as Handle using a ProcessBuilder.
You can use the excellent Sysinternals Process Explorer to do this, and it's not limited to Java processes.
See this posting for details. I don't know how to invoke this functionality from java, however.
My own preliminary answer (please, someone do better!):
Ideally, I'd like to learn how to programmatically do what tools like Process Explorer, unlocker, handler, etc., do, and then call that from Java with JNA or similar. But it looks like that involves data structures that change for each Windows release, so it sounds very fragile. The system call involved appears to be named NtQuerySystemInformation.
It looks like in cases like we are dealing with, the preferred approach for Windows Vista onward is to use the "restart manager API," which triggers a system restart, clearing all open filehandles. (source: http://social.msdn.microsoft.com/Forums/sv/netfxbcl/thread/37dc9843-2583-41fc-8260-b78183aa4bed) We sure don't want to do that, if we can help it.

java operation on Files - java.io.File or cmd commands

i need to perform some operations on files - rename, delete and etc.
what is better? use cmd commands or use java.io.File methods?
thanks.
Normally it's not a good idea to depend on OS specific things in a platform independent environment, not mentioning the speed which would be much slower with the local commands.
I would stick with the Java implementations, if it's possible with them.
After lots of comments I catch the real question. So my answer is:
Of course it is better to use java feauters, because:
If you wan't your program to be portable you can't use command line, because it wouldn't work on unix or other systems expect windows. Also can't work on some other versions of windows.
To use command line feautures from your code you should creat new process end execute this commands, which is very slow.

Command line tool in Java gets run many times in a row, JRE keeps opening/closing, slow

I wrote a command line tool in Java and it gets run many times in a row from a BAT script. Right now it's a runnable JAR (which in hindsight isn't probably the right choice here...). The JRE seems to get loaded and unloaded every time the program is run, which seems inefficient. Overall, it seems a lot slower than it should be.
Do any Java gurus out there know a more proper way to handle this situation?
As there is no easy fix, you might also consider more radical approaches:
Actually porting what's in your bat in the java itself (easy if it's loop on files with some kind of filter).
Compiling the jar into an exe (e.g. with GCJ) if maximum portability is not an issue.
You could try a number of things. A simple one is starting the JVM with -Xquickstart.
EDIT: Looks like this option is for the IBM JDK only (which incidentally also has support for AOT-compilation/shared class caches).
Another option is, making it into a single longer running process that can accept multiple jobs interactively or in a batch.
Someone created a project to make a framework for this purpose called nailgun, not sure what state it is in. Google gave me these results when I searched: http://sourceforge.net/projects/nailgun/ and http://martiansoftware.com/nailgun/.
There is also a GNU's gcj which will compile Java down to native code http://gcc.gnu.org/java/.
This is actually one of the biggest problems with Java, and there aren't any easy solutions. Basically, if you want a lightweight program that might get run many times in rapid succession, then you shouldn't be doing it in Java.
I don't have any experience with compiling Java to native code, but I do know that almost no one does it; there might be a good reason for that.
If you post the BAT file, or at least describe what it does, maybe someone can offer a better suggestion.

Options to configure a Linux box from Java

I'm trying to make an java application to manage Linux servers from a web interface.
It is a bad idea to perform each task by calling bash shell ?
Are there any other options other than those to use C, Perl or another language?
It's not necessarily a bad idea to use bash to do the actual work. It would help if you gave us more of an idea what exactly the web interface was changing.
Java in particular does not provide much system-specific controls, because it was designed as a cross-platform language, so putting specific platform tools in would go against it's purpose.
You could certainly do it that way. Ideally you'd open up a port and accept specially crafted, specific actions which perform only the intended actions (an interface server) through a socket library.
I should think that the disadvantage(s) of calling Bash scripts for your commands is all related to error handling and return values. Each of your Bash scripts will need to return sensible, useful information to the Java app in the case of failures (or even successes). And you'll probably want a common interface for that such that each Bash script, no matter its function, returns the same types so that the Java can interpret it easily.
So, in that sense, making the changes from your Java program reduces the complexity of handing the information back and forth. On the other hand, if Bash is easier for you, you may find it more fast and flexible.
Opening up a single bash shell and sending commands (and properly parsing results) shouldn't be bad. It does tie your program to a single OS and even a single shell, but that's the nature of what you are trying to do.
What I wouldn't do is open a shell for each command and close it after each result. It seems to me that would cause unnecessary thrashing when many commands were executed in a row.
Security concerns jump at me. If you have a form like "type command" then someone clever could exploit some things. For example "configure network" is fine but "configure network; install rootkit" can be typed because a semi-colon allows commands to be chained.
All in all, this is not tight integration. If this is a personal project, go for it. It's a good learning project to turn a procedural script into a java program. If this is a serious effort to recreate the many various webapp admin tools there are, I'd seriously suggest skipping this. The VPanel/CPanel things I've seen I hate. There used to be a php based linux admin thing that looked ok but I just find them easily to learn, easy to outgrow because the net and community is full of command line knowledge.
If you are trying to automate a large deployment, look at the ruby-based puppet. It looks really neat.
I have a socket server were I perform different operations (using ifconfig by calling shell for example) and I plan to integrate an client in a JSF application.Because I'm not experienced ant I intend to make it my graduation project, but I'm not so sure if calling bash from java to configure a linux box is a good solution.
Java does have some Linux-configuring classes (well, at least, OpenJDK does). Check OperatingSystemMXBean or something like that.
You're beter to write your own server configuration utility in the language you prefer, sanitize it, make it secure and then call it via bash from your java app.
There are two questions here:
Should you try to do the configuration work in Java, or should you externalize it?
Assuming that you have externalized it, should you use bash scripts.
In this case, the answer to question 1) depends. This kind of thing can be difficult to implement in pure Java. This leaves two choices; externalize the task using a Process, or try to do it in a native code library via JNI or JPA. The latter approach is complicated and gives you JVM crashes if you make a mistake, so I would rule that out.
On the other hand, if you can find a good standard or 3rd party Java API that does what you need (without infesting your JVM with flakey JNI, etc), you should use that.
The answer to 2) is that bash scripts will work as well as any other scripting language. I think that using scripts gives you a bit more flexibility. For example, if you need to do things to compensate for differences in the different flavours of Linux, UNIX or maybe even Windows (!) you can put this into the externalized scripts. (A corollary is that the scripts need to be configurable, so don't embed them in your source code!)
Another alternative might be to run the commands (e.g. ifconfig) directly, using a fully qualified command name and supplying the arguments as an array of strings, etc. But unless your app is going to run the external command 100s of times a minute, it is probably not worth the (Java) coding effort and the loss of flexibility / configurability.
A lot of the response would depend on why you're doing this and why other more obvious solutions aren't possible. Knowing why you would choose to roll your own as opposed to installing Webmin would be good, or why you're choosing to use Web UI at all as opposed to VNC to control the box. There are some obvious responses to the later (firewall issues for instance), but there's no immediately obvious reason for the former. Without knowing more about the requirements, answering questions about implementation details like bash scripts versus perl or C is meaningless.

Categories