public class LineNum1 extends Thread{
public synchronized void run()
{
try {
Hello.main(null);
System.out.println("Stack Trace of thread"+ this.currentThread().getName());
System.out.println(this.currentThread().getStackTrace()[1].getLineNumber());
System.out.println("End of Stack Trace");
} catch (Exception e1) {
e1.printStackTrace();
}
}
public static void main(String[] args) {
LineNum1 t = new LineNum1();
t.start();
}
}
I'm developing a code coverage tool.
Using the above program I'm executing Hello.java from here. Is there any method where I can get the control over Hello.java?
Or to make my life simpler can i get the line numbers of the executed lines(Execution path) of Hello.java?
You want to use the Java Debug Interface. It's the Java library that is used for writing Java tools like debuggers. It'll allow you to step through the program, query for line numbers and whatnots as you go.
There's a simple demo application for it called trace that does most of what you want already: http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/trace.html
There's a lot of documentation for it, if you've got the time to read it:
http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/index.html
You can probably execute the second Java class as a Process and read the output yourself.
I have not completed the code coverage completely yet. But I have used bytecode instrumentation to instrument the methods, hence i get the log of all the methods I've visited. This Javassist Turtorial might help you.
Related
I am using below script(.sh file) to run a java code in an UNIX system,but even if Java is giving exception or terminated successfully in both cases,
exit code coming as 0, I want to return non zero exit codes from script, if Java run throwing an exception, so that I can add if-then check in script,to print success or failure messages.
#!/bin/sh
echo 'processing started -->>'
LOC=/opt/appl/Mapping/
export JAVA_HOME=/usr/java6
export PATH=/usr/java6/bin
LD_LIBRARY_PATH=/opt/appl/JARS/
export LD_LIBRARY_PATH
java -classpath $LOC/ojdbc6-11.2.0.3.0.jar:$LOC/ds35-02.00.11.jar:$LOC/log4j-1.2.17.jar:$LOC/TestClasses.jar:$LOC/db2jcc_license_cisuz-3.0.0.jar:$LOC/db2jcc_license_cu-3.0.0.jar:$LOC/db2jcc-3.0.0.jar -Xms256M -Xmx512M com.home.backfill.TestRun
I can use Try-catch in Java file and use System.exit(1) at catch block, but I am looking for any good generic approach, as My code could be very long, not sure if it would be good idea to put System.exit(1) in every catch block.
If you want something generic:
interface ExceptionAction {
public void apply() throws Exception;
}
class Catcher {
public static void invoke(ExceptionAction ea) {
try{
ea.apply();
} catch(Exception e) {
System.exit(1);
}
}
}
Then invoke by creating lambdas. (You will have to set any 'return' value to a captured local variable):
Catcher.invoke(() -> {
/// your code here
});
I would note that this is about as verbose as try/catch though, and the latter is probably more readable/colloquial.
If I understood you correctly, why don't you ran a generic function that determines what kind of code to return?
try {
//your code here
} catch(YourException e){
Handler.handle(e);
}
Where Handler.handle(e) takes an exception and determines the Integer with which to shutdown the system. At least there you have a centralized point of where the system will shutdown.
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)
I'm running into the strangest error in this program, which is confirmed when debugging it. I have the following code (boiled down to highlight the problem, of course):
BHFrame.java
public class BHFrame
{
private boolean uSS;
private StateSaver stateSaver;
public BHFrame(boolean useInternalStateSaver)
{
//Init code
uSS = useInternalStateSaver;
//More init code
System.out.println(uSS);
if (uSS)
{System.out.println("Entered 1");
stateSaver = new StateSaver(title, false);
stateSaver.addSaveable(getThis());
}
//More init code
System.out.println(uSS);
if (uSS)
{System.out.println("Entered 2");
try
{
stateSaver.loadState();
stateSaver.putState(getThis());
}
catch (IOException ex)
{
alertUserOfException(ex);
}
}
}
}
GUI.java
public class GUI extends BHFrame
{
public GUI(boolean useInternalStateSaver)
{
super(useInternalStateSaver);
}
}
Main.java
public class Main
{
public static void main(String[] args)
{
GUI gui = new GUI(false);
}
}
Output
false
false
Entered 2
Exception in thread "main" java.lang.NullPointerException
at bht.tools.comps.BHFrame.<init>(BHFrame.java:26)
at bhms.GUI.<init>(GUI.java:5)
at bhms.Main.main(Main.java:5)
The class BHFrame is extended and run from a child class that calls this constructor, but that really shouldn't affect this behavior. The problem is that, when false is passed to the constructor as useInternalStateSaver, the first if (uSS) is skipped, but the second is entered. Upon debugging, I found that uSS is false throughout runtime, including on the line of the second if statement, here. Why would Java enter an if statement when the condition returns false? Before you ask, I did delete the .class files and recompile it just in case there was some residual code messing with it, but I got the same result. And rest assured, all the references to the uSS variable are displayed here.
Solution
As it turns out, this appears to be a bug in NetBeans 7.1 Build 201109252201, wherein the IDE doesn't properly insert new code into the compiled .class files. The problem was fixed by compiling the files externally. A bug report has been submitted.
Whatever's throwing that exception is probably not in your posted code.
It's not being caught by your catch statement, which only catches IOException.
It's a NullPointerException and can occur anywhere.
You have shown no indication that the code inside your if block is actually executing. In your screenshot, there is absolutely know way of knowing if your if block is entered or not. There are no logging statements.
Add debugging messages at various points to see exactly what is happening. Or, you know, look at line 26 (wayyyyy before your posted code) to see why you're getting a NullPointerException.
I've seen crazy stuff like this when there is bad RAM on the machine. You might want to run memtest86.
You might also consider deleting all of your project class files, and then doing a build. Maybe you changed Main.java, but it was never recompiled. I hate that when that happens.
This is just a guess, because I can't see the code you are mentioning, but I reckon you have defined a local variable uSS in the second //More init code segment.
Once you define a local variable named the same as an instance variable, it 'hides' the instance variable. Better to qualify all instance variables with this.
So, try qualifying all above accesses of uSS with this. ... (this.uSS)
Even if this isn't the issue, it might be better to post the full code anyway.
HTH
In Matlab, when a Java exception is thrown by a Java method invoked from M-code, it is converted to a Matlab error or MException, and the Java stacktrace is included in the MException's message. On Windows, the stacktrace is displayed double spaced. Here's an example.
package test;
public class Bummer {
public static void a() { b(); }
public static void b() { c(); }
public static void c() { d(); }
public static void d() { throw new RuntimeException("bummer"); }
}
Which produces this.
>> test.Bummer.a()
??? Java exception occurred:
java.lang.RuntimeException: bummer
at test.Bummer.d(Bummer.java:8)
at test.Bummer.c(Bummer.java:7)
at test.Bummer.b(Bummer.java:6)
at test.Bummer.a(Bummer.java:5)
>> disp(find(lasterr == sprintf('\r')))
61 95 129 163 197
This hurts readability, especially when you have a twenty call deep stack.
I believe this is because the stacktrace part of the error message is being constructed with DOS mode CRLF (\r\n) line endings. Which makes sense on a Windows machine. But the Matlab command window is kind of Unix mode, and converts \r\n to two line feeds.
Our current workaround is to use try/catch guard code like this around most Java method calls.
try
somejavaobject.SomeMethod();
catch err
rethrowmsg(err, 'Some additional details');
end
Rethrowmsg() is a function we wrote that munges err to convert \r\n to \n, incorporates additional details in the message, and then calls RETHROW.
Adding the workaround is a bit tedious and prone to be left out. And if you're doing "dbstop if all error", it won't fix the display of the error at that point. In the end, this is a minor annoyance, but when you spend all day debugging Matlab code, it adds up. And I'm curious about the Java exception/MException integration mechanism.
Is there a way to configure Matlab to construct the stacktrace part of the error message text with \n line separators so it displays single-spaced in the command window?
When the MATLAB Runtime intercepts the java exception, it uses the system line endings when it wraps it in a MException. To get around it, you can throw the exception on a different thread, or send the stack trace directly to stderr, such as with printStackTrace():
public class Bummer {
public static void a() { b(); }
public static void b() { c(); }
public static void c() { d(); }
public static void d() { new RuntimeException("bummer").printStackTrace(); }
}
Of course, it is a very bad thing to get a java exception in MATLAB. If you're using exceptions for things that are not really exceptional, then you may want to consider wrapping with a MException your users will find useful.
If you're using the exceptions to debug your java code, I find the stack trace analyzing functions of most java IDE's are able to deal with the extra line breaks nicely.
Try setting:
java.lang.System.setProperty('line.separator', sprintf('\n'));
Does using the FORMAT command improve the display at all? This helps display variables in a more compact form:
format compact
It may help display error messages in a more compact form too.
Does enyone know if it is possible to launch a java application in Eclipse but in a loop.
I need to execute a application all the night.
If I try tu run it in win console, it is complicated, I have ti specify a bunch a parameters.
Wrap your main in a call to Runtime.exec and put that in a loop.
public static void main(String args[]){
while(true){
Process proc = Runtime.getRuntime().exec("java yourclasshere");
try{
proc.waitFor();
} catch (InterruptedException e) {}
}
}
Just run the way you would run a regular Java program, in a loop:
public class MyProgram {
public static void main(String[] args) {
// your infite, of finite loop goes here
}
}
And then, just run it, and if there are not unhandled exceptions, it will run all night indeed.
Eclipse is a development environment, not an application manager. It's not well suited for what you're asking to do. It might be best to learn what those parameters are and why you need them, and write a batch file to handle them for you. There might be a better answer if you provide more details.