Regarding manual termination of the program in eclipse java? - java

public class Test {
public static void main(String[] args)
{
while(true) {
System.out.println("1 ");
}
}
}
What this code does is run for infinite till the program is terminated manually for example give the picture below.
What my requirement is when I manually terminate the execution
my output should be like below
1
1
1
Program terminated manually
thank you
The above 2 lines of output after I manually terminate the program.
Why I need this is I am storing the serializable objects in the file. My code flow is when I working on the program there will be a lot of modifications in the object at end of execution I serialize the updated object into the file. So when I terminate the program manually serialization of the updated object is not done. So I need Serialization should be done even at manual termination.

You can add a hook to the shutdown event:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
//Do something here
}));
Edit: This doesn't work with eclipse, according to greg-449

Related

Way to create an exception when program forced to exit?

I'm trying to make a simple Java wordcounting program.
When it reads Microsoft Office files, it first reads the text of the XML files (Microsoft Office files are actually bundles of zipped xml files!) and then reads them to a folder called "converted".
I want "converted" to be deleted right after the program ends, so I added a
new File("converted").deleteOnExit();
which does that well.
However, if the user of the program presses Ctrl+C in the command prompt, then the program will exit early, and the folder will not be deleted.
I would like to know if there's a way to throw an exception if a program is exited. It seems unlikely, because a forced exit of a program will probably stop any code, but I was wondering if this is possible. Then, I'll be able to handle the exception and exit the program correctly, so that the directory will be deleted. I mean, I can add this:
catch(ExitException e) { // if the exception is called "ExitException"
System.err.format("Program ended unexpectedly.%n");
System.exit(-1); // this line so that the folder can delete
}
(The way I understand it, the folder is only deleted if a System.exit() is called. Correct me if I'm wrong.)
Thanks.
There isn't really a way to have it throw an exception on ^C (Control C), but you can have code run when the program is exited in any way as seen below.
Try using shutdown hooks: Runtime.getRuntime().addShutdownHook() should run even on ^C.
Note that this won't run under very specific cases as defined there (SIGKILL), but it will handle most lower things.
Try this instead (run it once at some point in your program):
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
new File("converted").delete();
} catch (Exception e) {
e.printStackTrace();
}
}
});
And get rid of your new File("converted").deleteOnExit();.

Interrupt java thread running nashorn script

In the code below i have javascript running in a separate thread from the main one. That script is an infinite loop, so it needs to be terminated somehow. How?
Calling .cancel() is not working AFTER the script begins running. But if i call .cancel() just after the thread initialization, it will terminate it (the commented out line).
package testscriptterminate;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.Timer;
import java.util.TimerTask;
public class TestScriptTerminate extends TimerTask{
private ExecutorService threads;
private Future runScript;
private Timer t;
public TestScriptTerminate(){
t = new Timer();
t.schedule(this, 6000); //let the script run for a while before attempt to cancel
threads = Executors.newFixedThreadPool(1);
runScript = threads.submit(new ScriptExec());
//runScript.cancel(true); //will cancel here, before the script had a change to run, but useless, i want to cancel at any time on demand
}
#Override
public void run(){
//after script has fully initialized and ran for a while - attempt to cancel.
//DOESN'T WORK, thread still active
System.out.println("Canceling now...");
runScript.cancel(true);
}
public static void main(String[] args) {
new TestScriptTerminate();
}
}
class ScriptExec implements Runnable{
private ScriptEngine js;
private ScriptEngineManager scriptManager;
public ScriptExec(){
init();
}
#Override
public void run() {
try {
js.eval("while(true){}");
} catch (ScriptException ex) {
System.out.println(ex.toString());
}
}
private void init(){
scriptManager = new ScriptEngineManager();
js = scriptManager.getEngineByName("nashorn");
}
}
So this is old, but i just wrote this up and thought it would probably be valuable to share. By default there is ~nothing you can do to stop a Nashorn script executing, .cancel() Thread.stop() Thread.interrupt() do nothing, but if you are willing to put in a bit of effort and are ok with rewriting some bytecode, it is achieveable. Details:
http://blog.getsandbox.com/2018/01/15/nashorn-interupt/
JavaScript (under Nashorn), like Java, will not respond to an interrupt in the middle of a tight loop. The script needs to poll for interruption and terminate the loop voluntarily, or it can call something that checks for interruption and let InterruptedException propagate.
You might think that Nashorn is "just running a script" and that it should be interrupted immediately. This doesn't apply, for the same reason that it doesn't apply in Java: asynchronous interruption risks corruption of the application's data structures, and there is essentially no way to avoid it or recover from it.
Asynchronous interruption brings in the same problems as the long-deprecated Thread.stop method. This is explained in this document, which is an updated version of the document linked in the comments.
Java Thread Primitive Deprecation
See also Goetz, Java Concurrency In Practice, Chapter 7, Cancellation and Shutdown.
The easiest way to check for interruption is to call Thread.interrupted(). You can call this quite easily from JavaScript. Here's a rewrite of the example program that cancels the running script after five seconds:
public class TestScriptTerminate {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
void script() {
ScriptEngineManager scriptManager = new ScriptEngineManager();
ScriptEngine js = scriptManager.getEngineByName("nashorn");
try {
System.out.println("Script starting.");
js.eval("while (true) { if (java.lang.Thread.interrupted()) break; }");
System.out.println("Script finished.");
} catch (ScriptException ex) {
ex.printStackTrace();
}
}
void init() throws Exception {
Future<?> scriptTask = pool.submit(this::script);
pool.schedule(() -> {
System.out.println("Canceling now...");
scriptTask.cancel(true);
}, 5, TimeUnit.SECONDS);
pool.shutdown();
}
public static void main(String[] args) throws Exception {
new TestScriptTerminate().init();
}
}
Since we're starting up a thread pool, might as well make it a scheduled thread pool so that we can use it for both the script task and the timeout. That way we can avoid Timer and TimerTask, which are mostly replaced by ScheduledExecutorService anyway.
The usual convention when handling and interrupt is either to restore the interrupt bit or to let an InterruptedException propagate. (One should never ignore an interrupt.) Since breaking out of the loop can be considered to have completed the handling of the interrupt, neither is necessary, and it seems sufficient simply to let the script exit normally.
This rewrite also moves a lot of work out of the constructor into an init() method. This prevents the instance from being leaked to other threads from within the constructor. There is no obvious danger from this in the original example code -- in fact, there almost never is -- but it's always good practice to avoid leaking the instance from the constructor.
Unfortunately it does not work for simple infinite loops: while (true) { }. I tried Thread.cancel(); does not cause the thread to exit. I wanted something foolproof for running scripts in an IntelliJ plugin where a user can make a mistake an cause an infinite loop, hanging the plugin.
The only thing I found to work in most cases is Thread.stop(). Even that does not work for a script like this:
while(true) {
try {
java.lang.Thread.sleep(100);
} catch (e) {
}
}
javascript catches the java.lang.ThreadDeath exception and keeps going. I found that the above sample is impossible to interrupt even with several Thread.stop() issued one after the other. Why would I use several? Hoping that one of them will catch the thread in its exception processing code and abort it. Which does work if there is something in the catch block to process as simple as var i = "" + e; that is enough to cause the second Thread.stop() to end it.
So the moral of the story is there is no fail safe way of ending a runaway script in Nashorn, but there is something that will work on most cases.
My implementation issues a Thread.interrupt(), then politely waits 2 seconds for the thread to terminate and if that fails then it issues Thread.stop() twice. If that does not work, then nothing else will either.
Hope it helps someone eliminate hours of experimentation to find a more reliable method to stop nashorn runaway scripts than hoping on the cooperation of the running script to respect Thread.cancel().
I have a similar problem where I let users write their own scripts.
But before I allow the script to be executed, I parse the script.
and if I find any of the following
(System.sleep. Exit, Thread.sleep, goto) etc
I don't even start the script, and I give user an error.
and then I do a search for all
(for,loops, while, doWhile), and I inject a method.
checkForLoop() just after the loop identifier.
I inject checkForLoop(); into allow user submitted script.
while(users code)
{
}
becomes
while ( checkForLoop() && users code )
{
}
This way before every iteration of their loop, my method is called.
and I can count how many times I was called or check internal timers.
Than I can stop the loops or timers from inside checkForLoop();
Honestly I think its a big security issue anyway, just to blindly let users write script and just execute it.
You need to build in a system that injects your code into their code loops.
Which is not that hard.
There are 100s of safety mechanisms you can apply to users submitted code, there is no RULE that says you need to run their code as is.
I have edited this answer to include a very simple example.
//Step 1
put the users submitted JS code into a Java String called userJSCode;
Step 2
//inject code at the start of their code.
String safeWhile ="var sCount=0; var sMax=10;
function safeWhileCheck(){ sCount++;
if ( return ( sCount > sMax )}";
userJSCode = safeWhile + userJSCode;
//Step 3: inject the custom while code
String injectSsafeWHile = "while( safeWhileCheck() && ";
userJSCode = userJSCode.replace("while(", injectSsafeWHile);
//Step 4: execute custom JS code
nashhorn.execute(injectSsafeWHile);
//Here is users bad submitted code, note no i increment in the loop, it would go on for ever.
var i=0;
while ( i <1000 )
console.log("I am number " + i);
using the steps above we end up with
var sCount=0;var sMax=10;
function safeWhileCheck(){
sCount++;
return ( sCount > sMax )};
var i=0;
while ( safeWhileCheck() && i <1000 )
console.log("I am number " + i)"
Here the while loop only executes a max of 10 times, so whatever you set the limit to.

How to findout main method has called by JVM or existing process?

Considering the following code
public static void main(String...arg){
//do something
if(<<the method has called by a new process>>){System.exit(0);}
else{System.setProperty("main_result","0");return;}
}
the main method would be called by a separated process by JVM or existing process, now how can I find it out?
Thanks in advance
Let's clarify: there might be another class with a main that was started, or the main is somehow called again.
Normally you want to call System.exit(0) (or return;?) but when called from the program itself you want to end in System.setProperty("main_result","0");.
public static void otherMain(String[] args) {
Main.main(args);
}
public static void main(String[] args) {
...
StackTraceElement[] elems = Thread.currentThread().getStackTrace();
//for (StackTraceElement elem : elems) {
// System.out.printf("%s%n", elem.getClassName());
//}
if (elems.length > 2) { // [0] Thread [1] main
System.setProperty("main_result","0");
}
}
In java, every Java process runs in its own JVM. So, the "same" main
method cannot be called by a different process under normal
circumstances
Even if you run the same program twice, they will be running in their
own JVMs.
You can try one thing.. Keep a static variable in your program, run it and
make it sleep for a long period of time (process 1).. Now, run the same
program again and update the static variable(runs in process 2).. See, whether it will be
updated in the first process (No, it won't be updated as each process will have it's own
set of variables..)
Do you really need it? Just don't use System.exit(0); and refactor main method to finish gracefully.
Calling System.setProperty in both cases - when run as new process and also as a class on classpath, will not make any difference.
Edit: Finding out who is calling the method is not easy and definitely bad practice.
I would refactor the code as follows:
public static void main(String...arg){
System.exit(doStuff(arg));
}
public static int doStuff(String... arg) {
//do something
}
To access this logic within the same JVM you can now call MyClass.doStuff and get the return value directly.
It would be better to consider refactoring and get rid of such problem.
Otherwise the following code can help:
if(Thread.currentThread().getStackTrace()[1].getClassName().equals(
System.getProperty("sun.java.command"))){
System.out.println("!");
}
Will not work if there is no "sun.java.command" property (on not Sun/Oracle JVMs it may absent)

Why static block are executed later?

P.S :
This question has been edited a few times as my previous code doesn't demonstrate the problem. There are some answers which may not make perfect sense against the edited question
I have a public class named Son.java
package com.t;
public class Son extends Father {
static int i;
static {
System.out.println("son - static");
i = 19;
}
{
System.out.println("son - init-block");
}
public static void main(String[] args) {
//Son s = new Son();
int a[] = new int[2];
System.out.println(a[5]);
}
}
class Father {
static {
System.out.println("f - static");
}
{
System.out.println("f - init-block");
}
}
When I run the program for the 1st time:
Output is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at com.t.Son.main(Son.java:19)
f - static
son - static
And later when I run this program (order of output is random)
Output is:
f - static
son - static
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at com.t.Son.main(Son.java:19)
I have read that static blocks are executed as the classes are initalised.
But why does the exception has come first here and then static block is executed?
I am using Eclipse too to run my program.
Can somebody explain?
The exception doesn't happen first, you are just seeing the printout of the exception first.
Had the exception happened first, you would never have seen the rest of the output.
The reason for this is that you have output to both System.err (from your exception) and System.out in your program. The order in which these are printed to the screen is not defined, so therefore you can get them in different order.
Stack traces of uncaught exceptions are printed in System.err, which is an unbuffered stream. You print text to System.out which is a buffered stream and it is unpredictable whether it he buffer gets flushed before or after the stack trace is printed.
If you change all your print statements to System.err then the order of the output will become the order of printing, and it will always be the same order.
#Keppil's answer has nailed it.
I just want to point out something ... erm ... interesting.
The OP says this:
I am using Eclipse to run my program.
The knee jerk response would be to say "that isn't relevant" ... but in this case, I think it >>is<< relevant. I suspect that non-determinism in stdout/stderr timing is being is amplified by the fact that the output is going to a Eclipse "console" panel.
When an application is run from the command line, output to stderr and stdout probably gets merged into out stream somewhere in the OS kernel. And if not, the console program probably uses a select syscall to handle input from two sources ... and gives one stream priority over the other, 'cos that is the easy way to code it. As a result, you would expect the output to appear on the console in a mostly consistent order, even though order is non-deterministic.
But when the application writes to an Eclipse console, Eclipse probably uses a separate thread to read each stream. Assuming that both threads are blocked in read syscalls, and input arrives at roughly the same time on both streams, it will be up to the thread scheduler to decide which thread gets woken first. That is going to be far less predictable that the behaviour of a select ... or of stream merging in the kernel.
Either way, my observation is that reordered stdout / stderr output is more prevalent with an Eclipse console than when you are using a "native" console.
As the asker said main belongs to Son class and is extending Father. I modified the code a little, so I was able to compile.
class Father {
static{
System.out.println("f - static");
}
}
public class Son extends Father {
static {
System.out.println("son - static");
}
public static void main(String[] args) throws ArrayIndexOutOfBoundsException{
int a[] = new int[2];
System.out.println(a[3]);
}
}
And the output is:-
f - static
son - static
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at kanwal.Son.main(Son.java:20)
Its working exactly, the way it is supposed to.
EDIT:-
This answer was made, before OP edited the question.

Lua / Java / LuaJ - Handling or Interrupting Infinite Loops and Threads

I'm using LuaJ to run user-created Lua scripts in Java. However, running a Lua script that never returns causes the Java thread to freeze. This also renders the thread uninterruptible. I run the Lua script with:
JsePlatform.standardGlobals().loadFile("badscript.lua").call();
badscript.lua contains while true do end.
I'd like to be able to automatically terminate scripts which are stuck in unyielding loops and also allow users to manually terminate their Lua scripts while they are running. I've read about debug.sethook and pcall, though I'm not sure how I'd properly use them for my purposes. I've also heard that sandboxing is a better alternative, though that's a bit out of my reach.
This question might also be extended to Java threads alone. I've not found any definitive information on interrupting Java threads stuck in a while (true);.
The online Lua demo was very promising, but it seems the detection and termination of "bad" scripts is done in the CGI script and not Lua. Would I be able to use Java to call a CGI script which in turn calls the Lua script? I'm not sure that would allow users to manually terminate their scripts, though. I lost the link for the Lua demo source code but I have it on hand. This is the magic line:
tee -a $LOG | (ulimit -t 1 ; $LUA demo.lua 2>&1 | head -c 8k)
Can someone point me in the right direction?
Some sources:
Embedded Lua - timing out rogue scripts (e.g. infinite loop) - an example anyone?
Prevent Lua infinite loop
Embedded Lua - timing out rogue scripts (e.g. infinite loop) - an example anyone?
How to interrupt the Thread when it is inside some loop doing long task?
Killing thread after some specified time limit in Java
I struggled with the same issue and after some digging through the debug library's implementation, I created a solution similar to the one proposed by David Lewis, but did so by providing my own DebugLibrary:
package org.luaj.vm2.lib;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
public class CustomDebugLib extends DebugLib {
public boolean interrupted = false;
#Override
public void onInstruction(int pc, Varargs v, int top) {
if (interrupted) {
throw new ScriptInterruptException();
}
super.onInstruction(pc, v, top);
}
public static class ScriptInterruptException extends RuntimeException {}
}
Just execute your script from inside a new thread and set interrupted to true to stop the execution. The exception will be encapsulated as the cause of a LuaError when thrown.
There are problems, but this goes a long way towards answering your question.
The following proof-of-concept demonstrates a basic level of sandboxing and throttling of arbitrary user code. It runs ~250 instructions of poorly crafted 'user input' and then discards the coroutine. You could use a mechanism like the one in this answer to query Java and conditionally yield inside a hook function, instead of yielding every time.
SandboxTest.java:
public static void main(String[] args) {
Globals globals = JsePlatform.debugGlobals();
LuaValue chunk = globals.loadfile("res/test.lua");
chunk.call();
}
res/test.lua:
function sandbox(fn)
-- read script and set the environment
f = loadfile(fn, "t")
debug.setupvalue(f, 1, {print = print})
-- create a coroutine and have it yield every 50 instructions
local co = coroutine.create(f)
debug.sethook(co, coroutine.yield, "", 50)
-- demonstrate stepped execution, 5 'ticks'
for i = 1, 5 do
print("tick")
coroutine.resume(co)
end
end
sandbox("res/badfile.lua")
res/badfile.lua:
while 1 do
print("", "badfile")
end
Unfortunately, while the control flow works as intended, something in the way the 'abandoned' coroutine should get garbage collected is not working correctly. The corresponding LuaThread in Java hangs around forever in a wait loop, keeping the process alive. Details here:
How can I abandon a LuaJ coroutine LuaThread?
I've never used Luaj before, but could you not put your one line
JsePlatform.standardGlobals().loadFile("badscript.lua").call();
Into a new thread of its own, which you can then terminate from the main thread?
This would require you to make some sort of a supervisor thread (class) and pass any started scripts to it to supervise and eventually terminate if they don't terminate on their own.
EDIT: I've not found any way to safely terminate LuaJ's threads without modifying LuaJ itself. The following was what I came up with, though it doesn't work with LuaJ. However, it can be easily modified to do its job in pure Lua. I may be switching to a Python binding for Java since LuaJ threading is so problematic.
--- I came up with the following, but it doesn't work with LuaJ ---
Here is a possible solution. I register a hook with debug.sethook that gets triggered on "count" events (these events occur even in a while true do end). I also pass a custom "ScriptState" Java object I created which contains a boolean flag indicating whether the script should terminate or not. The Java object is queried in the Lua hook which will throw an error to close the script if the flag is set (edit: throwing an error doesn't actually terminate the script). The terminate flag may also be set from inside the Lua script.
If you wish to automatically terminate unyielding infinite loops, it's straightforward enough to implement a timer system which records the last time a call was made to the ScriptState, then automatically terminate the script if sufficient time passes without an API call (edit: this only works if the thread can be interrupted). If you want to kill infinite loops but not interrupt certain blocking operations, you can adjust the ScriptState object to include other state information that allows you to temporarily pause auto-termination, etc.
Here is my interpreter.lua which can be used to call another script and interrupt it if/when necessary. It makes calls to Java methods so it will not run without LuaJ (or some other Lua-Java library) unless it's modified (edit: again, it can be easily modified to work in pure Lua).
function hook_line(e)
if jthread:getDone() then
-- I saw someone else use error(), but an infinite loop still seems to evade it.
-- os.exit() seems to take care of it well.
os.exit()
end
end
function inithook()
-- the hook will run every 100 million instructions.
-- the time it takes for 100 million instructions to occur
-- is based on computer speed and the calling environment
debug.sethook(hook_line, "", 1e8)
local ret = dofile(jLuaScript)
debug.sethook()
return ret
end
args = { ... }
if jthread == nil then
error("jthread object is nil. Please set it in the Java environment.",2)
elseif jLuaScript == nil then
error("jLuaScript not set. Please set it in the Java environment.",2)
else
local x,y = xpcall(inithook, debug.traceback)
end
Here's the ScriptState class that stores the flag and a main() to demonstrate:
public class ScriptState {
private AtomicBoolean isDone = new AtomicBoolean(true);
public boolean getDone() { return isDone.get(); }
public void setDone(boolean v) { isDone.set(v); }
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
System.out.println("J: Lua script started.");
ScriptState s = new ScriptState();
Globals g = JsePlatform.debugGlobals();
g.set("jLuaScript", "res/main.lua");
g.set("jthread", CoerceJavaToLua.coerce(s));
try {
g.loadFile("res/_interpreter.lua").call();
} catch (Exception e) {
System.err.println("There was a Lua error!");
e.printStackTrace();
}
}
};
t.start();
try { t.join(); } catch (Exception e) { System.err.println("Error waiting for thread"); }
System.out.println("J: End main");
}
}
res/main.lua contains the target Lua code to be run. Use environment variables or parameters to pass additional information to the script as usual. Remember to use JsePlatform.debugGlobals() instead of JsePlatform.standardGlobals() if you want to use the debug library in Lua.
EDIT: I just noticed that os.exit() not only terminates the Lua script but also the calling process. It seems to be the equivalent of System.exit(). error() will throw an error but will not cause the Lua script to terminate. I'm trying to find a solution for this now.
Thanks to #Seldon for suggesting the use of custom DebugLib. I implemented a simplified version of that by just checking before every instruction if a predefined amount of time is elapsed. This is of course not super accurate because there is some time between class creation and script execution. Requires no separate threads.
class DebugLibWithTimeout(
timeout: Duration,
) : DebugLib() {
private val timeoutOn = Instant.now() + timeout
override fun onInstruction(pc: Int, v: Varargs, top: Int) {
val timeoutElapsed = Instant.now() > timeoutOn
if (timeoutElapsed)
throw Exception("Timeout")
super.onInstruction(pc, v, top)
}
}
Important note: if you sandbox an untrusted script calling load function on Lua-code and passing a separate environment to it, this will not work. onInstruction() seems to be called only if the function environment is a reference to _G. I dealt with that by stripping everything from _G and then adding whitelisted items back.
-- whitelisted items
local sandbox_globals = {
print = print
}
local original_globals = {}
for key, value in pairs(_G) do
original_globals[key] = value
end
local sandbox_env = _G
-- Remove everything from _G
for key, _ in pairs(sandbox_env) do
sandbox_env[key] = nil
end
-- Add whitelisted items back.
-- Global pairs-function cannot be used now.
for key, value in original_globals.pairs(sandbox_globals) do
sandbox_env[key] = value
end
local function run_user_script(script)
local script_function, message = original_globals.load(script, nil, 't', sandbox_env)
if not script_function then
return false, message
end
return pcall(script_function)
end

Categories