Windows: signaling a Java process to show its window - java

I have a Java process that runs in the background. How can I quickly signal the process to show its window? I want a really light-weight script that can do this and can be launched from the Start Menu.
I think maybe a BAT file that checks if the lock file has been touched in the last few seconds, signal the process, otherwise, create a new one. The signal could be by creating another file that the process would be listening for.
That works, but it seems inefficient. Hesitation sounds unavoidable.
I could use Java instead of a BAT file, still that leaves the question of how to signal the background process. This only has to work in Windows, but I am good with Java so that is what I am using.
Any ideas?

One option would be to have that process having a listener on a port (as an example 8888), then you could send a message to that port (or do something like telnet localhost 8888). The running processes could have a separate thread listening on that port.
Another option would be to use JMX communication with the JVM - see http://download.oracle.com/javase/6/docs/technotes/guides/management/agent.html

Is there anything preventing you from checking the lock file from your Java process? You could use the Observer pattern to alert the main thread (or which ever thread) to changes in the file.
For example:
public class FileWatcher implements Observable {
private long lastModified;
private final File file;
public FileWatcher(File f) {
this.file = f;
this.lastModified = file.lastModified();
Thread t = new Thread() {
public void run() {
while(!stopThread) {
if(lastModified < file.lastModified()) {
lastModified = file.lastModified();
setChanged();
notifyObservers();
}
Thread.currentThread().sleep(5);
}
}
};
t.start();
}
}
DISCLAIMER: not tested or verified at all, but I'm sure you get the idea.
EDIT: oops, forgot the loop.
EDIT: new idea.
I have another idea. (I know you already accepted an answer, but I wanted to throw this out there.) Would it be possible to use the select function? In my very limited skim of the MSDN docs, this is only mentioned this in the context of sockets. I know the Linux equivalent is applicable to any file descriptor.
Instead of simply polling the file in the thread I mentioned above, let the OS do it! Pass the file into the writefds set to select and then it'll return when the file is modified. This means your process isn't spending valuable CPU time waiting for changes to the file.
I haven't verified whether or not Java exposes this call in the JDK, so it might require writing a JNI interface to get it to work. My knowledge in this area is a little fuzzy, sorry.
EDIT again again:
Found it! Java's Selector class looks like it implements select. Unfortunately, FileChannel isn't selectable, which is probably required in this case. :(

Related

linux-wide semaphore with a Java API

I need to prevent a certain application function from being run concurrently with itself. The risk is significant because this function is in code submitted to java.util.Timer (to repeat every minute for several hours) and the process that sets up the function completes and goes back to the bash command line. The user might then invoke the same program. Another risk is from the user that has two or more console windows and they mistakenly run the program in both console windows.
I think an operating system-wide semaphore with a Java API might do the trick. Is there such a Java archive available?
I was asked if multiple JVMs are used. I think if multiple consoles are opened then multiple JVMs are implied.
This is my wrapper to use Java's Timer and TimerTask.
public final class TimedExecutorWrapper
{ ... various private members ...
public Timer go()
{
Timer myTimer = new Timer();
myTimer.scheduleAtFixedRate(this.myTask,
this.startTodayAtThisTime,
this.frequencyInSeconds * 1000);
TimerTask myTaskToInvokeCancel = new TaskToInvokeCancel(myTimer);
// use the same Timer to schedule the task that cancels and purges
myTimer.schedule(myTaskToInvokeCancel,
this.stopTodayAtThisTime);
return myTimer;
}
private final class TaskToInvokeCancel extends TimerTask
{
private Timer timer; // to be cancelled and purged
TaskToInvokeCancel(Timer timer)
{
this.timer = timer;
}
public void run()
{
this.timer.cancel(); // discards any scheduled tasks without
// interfering with any running task
this.timer.purge();
}
}
}
You could create a 0 byte file 'methodname.LOCK' in a shared directory when you begin the operation, and delete it when you are done. Creating it with a no recreate flag in Java should solve your problem.
Make sure to delete it in a 'finally' block so you are never left in a state where the file exists and continues to block the process from ever running
just open a serversocket at a specific port. if this succeeds there is no other application, if not an exception is thrown.
The only standard Java feature I've seen that prohibits multiple instances of the same program is the SingleInstanceService in Java WebStart.
http://download.oracle.com/javase/1.5.0/docs/guide/javaws/developersguide/examples.html#SingleInstanceService
It requires you to create a JNLP file for your application, which is a bit cumbersome but may be very useful to you anyway. Note that Java does not allow command line parameters to be passed to your program which may be very inconvenient in this situation. Depends on what your command line says.
If Java WebStart does not work for you, then you must ask the operating system for a resource which is denied for subsequent requests and have it automatically released. The only one of these not platform specific is the TCP/IP socket but these are rare and may be used by another program. Under Linux you may ask for shared memory but I do not have personal experience with this.

Java - how to stop a thread running arbitrary code?

In my application which runs user submitted code[1] in separate threads, there might be some cases where the code might take very long to run or it might even have an infinite loop! In that case how do I stop that particular thread?
I'm not in control of the user code, so I cannot check for Thread.interrupted() from the inside. Nor can I use Thread.stop() carelessly. I also cannot put those code in separate processes.
So, is there anyway to handle this situation?
[1] I'm using JRuby, and the user code is in ruby.
With the constraints you've provided:
User submitted code you have no control over.
Cannot force checks for Thread.interrupted().
Cannot use Thread.stop().
Cannot put the user code in a process jail.
The answer to your question is "no, there is no way of handling this situation". You've pretty much systematically designed things so that you have zero control over untrusted third-party code. This is ... a suboptimal design.
If you want to be able to handle anything, you're going to have to relax one (or preferably more!) of the above constraints.
Edited to add:
There might be a way around this for you without forcing your clients to change code if that is a(nother) constraint. Launch the Ruby code in another process and use some form of IPC mechanism to do interaction with your main code base. To avoid forcing the Ruby code to suddenly have to be coded to use explicit IPC, drop in a set of proxy objects for your API that do the IPC behind the scenes which themselves call proxy objects in your own server. That way your client code is given the illusion of working inside your server while you jail that code in its own process (which you can ultimately kill -9 as the ultimate sanction should it come to that).
Later you're going to want to wean your clients from the illusion since IPC and native calls are very different and hiding that behind a proxy can be evil, but it's a stopgap you can use while you deprecate APIs and move your clients over to the new APIs.
I'm not sure about the Ruby angle (or of the threading angle) of things here, but if you're running user-submitted code, you had best run it in a separate process rather than in a separate thread of the same process.
Rule number one: Never trust user input. Much less if the input is code!
Cheers
Usually you have a variable to indicate to stop a thread. Some other thread then would set this variable to true. Finally you periodically check, whether the variable is set or not.
But given that you can't change user code , I am afraid there isn't a safe way of doing it.
For Running Thread Thread.Interrupt wont actually stop as sfussenegger mentioned aforth (thanks sfussenegger recollected after reading spec).
using a shared variable to signal that it should stop what it is doing. The thread should check the variable periodically,(ex : use a while loop ) and exit in an orderly manner.
private boolean isExit= false;
public void beforeExit() {
isExit= true;
}
public void run() {
while (!isExit) {
}
}

How to test "Too Many Files Open" problem

I have a batch process that converts WAV to MP3 sequentially. The problem is that after a few thousand there are too many files left open, and it runs up against the file limit.
The reason it does this is because of the code in SystemCommandTasklet:
FutureTask<Integer> systemCommandTask = new FutureTask<Integer>(new Callable<Integer>() {
public Integer call() throws Exception {
Process process = Runtime.getRuntime().exec(command, environmentParams, workingDirectory);
return process.waitFor();
}
});
This has the nasty side effect of making me rely on the JVM to clean up the processes, leaving files open and such.
I've rewritten it to be so:
FutureTask<Integer> systemCommandTask = new FutureTask<Integer>(new Callable<Integer>() {
public Integer call() throws Exception {
Process process = Runtime.getRuntime().exec(command, environmentParams, workingDirectory);
int status = process.waitFor();
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().flush();
process.getOutputStream().close();
process.destroy();
return status;
}
});
I'm 95% certain that this works on my mac (thanks to lsof), but how do I make a proper test that will work on any system to PROVE that what I am trying to do is actually working?
You should not use Runtime#exec() for that, because the process is not attached to the JVM's. Please take a look on the j.l.ProcessBuilder which returns a Process which is controlled by the JVM's process. So dumping the process may force the system to free / close resources.
You should schedule and limit the processes as well using j.u.c.Executors.
You also may read the limit using "ulimit -Sn" ("ulimit -Hn" should not be prefered due to system health ;).
Check your tool that converts your media whether it keeps resources reserved after completion (leakage, waiting for caller signals etc).
A proof will be difficult. But ...
Create a (Dummy)command that doesn't do much but keeps a lock on the files, just as the real thing. This makes sure your test doesn't depend on the actual command used.
Create a test that starts SystemCommandTask, using the old version, but the DummyCommand. Make it start the task often, until you get the expected exception. Lets call the number of Tasks needed N
Change the test to start 100xN Tasks.
Change the Task to the new version. If the test goes green you should be reasonably sure that your code works.
You could try and code to avoid it.
Why don't you proactively limit number of tasks at a time say 100 ?
In that case you could use some pooling mechanism to execute you work like Thread Pools.

What do I do about a Java program that spawned two instaces of itself?

I have a java JAR file that is triggered by a SQL server job. It's been running successfully for months. The process pulls in a structured flat file to a staging database then pushes that data into an XML file.
However yesterday the process was triggered twice at the same time. I can tell from a log file that gets created, it looks like the process ran twice simultaneously. This caused a lot of issues and the XML file that it kicked out was malformed and contained duplicate nodes etc.
My question is, is this a known issue with Java JVM's spawning multiple instances of itself? Or should I be looking at sql server as the culprit? I'm looking into 'socket locking' or file locking to prevent multiple instances in the future.
This is the first instance of this issue that I've ever heard of.
More info:
The job is scheduled to run every minute.
The job triggers a .bat file that contains the java.exe - jar filename.jar
The java program runs, scans a directory for a file and then executes a loop to process if the file if it finds one. After it processes the file it runs another loop that kicks out XML messages.
I can provide code samples if that would help.
Thank you,
Kevin
It's not a Java problem. If you want the app to run alone, no copies, you should use the shell script or the java app to make and remove a lock somewhere.
You actually start multiple java's by starting more than 1 batch job with the same command. Windows nor Java can now that's not what you want. You could solve that by something like:
public static void main(String [ ] args)
{
createLockIfNotExists();
try {
yourstuff;
} finally {
releaseLock();
}
}
private static void createLockIfNotExists() throws MyLockAlreadyExists {
// A bit tricky
// check if LOCKFILE exists, if yes throw MyLockAlreadyExists
// try to create LOCKFILE, can fail if at 1 ms earlier an other app created
// that file, so an exception while creating also results in LockAlreadyExists
}
Are there good examples somewhere which handle this locking? Maybe in Apache Commons?
Here seems to be a functioning example for Windows.
You could also use the database to write your lock. Lock the locking table before you use it of course so no 2 processes write their lock at the same time, and afterwards read the lock record to check whether you actually got the lock. Something like pseudo code:
SELECT * FROM lock_table;
if locks.length > 0: someone else is running
LOCK lock_table;
INSERT INTO lock_table VALUES(my_pid);
UNLOCK lock_table;
SELECT pid FROM lock_table;
if pids.length > 1: what happened?
if pids[0] != my_pid: someone else got the lock
A bit more juice and you also add not only the PID but also a timestamp, and check whether that timestamp is stale (too old).

Concurrent/Non-blocking console keyboard input

I'm working on a MUD in java. I read player input every tick, but I'm using Scanner which uses blocking operations. I want to have non-blocking input.
I've looked at the nio package which has a Selector class, but I'm not sure how to use it with regard to System.in. I figure I'll definitely need it once I'm running a server, but for now everything is offline.
I've tried extending the main class from Applet and overriding keyDown, but that just meant input was no longer accepted after the first one. Sure, I wasn't blocking anything anymore, but then there was no more input. keyDown never got called again, I guess.
Perhaps threads can be interrupted even when they are executing blocking operations?
Thanks for any insight into this problem.
You can't do that with the system console because by now it can't be done in a multi-platform way.
You can use swing window as console or find a JNI based approach but it might not work on some platforms.
You may use JCurses. It might work, it's based on JNI and supports Windows and Linux.
keyDown() is deprecated so I'd suggest to use processKeyEvent and a keyListener instead.
Perhaps threads can be interrupted even when they are executing blocking operations?
Yes if you have a reference to the thread object you want to interrupt, you can simply call interrupt() method on that instance. And in the run method of the thread you can handle the interrupted exception. However, this seems a little bit hack-ish. I don't see how this is more helpful than using a simple KeyListener.
JLine might fit your bill as well:
http://jline.sourceforge.net/apidocs/src-html/jline/ConsoleReader.html#line.1447
I had had to solve similar problem with blocking writing/reading from http. In that particular case I used local buffer and Threads.
Idea is simple, one Thread read from stdin and put content in buffer. Second do same with writing.
And then you use nonblocking queries into your buffer.
Sample code:
class NonBlockingReader implements Runnable{
Reader in;
List buffer;
public void run(){
String line=null;
while((line=in.readLine())!=null){
storeLine(line);
}
}
private synchronized storeLine(String line){
buffer.add(line);
}
public synchronized String getLine(){
if(list.size()>0)
return list.removeFirst();
return null;
}
}
// .. same for writer, then you jast pass stdin and stdout ...

Categories

Resources