I'm using commons VFS to monitor certain folder for changes (mainly inserting new file), the program should runs permanently, I use the following code
FileSystemManager fsManager = VFS.getManager();
FileObject listendir = fsManager.resolveFile(path);
DefaultFileMonitor fm = new DefaultFileMonitor(new VfsListener());
fm.setRecursive(true);
fm.addFile(listendir);
fm.start();
where path is the folder path, and VfsListener is a class that implements FileListener, when I run the program it runs and then closed immediately, when I added this after fm.start() :
Thread.sleep(100000)
the program run for a while and then closed after the time out is reached, and I don't want that, I want the program to rum permanently, if anyone know please reply
VFS starts the FileMonitor thread as a daemon thread in low priority. The definition of the method setDaemon(boolean) states that
Marks this thread as either a daemon thread or a user thread. The
Java Virtual Machine exits when the only threads running are all
daemon threads.
This method must be called before the thread is started.
This is the reason your program works as long as you 'sleep' in the main thread. However, this is only an issue if you're running this program as a standalone java program. If you run the same piece of code in a application server like Jboss, the code just works fine.
If you still want the standalone program to wait indefinitely, you can modify the program to use a ThreadPoolExecutor which will essentially wait for the new tasks to be available in the Task Queue.
public static void main(String[] args) throws FileSystemException {
Executor runner = Executors.newFixedThreadPool(1);
runner.execute(new Runnable() {
#Override
public void run() {
FileObject listendir = null;
try {
FileSystemManager fsManager = VFS.getManager();
listendir = fsManager.resolveFile(absolutePath);
} catch (FileSystemException e) {
e.printStackTrace();
}
DefaultFileMonitor fm = new DefaultFileMonitor(new FileListener() {
#Override
public void fileDeleted(FileChangeEvent event) throws Exception {
System.out.println(event.getFile().getName().getPath()+" Deleted.");
}
#Override
public void fileCreated(FileChangeEvent event) throws Exception {
System.out.println(event.getFile().getName().getPath()+" Created.");
}
#Override
public void fileChanged(FileChangeEvent event) throws Exception {
System.out.println(event.getFile().getName().getPath()+" Changed.");
}
});
fm.setRecursive(true);
fm.addFile(listendir);
fm.start();
}
});
}
Hope this helps.
Related
I'd like to check to see if a Thread is Interrupted, from some other Thread, without polling this to check - i.e. some kind of monitor.
Specifically, what I am trying to do is force-kill (Stop) a Thread when it is Interrupted. I will include a code example below of a trivial example of what I have done so far - it works, but polling to check if the Thread is interrupted is sub-optimal and I would like to avoid this.
public class ThreadTest
{
public static void main(final String[] args) throws InterruptedException
{
final Thread outerThread = new Thread()
{
#Override
public void run()
{
// Need to externally monitor the thread to detect and process interrupts (for cancellation)
final Thread thread = Thread.currentThread();
new Thread()
{
#Override
public void run()
{
while (true)
{
try
{
Thread.sleep(500);
}
catch (final InterruptedException e)
{}
if (thread.isInterrupted())
{
// Then kill it
thread.stop();
return;
}
}
}
}.start();
uninterruptibleForever();
}
};
outerThread.start();
// Ensure the thread has time to start up
Thread.sleep(500);
outerThread.interrupt();
// The thread should terminate at this point and not continue.
}
/** Some arbitrary task that runs forever and ignores interrupts */
public static void uninterruptibleForever()
{
while (true)
{
System.out.println(MessageFormat.format("I''m still running at {0}", new Date().toLocaleString()));
}
}
}
I can't recommend strongly enough that you don't use Thread#stop().
It should never have existed, was deprecated very quickly and frankly should have been removed about 20 years ago.
You have no idea what the thread is doing when you stop it and it is very easy to corrupt shared objects and leave external resources (e.g. files) in an invalid state.
Suppose the thread is in the middle of resizing a shared ArrayList<> there's risk the object will be corrupted and your whole program fails intermittently in ways you cannot fix.
Do not use Thread#stop() it is broken and cannot be fixed.
It's a terrible feature of Java that it leads people into invalid techniques regarding threads.
Caveat over - how about just overriding interrupt() in a sub-class?
public void interrupt(){
this.stop();
}
You've decided to sub-class Thread (rather than Runnable) so this will "work". "work" in the sense of what you're doing. Not actually work or anything.
The only valid way to solve this is have the thread you want to terminate co-operate by responding to interrupt() as an instruction to come to a suitable point and then terminate cleanly.
Or you can create another flag indicating the thread should end.
I don't know why you need to monitor the thread externally. But here is a small sample how you could do it if you really need it:
import java.util.LinkedList;
import java.util.List;
public abstract class MonitoredCallable implements Runnable {
private final List<InterruptedHandler> interruptedHandlers = new LinkedList<>();
protected abstract void runInternal() throws Exception;
#Override
public final void run() {
try {
runInternal();
} catch(Exception ex) {
}
for (InterruptedHandler interruptedHandler : interruptedHandlers) {
interruptedHandler.threadInterrupted(this);
}
}
public void addInterruptedHandler(InterruptedHandler interruptedHandler) {
this.interruptedHandlers.add(interruptedHandler);
}
public static interface InterruptedHandler {
void threadInterrupted(Thread t);
}
}
Now just use it like this:
MonitoredThread mt = new MonitoredThread() {
#Override
protected void runInternal() throws Exception {
//dosomething
}
};
mt.addInterruptedHandler(t->t.stop());
I found very good example for SNMP server and SNMP client but I'm not sure how I can implement JUnit test into single test file:
public class SNMPClientTest
{
#Test
public void randomData()
{
SnmpTrap trap = new SnmpTrap("127.0.0.1",
"1.3.6.1.4.1.2789.2005.1={s}WWW Server Has Been Restarted",
2, "kschmidt", "MD5", "mysecretpass", "DES", "mypassphrase");
trap.doTrap();
}
}
public class SNMPServerTest
{
#Test
public void randomDatabaseData() throws SQLException, FileNotFoundException, IOException
{
V3TrapReceiver v3 = new V3TrapReceiver("127.0.0.1", "kschmidt", "MD5",
"mysecretpass", "DES", "mypassphrase");
v3.listen();
}
}
When I run the server I get message Waiting for traps.. and I can't continue the JUnit test. But I can run them into 2 separate files.
How I can solve this? You can find the complete source code here: http://pastebin.com/zKEtXQmq
If you wanted to have both the client and the server running within the same test you can consider starting them as separate Threads within a single Test.
I normally try to avoid this because it does add some complexity and context management to the test.
Please note:
This sample has not been tested, there may be tweaks that need to be made. The gist of the handling of the additional threads should be about right.
I did not verify anything for your tests, so all this does is run the server and then the client with no expectation of output or state.
#Rule
public ErrorCollector collector = new ErrorCollector();
#Rule
public Timeout testTimeout = new Timeout(15, TimeUnit.SECONDS);
#Test
public void testServerClientCommunication throws Exception () {
final SnmpTrap trap = new SnmpTrap("127.0.0.1",
"1.3.6.1.4.1.2789.2005.1={s}WWW Server Has Been Restarted",
2, "kschmidt", "MD5", "mysecretpass", "DES", "mypassphrase");
final V3TrapReceiver v3 = new V3TrapReceiver("127.0.0.1", "kschmidt", "MD5",
"mysecretpass", "DES", "mypassphrase");
Runnable serverTask = new Runnable() {
#Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
v3.listen();
}
} catch (Throwable th) {
//Exceptions thrown outside of the main Junit execution won't get propagated back to fail the test
//Use the ErrorCollector to maintain awareness
collector.addError(th);
}
}};
//Create the Thread to handle the Server execution
final Thread serverExecutor = new Thread(serverTask, "SNMP Server");
/*
* Create the client task and thread.
*/
Runnable clientTask = new Runnable() {
#Override
public void run() {
try {
boolean clientIsDone = false;
while (!clientIsDone) {
trap.doTrap();
//FIXME: Determine the state that matters.
clientIsDone = true;
}
} catch (Throwable th) {
//Exceptions thrown outside of the main Junit execution won't get propagated back to fail the test
//Use the ErrorCollector to maintain awareness
collector.addError(th);
}
}};
Thread clientExecutor = new Thread(clientTask, "SNMP Client");
/*
* Start the server first
*/
//Don't hold the JVM if the server is not done.
serverExecutor.setDaemon(true);
serverExecutor.start();
/*
* Now start the client. Note that after the client traps successfully that it will interrupt the server thread.
* The intent is that the interrupt will allow the server thread to die gracefully
*/
clientExecutor.setDaemon(true);
clientExecutor.start();
//Since we off-threaded the tasks the test will consider itself 'done' unless we join with the client, which basically says
//"Hold the current thread at this point until the other thread completes."
clientExecutor.join();
}
Start the server in a method annotated with #BeforeClass. This will run before any other tests will be invoked.
I have a GUI program that executes TestNG automation scripts. It's meant for users to easily configure some setting and launch the automation script that they want.
One thing I need to add is the ability to instantly stop the running TestNG process. Something like how in Eclipse, the 'Terminate' button will instantly stop whatever is running.
This is what the code that launches the TestNG tests looks like:
public class ScriptRunner implements Runnable {
public void runScript() {
Thread testRun = new Thread(this);
testRun.start();
}
#Override
public void run() {
//various other things are configured for this,
//but they're not relevant so I left them out
TestNG tng = new TestNG();
//While this runs, various browser windows are open,
//and it could take several minutes for it all to finish
tng.run();
}
}
As per the comment, the tng.run() can take several minutes to complete, and it's performing several things, opening/closing browser windows, etc.
How can I just instantly terminate the process, like you would when running an application from an IDE?
EDIT:
Per the comments, I'm attempting to use a ServiceExecutor and shutDownNow() The code is looking like this:
ExecutorService executorService = Executors.newFixedThreadPool(10);
public void runScript() {
executorService.execute(this);
}
//this method gets called when I click the "stop" button
public void stopRun() {
executorService.shutdownNow();
}
#Override
public void run() {
//same stuff as from earlier code
}
Spawn a child JVM process using ProcessBuilder or Runtime and you will be able to terminate that process when the user requests that the script stops running.
You can use ExecutorService to start test execution into one another thread. You can choose to have many thread in parrallel or juste one thread for all tests in sequence by choosing which executor service you need.
After that, start the execution of all tests in the same executor service instance by calling submit() method on it. You can stop the execution of all submitted runnables by calling shutdownNow() method.
It is important to use the same instance of ExecutorService, otherwise you start each test in a different thread and you will not enable to break the execution chain (or by calling shutdownNow() on all of them).
I was recently working on the executor framework. Here I have listed my problem
http://programtalk.com/java/executorservice-not-shutting-down/
Be careful if you are doing some IO operations the executor service may not shutdown immediately. If you see the below code stopThread is important because it tells your program that the thread has been asked to stop. And you can stop some iteration what you are doing.
I will modify your code like this:
public class MyClass {
private ExecutorService executorService;
private boolean stopThread = false;
public void start() {
// gives name to threads
BasicThreadFactory factory = new BasicThreadFactory.Builder()
.namingPattern("thread-%d").build();
executorService = Executors.newSingleThreadExecutor(factory);
executorService.execute(new Runnable() {
#Override
public void run() {
try {
doTask();
} catch (Exception e) {
logger.error("indexing failed", e);
}
}
});
executorService.shutdown();
}
private void doTask() {
logger.info("start reindexing of my objects");
List<MyObjects> listOfMyObjects = new MyClass().getMyObjects();
for (MyObjects myObject : listOfMyObjects) {
if(stopThread){ // this is important to stop further indexing
return;
}
DbObject dbObjects = getDataFromDB();
// do some task
}
}
public void stop() {
this.stopThread = true;
if(executorService != null){
try {
// wait 1 second for closing all threads
executorService.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
What about this,
add a volatile static boolean and make the thread code look like...
if(ScriptRunner.runThread){
//Do some stuff here
}
if(ScriptRunner.runThread){
//Do some other stuff here
}
if(ScriptRunner.runThread){
//Do some other stuff here
}
if(ScriptRunner.runThread){
//Do rest of the stuff here
}
Now you can add a button in your main GUI that simply sets the runThread to false so the thread will terminate nearly instant leaving all the leftover code untouched as you press the Stop button.
public class ScriptRunner implements Runnable {
volatile static Boolean runThread = true;
public void runScript() {
Thread testRun = new Thread(this);
testRun.start();
}
public void terminate(){
runThread = false;
}
#Override
public void run() {
//various other things are configured for this,
//but they're not relevant so I left them out
TestNG tng = new TestNG();
//While this runs, various browser windows are open,
//and it could take several minutes for it all to finish
tng.run();
}
}
How about a new Thread? You have to add an private Thread thread; in the gui and when ever you start
thread = new thread(){
#Override
public void run(){
//start process here
}
};
thread.start();
and to stop "terminate"
thread.stop();(depracted) or thread.setDeamon(true);
Everytime I have to stop a process by the gui I use this.
Hope I could help ;)
In your GUI somewhere you have something like
ScriptRunner scriptRunner = new ScriptRunner();
scriptRunner.runScript();
When you want to stop it call
scriptRunner.interrupt();
Change the code in ScriptRunner
private Thread testRun;
public void runScript() {
testRun = new Thread(this);
testRun.start();
}
public void interrupt() {
testRun.interrupt();
}
Save all created processes and kill them when your program ends:
public class ProcessFactory {
private static Set<Process> processes = new HashSet<>();
private static boolean isRunning = true;
public static synchronized Process createProcess(...) throws ... {
if (!isRunning)
throw ...
... // create your spawned process
processes.add(process);
return process;
}
public static synchronized void killAll() {
isRunning = false;
for (Process p : processes)
p.destroy();
processes.clear();
}
public static void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
void run() {
killAll();
}
});
}
}
This can be improved by adding a mechanism that removes already dead processes, but you get the general idea.
i am facing one multiThreaded issue.
i have 10 Threads.when we strat application the first thread will try to create the folder.
mean while remaining thread try to move the file to that folder,before creating folder.so i am getting NulpointerException. how to stop remaining theads up to folder creater thread completes.
code like this:
Static int i;
moveFile()
{
if(i==1){
create();
}
move(){
}
}
You can do it in many ways.
Make a check of folder exist in your thread then place file into it
Run 2nd thread only after creation of folder so that this will never happen. If there are multiple folders and so many files are ther then launch new thread after complition of creation of folder where the 2nd thread dedicatly push files into that specific folder
Create a latch (countdown latch) of size 1.
In the thread creating the folder call the countdown() method on the latch after the folder has been created. In all other threads call the await() method on the latch before beginning any processing like moving the file.
There are zillion other ways to do it. If it's possible choose the simplest approach (spawn the threads/ tasks which move files et-all only after the folder is created)
I think Thread.join() is what you are looking for. It performs wait() on the thread (possibly with timeout) until it's execution ends.
Pass a reference of the "folder thread" to each of the other "file threads", and join() it.
Example:
public class JoinThreads {
static ArrayList<FileThread> fthreads = new ArrayList<FileThread>();
public static void main(String[] args) {
Thread folderThread = new Thread () {
#Override
public void run() {
// Create the folder
}
}.start();
// Add new threads to fthreads, pass folderThread to their constructor
for (FileThread t : fthreads) {
t.start();
}
}
public class FileThread extends Thread {
Thread folderThread;
File file;
public FileThread(Thread folderThread, File file) {
this.folderThread = folderThread;
}
#Override
public void run() {
try {
folderThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Save the file, folder should already exist!
}
}
}
I'm writing an app in java allowing me to run other applications. To do that, I've used an Process class object, but when I do, the app awaits the process to end before exiting itself. Is there a way to run external application in Java, but don't wait for it to finish?
public static void main(String[] args)
{
FastAppManager appManager = new FastAppManager();
appManager.startFastApp("notepad");
}
public void startFastApp(String name) throws IOException
{
Process process = new ProcessBuilder(name).start();
}
ProcessBuilder.start() does not wait for process to finish. You need to call Process.waitFor() to get that behaviour.
I did a small test with this program
public static void main(String[] args) throws IOException, InterruptedException {
new ProcessBuilder("notepad").start();
}
When run in netbeans it appear to be still running. When running from command line with java -jar it returns immediately.
So your program is probably not waiting to exit, but your IDE makes it seem so.
You can run it in another thread.
public static void main(String[] args) {
FastAppManager appManager = new FastAppManager();
appManager.startFastApp("notepad");
}
public void startFastApp(final String name) throws IOException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Process process = new ProcessBuilder(name).start();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
You might want to start a daemon thread depending on your needs:
ExecutorService executorService = Executors.newSingleThreadExecutor(new ThreadFactory() {
#Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread();
thread.setDaemon(true);
return thread;
}
});