InvalidStackFrameException After Calling Method via ObjectReference#invokeMethod - java

I am currently working on an Eclipse plugin which enhances the debugging possibilities. During the debugging session, I invoke a Scala method via com.sun.jdi.ObjectReference#invokeMethod like that:
public int callMethod_Reactive_Level(final ObjectReference o) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException {
final Method m = apiValues.getMethod_Reactive_level(o); // com.sun.jdi.Method
final IntegerValue intVal = (IntegerValue) o.invokeMethod(thread, m, new LinkedList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);
return intVal.intValue();
}
After doing that, a call to org.eclipse.debug.core.model.IVariable#getValue leads to an InvalidStackFrameException. The whole error message is:
Status ERROR: org.scala-ide.sdt.debug code=5010 Exception while retrieving variable's value com.sun.jdi.InvalidStackFrameException
The message Exception while retrieving variable's value is shown when I inspect a variable in the variables view after calling a method as shown above.
Any idea how this problem can be solved? I do not understand why this is so problematic, since the JDI explicitely provides the possibility to do that.
Update: Since it may be a bug in the Scala IDE, there is a discussion and a tutorial how to reproduce the issue in the Scala IDE dev group.

The error message seems to come from the Scala IDE implementation of IVariable.getValue. It delegates to the JDI StackFrame.getValue, which throws. According to the docs, this can happen "if this stack frame has become invalid. Once the frame's thread is resumed, the stack frame is no longer valid."
My guess is that executing an invokeMethod on the same thread invalidates the stack frame.

Related

NoSuchMethodError when calling getDeclaredAnnotation()

I have a running application where once I clicked on a 'Edit' link of a table, I'm getting an error in the log of NoSuchMethodError and the control stays in the current page, not proceeding to the edit page.
Below piece of code has been hit while getting the error;
Field[] fields = entityObj.getClass().getDeclaredFields();
for(int i=0;i<fields.length;i++){
Field field =fields[i];
field.setAccessible(true);
if(field.getDeclaredAnnotation(EmbeddedId.class)!=null){
return true;
}
}
return false;
In the above code at the line,
if(field.getDeclaredAnnotation(EmbeddedId.class)!=null)
I'm getting the particular error.
Also mentioning the log as below;
Caused by: java.lang.NoSuchMethodError: java.lang.reflect.Field.getDeclaredAnnotation(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
at com.sprint.neo.querymodel.common.QueryObjectUtil.checkEnitityIsHasEmbeddedId(QueryObjectUtil.java:131)
at com.sprint.neo.querymodel.common.EntityManager.getEntityObject(EntityManager.java:89)
at com.sprint.neo.querymodel.common.EntityManager.loadEntityObject(EntityManager.java:72)
at com.sprint.neo.querymodel.common.EntityManager.entityload(EntityManager.java:60)
at com.sprint.neo.querymodel.common.EntityManager.loadAndGetEntityObject(EntityManager.java:56)
at com.sprint.neo.querymodel.common.QueryObjectUtil.getListOfEntityObject(QueryObjectUtil.java:718)
at com.sprint.neo.querymodel.common.QueryObjectCache.excuteUpdate(QueryObjectCache.java:251)
at com.sprint.neo.querymodel.common.QueryObjectRow.excuteUpdate(QueryObjectRow.java:298)
at com.sprint.neo.engine.controller.actions.TaskViewEditAction.edit(TaskViewEditAction.java:83)
The control should proceed to the edit jsp page as all the jsp are implemented correctly.
What I'm doubting about the error from the log is that, if any jar file is missing regarding Reflection api.
Please suggest me a solution to overcome this problem. Any valuable advise will be helpful. Thanks a lot.
You are using the method Field.getDeclaredAnnotation(Class). This method was introduced in Java 8. It is not available in Java 7 and earlier. You need to upgrade your JDK.
Field is a subclass of AccessibleObject and inherits the method from that class. See the Javadoc: It says “Since: 1.8” which is the version for Java 8 in the internal numbering scheme.

How to execute a void method automatically when a breakpoint is hit?

I'm using latest IntelliJ IDEA Ultimate 16 EAP. I have some code in a library that initializes an object with some setters:
X createSomething() {
X x = new X();
x.setY(z);
return x; // breakpoint on this line
}
I'm looking to modify this returned value's state from the debugger: calling x.setY(y). I tried with conditions, because I want it to happen on every hit of the breakpointstopping at the breakpoint and using the "Evaluate Expression" window is unfeasible.
It's not possible to do this in any of the normal object oriented ways (e.g. overriding that method), nor it is possible to capture the result outside the method and modify it there because it's deep within many calls.
Here are my tries that all failed due to no support for those language features in the debugger. They failed with a dialog asking "Would you like to stop at the breakpoint?". The language level is fixed at Java 6-7 because I'm developing for Android.
Try 1: Call the method
Problem processing VM event:
Breakpoint: 'Line 9 in ClassName.createSomething() (package)'
Error: Failed to evaluate breakpoint condition 'x.setY(y)'
Reason: Boolean value expected
Also tried variants like: x.setY(y); false;, but it needs to be an expression.
Try 2: Call the method using lambda
Problem processing VM event:
Breakpoint: 'Line 9 in ClassName.createSomething() (package)'
Error: Failed to evaluate breakpoint condition '() -> { x.setY(y); return false; }'
Reason: Lambdas evaluation is not supported
Try 3: Call the method to have a boolean expression
Problem processing VM event:
Breakpoint: 'Line 9 in ClassName.createSomething() (package)'
Error: Failed to evaluate breakpoint condition 'new java.util.concurrent.Callable<Boolean>() { #Override public Boolean call() { x.setY(y); return false; } }.call()'
Reason: Anonymous class evaluation is not supported
Try 4: Call a static method (working workaround)
I found a workaround that I want to share, but I'm still looking for a better solution if anyone knows one: that doesn't require recompiling and restarting.
Create a method in a class:
public class SomeClass {
public static boolean fixX(X x) {
x.setY(y);
return false; // don't actually stop on the breakpoint
}
}
In the breakpoint condition add
full.pkg.SomeClass.fixX(x)
This works, but any time you want to modify the condition you'll have to restart the app. Parametrized fixX(x, changeAbleY) is a solution to that.
Make sure to disable or remove the breakpoint to prevent headaches by modified behavior when debugging unrelated issues.
Steps:
Right click on the breakpoint
A tool popup will open, in that popup click on "More" link at the bottom then a window will open.
Now check "Log evaluated expression" checkbox in that window and enter your method call in the given text box e.g methodName().
Click OK and start debugging.
When the breakpoint will hit your method will get called before that line's execution.
Reference: https://www.jetbrains.com/idea/help/configuring-breakpoints.html
Screenshot: Screenshot of breakpoint configuration window.
IntelliJ has a feature to add "Watches" where you can execute your void method but that's manual, not automatic.

ProgramCallDocument connecting to AS400 from Groovy Hangs

This question is specifically related to the JT400 class ProgramCallDocument, with it's method callProgram(String ProgramName)
I've tried wapping the call in a try/catch - but it's not throwing an exception, the debugger goes into the callProgram method, and just sits there indefinitely.
A small amount of specific information about the API is available here:
http://publib.boulder.ibm.com/infocenter/iadthelp/v7r0/index.jsp?topic=/com.ibm.etools.iseries.toolbox.doc/rzahhxpcmlusing.htm
Here's the code that I'm running:
AS400 as400System = AS400Factory.getAS400System()
ProgramCallDocument programCallDocument = new ProgramCallDocument(as400System, "com.sample.xpcml.Sample.xpcml")
programCallDocument.setStringValue("sampleProgramName.value", sampleValue)
Boolean didProgramCallDocumentRunSuccessfullyOnTheAS400 = programCallDocument.callProgram("sampleProgramName")
The last line of that snippet is the one that just sits there. I left out the try/catch for brevity.
The XPCML file that the ProgramCallDocument constructor uses is just a proprietary XML format that IBM uses for specifying the parameter lengths and types for a program call. I can come back and add it in if it would be helpful, but the ProgramCallDocument constructor runs validation on the XML, and it didn't come up with any validation errors. I'm not familiar with JT400, or how it does Program Calls, so any assistance would be wonderful.
As a further note, doing some more digging on a related issue today I also found this SO post:
Monitor and handle MSGW messages on a job on an IBM i-series (AS/400) from Java
I think it's relevant to this question, because it's about ways to trap MSGW status on the Java/Groovy side.
It's very likely the called program went into a MSGW status (error).
Check WRKACTJOB JOB(QZRCSRVS) to find the program call job and see the status as well as review the job log.
It may be easier to call a native program using the CommandCall class or as a JDBC stored procedure.
Here's an example of the CommandCall usage in Groovy:
sys = AS400Factory.AS400System
cmd = new CommandCall(sys)
if (!cmd.run "CALL MYLIB.MYPGM PARM('${sampleValue}')") {
println cmd.messageList
}

Java Reflection permission error

I'm trying to load a class via an URLClassLoader (well, it neither works with an normal class loader) and want them to not have any permission.
Therefore, i created my own security manager, which genereates a key on startup, which can only by requested once (in main thread).
The security manager has 2 lists, the applicationThread, which will be granted any right and the temporaryList, which will be granted one right just once (it's about the reflection).
As it is very hard to descripe, i decided to upload the whole thing: look at the link below
Ok, coming back: I created a WatchDog thread, which checks if the thread doesn't take too much time.
When i now start to instance two classes from an URLClassLoader, I call exactly 30 methods without getting any errors, but on the 31st call, it tries to check Permissions for the following but this is just happaning after the 30th call.
java.lang.RuntimePermission accessClassInPackage.sun.reflect),
Does anyone know what's going on there?
edit:
I had time to strip down the example.
http://myxcode.at/securitymanager.zip
I found out, that the SecurityManager is not asked synchronous. Just run this small piece of code and have a look at the red lines.
If the red lines come in the very first line, just run the program again, you will find out that it seems a little bit uncontrolled.
The problem more or less is, that i need the security manager to be synchronized.
Here is my output for those who cannot face the error(bug?)
http://pastebin.com/E9yLRLif
edit2: maybe its about the console? maybe the console is too slow?
For me the check occurs when i=15:
checkPermission ( (java.lang.RuntimePermission accessClassInPackage.sun.reflect) ) for Thread[main,5,main]
The reason for the delayed permission check is an inflationThreshold of the ReflectionFactory class which is used by the invoke method of NativeMethodAccessorImpl.java:
public Object invoke(Object obj, Object[] args)
throws IllegalArgumentException, InvocationTargetException {
if (++numInvocations > ReflectionFactory.inflationThreshold()) {
MethodAccessorImpl acc = (MethodAccessorImpl) new MethodAccessorGenerator()
.generateMethod(method.getDeclaringClass(), method
.getName(), method.getParameterTypes(),
method.getReturnType(), method
.getExceptionTypes(), method
.getModifiers());
parent.setDelegate(acc);
}
return invoke0(method, obj, args);
}
To disable the delay you could use Reflection API :)
Field hack = Class.forName("sun.reflect.ReflectionFactory").getDeclaredField("inflationThreshold");
hack.setAccessible(true);
hack.set(null, 0);

What is this java.awt.event error?

ANSWER:
If you ever see these lines and are mistified like I was, here's what they mean.
Thread[AWT-EventQueue-0] (Suspended (exception NullPointerException))
EventDispatchTread.run() line: not available [local variables unavailable]
It's not that the variables are unavailable because they are lurking behind a shroud of mystery in a library somewhere dank. No no, they just went out of scope! It's still your fault, you still have to find the null, and no you can't blame the library. Important lesson!
QUESTION:
One of the most frustrating things for me, as a beginner is libraries! It's a love/hate relationship: On the one hand they let me do things I wouldn't normally understand how to do with the code that I do understand, on the other hand because I don't completely understand them, they sometimes throw a wrench in code that is otherwise working fine! It's because I don't understand the errors that can occur when using these libraries, because I didn't write them, and because eclipse doesn't give me a great deal to go with when one of imports starts acting up...
So here's the problem: I've been working with java.awt.event to handle a bunch of JButtons on the screen for this and that. I get an error when I use one of the buttons I've made. The error is:
Thread[AWT-EventQueue-0] (Suspended (exception NullPointerException))
EventDispatchTread.run() line: not available [local variables unavailable]
What does this mean? What could be causing it? I'm embarrassed to post code, but if you can stand to try to decipher my terrible style, here is the method that seems to cause this error to be thrown.
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String name;
code...
if(cmd.equals("Play")) {
name = field.getText();
card = getCard(name);
if(card != null) {
if(rules.zoneHasCard(card, rules.hand)) {
display.updateStatusMessage(rules.play(card));
field.setText("");
display.updateHand(rules.zoneList("hand"));
display.updateDiscard(rules.zoneList("Discard")); // This is the error here! The discard Zone was empty!
}
else {
field.setText("You do not have " + card.getName());
field.selectAll();
}
}
else {
field.setText("That cardname is unused");
field.selectAll();
}
}
}
Welcome to the complexity of writing GUI code.
When you run a Swing program, a background thread called the Event Dispatch Thread is created. When the user clicks on a JButton, for example, JButton creates and fires an event using this Event Dispatch Thread. Hence the name: it's the thread that dispatches events!
Your code:
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String name;
// more code...
}
is called by this Event Dispatch Thread, so your code can handle the event.
Somewhere within your code you are trying to do something with a variable that is currently equal to null. The error message is telling you, "hey while running some code on the event dispatch thread, I encountered a NullPointerException" in your code.
Why are you not receiving more info? Possibly you configured Eclipse not to include debug info when compiling?
For now, I recommend adding some lines to your actionPerformed method to show the state of variables:
System.out.println("field = " + field);
System.out.println("rules = " + rules);
System.out.println("display = " + display);
See if this shows you any nulls.
Even if the NullPointerException comes from a library, the stack trace will show which line of your code called that library. But only if you've configured Eclipse to generate debugging info.
In the longer term, work through the Sun's Swing Tutorial to learn more about these issues.
Any method call on a null object will raise a null pointer exception.
In your code, rules, name or display could be null and cause an exception.
Use a debugger (such as the one included in the eclipse IDE) and set a breakpoint at the start of the actionPerformed() method, then step through it line by line to see when a variable you try to invoke a method on is null.
Just don't stop reading the stack trace after two lines. Somewhere in the stack trace you'll recognise the name of one of the classes/methods which you did write. Start looking there. (btw, people spend way to much time inside debuggers :-))
You might have forgotten to actually set an ActionCommand.
In the ActionEvent API Doc there's a note regarding possible null results of getActionCommand().

Categories

Resources