Writing a custom eclipse debugger - java

EDIT: There must be some way I can approach this without writing a whole new debugger. I'm currently looking into ways to build on top of the existing java debugger. If anyone has any ideas on how to grab information the Java debugger already has (about stack frames, variables, raw data etc.), that would be really helpful.
--
What I'm trying to do is I have this framework/API built on Java, and I would like to write an eclipse plugin debugger that is customized to my framework. Here is a simple example:
I have two classes, one called scope and one called variable. The scope holds a map of variables. The code is all in java, but I'm using this scope-variable relationship almost like a new language, and would like a variable debug tab that gives me a list of currently active scopes with the variables that are currently stored inside. Here is some code:
import java.util.Hashtable;
public class Scope {
private Hashtable<String, Variable> variableList = new Hashtable<String, Variable>();
// constructor
public Scope(){
}
public void put(String key, Variable v){
variableList.put(key, v);
}
public Variable get(String key){
return variableList.get(key);
}
}
public class Variable {
private String value;
private String name;
public Variable(String aName, String aValue){
name = aName;
value = aValue;
}
public String getValue(){
return value;
}
public String getName(){
return name;
}
public void setValue(String aValue){
value = aValue;
}
}
This is obviously an extremely simple example, but I would like to accomplish something similar to this where I can get a variables window, set a breakpoint, and have a "debugger" list out my active scope objects and the variable objects inside.
I've been trying to read and understand: http://www.eclipse.org/articles/Article-Debugger/how-to.html
and its pretty dense (as well as extremely outdated), but I will try to take some time to understand it. I just wanted to see if anyone had any high level recommendations on how to approach this type of problem, as I have little experience developing plugins in eclipse or making debuggers.
Thanks!

Not an easy task. That article is still the main reference, I think. Old, but not outdated. Try to digest it, and preferably to make it work. Before it, you should have a minimal experience developing Eclipse plugins.
There are many pieces in the picture, but the first thing you must understand is that when Eclipse is debugging something (assuming we are using the standard debug model), we have two separate "worlds": the Eclipse side, and the interpreter side (or, if you prefer, the "local" and "remote" sides).
Int the Eclipse side, the programming involves a cooperation between some Eclipse core classes and some classes of your own, which extend or implement some Eclipse classes/interfaces:
A "launchConfigurationType" (extension point in your plugin.xml) which causes the apparition of a new custom configuration when you click "Debug As -> New Configuration); this goes togetther with some "launchConfigurationTabGroups" definition that defines the "Tabs" dialogs that will appear in your custom launch configuration (eg) (each Tab will have its own class typically).
The launchConfigurationType is typically associated to a LaunchDelegate class, which is sort of your bootstrap class: it has the responsability of creating and starting a running/debugging instance, both on the Eclipse side and on the "interpreter" (or "remote") side.
On the Eclipse side, the running/debugging instance is represented by a IDebugTarget object and its children (the implementation is your responsability); this is created by the LaunchDelegate and "attached" to the remotely running process at launching time.
The remote side, the interpreter or program you are actually debugging, can be anything: a binary executable, a perl script, some app running in a some site (perhaps also a local Java program; but, even in this case, this would probably run in its own JVM, not in the debugging Eclipse JVM!). Your IDebugTarget object must know how to communicate to the "remote interpreter" (eg, by TCP) and perform the typical debugger tasks (place breakpoints, step, run, ask for variables, etc) - but the protocol here is up to you, it's entirely arbitrary.
What is not arbitrary is the hierarchy of your custom classes that the running Eclipse debugger will use: these should have a IDebugTarget as root, and should implement "The debug model" (see figure in article). As said above, the IDebugTarget object is who understands how to make the translation between the EClipse side and the remote side (see this image)

having worked on the eclipse edc debugger, it sounds like writing a whole debugger is not so much what you want.
it sounds like while running the debugger, you will have access to the objects that have the variables and scopes you are interested in.
you can use toString() in the classes themselves or use detail formatters to display a variation on the information you want. the toString() call can get quite detailed and nest into calls, show whole arrays, etc. detail formatters can also be quite complex.
see http://www.robertwloch.net/2012/01/eclipse-tips-tricks-detail-formatter/ . it's the best of several URLs (i have no association with the author).
once you are happy with the output of the Variable and Scope objects, you should be able to add watch expressions that will always show them in your expressions window (thus you don't have to rely on local variables in the stack frame you may be in).
this should then give you the list of Variables and Scopes from your framework that you are tracking … hopefully without having to write an entire eclipse debugger plugin to do so.

ok, i'm going to add a second answer here … i guess i'm not familiar enough with the state of your environment to know why custom detail formatters would not do the trick. for most cases, i think they'll provide you what you're looking for.
but if you're really interested in creating another view holding these items, then you could check out the eclipse jdt project . it's entirely possible that the extension points it provides will give you access to the internal variables and stack-frame information that you're looking to add, and also perhaps some UI that will make your job easier.
in other words, you might not have to write an entirely new debugger plugin, but perhaps a plug-in that can work together with jdt.
the site has pointers to the project plan, source repositories, the bugzilla issue tracking database (used for both bug-tracking and new feature discussion). perhaps some of those who are experts on jdt can help weigh in with their opinions about what will best suit your needs.

Related

How can I generate and compile Java files in Android at Runtime

I know with javax.tools.* it is possible, but since this is not included in the Android API, I'm desperately wondering, is this possible?
Right now, my goal is to create a drag-and-drop tool to allow users to create their own layouts (as not everyone wants to learn Mobile Development, as it requires a lot of time, dedication and practice) similar to how Android Studio does it's own. However, of course the most important thing is to implement functionality via onClickListener and onTouchListeners. I've begun remedying this by creating my own DSL (Domain-Specific-Language) with a GUI front-end allowing users to choose what they want via PopupMenu and SubMenus. For example...
Statements
{ if, for, while }
Statements must be followed immediately by a reference and then a conditional (obtained from that reference), like a "if(Object.conditional())" statement.
References
{ Object1, Object2, Object3 }
The objects are references to other Views (I.E, Buttons, Layouts, WebView, etc.).
Conditionals|Actions|Getters|Setters
{ isSomething(), doSomething(), getSomething(), setSomething() }
Each Reference's methods, wrapped so that each wrapper keeps track of it's method's attributes and description (hence documentation).
It would go something like such...
IF ImageView1.isVisible()
ImageView1.setVisible(false)
ELSE
ImageView1.setVisible(true)
Of course, the method setVisible(boolean) is a wrapped version of setVisiblity(int).None of this is typed, it is obtained from a simple PopupMenu which shows them the applicable selections based on current context.
How I plan on transcribing this to compiling code was to convert the statement into Java code, inserting references on the fly as they are needed (I.E, ImageView1 would be defined in java as private ImageView ImageView1;), generate methods somewhat similar to how ButterKnife generates it's extra classes for it's onClick and onTouch annotations, etc.
Then, after planning all of this (been working on it for 2 weeks now), I find out that Android does not have support for compiling code like this. Please tell me something like this is possible. It's something I 100% wanted to do. Is this possible with any third party libraries?
If not, is there some possible way to mimic doing so? I could do it the long and slow way, of preparing every such possible way, keeping track of the references myself through a map, and when it is about to be called, directly call the implemented method for the View associated with that key, which theoretically COULD work. In fact, that'd be my second go-to if I can't. It'd be messy though.
Sorry if this is too long, I just want to get this to work.
TL;DR: Is there a way to compile a generated Java file created at Runtime in Android (since javax.tools.* does not exist), and if not what would be the best way to do so?

Pull a real object from IVariable object representations

I'm currently implementing a IDebugContextListener class (part of the eclipse developer tools API/library) to listen to event changes in the debugger. The method that makes this happen is:
private void contextActivated(ISelection context) {
if (context instanceof StructuredSelection) {
Object data = ((StructuredSelection) context).getFirstElement();
if (data instanceof IStackFrame) {
reciever.setStackFrame((IStackFrame) data);
} else {
reciever.setStackFrame(null);
}
}
}
Basically the debugger is giving my program IStackFrame's, which have IVariables inside, which gives a model of what is going on in the program that is being debugged. These as far as I can tell are data representations of true variables that is running on the program that is being debugged. The IVariables are limited in their functionality, as they can do basic things such as get the name of the variable they represent and get the type etc.
This might not be possible but is there any way I can get a copy of the actual object that it represents rather than the IVariable data representations using the IDebugContextListener class?
My purpose is I want to use the internal functions of the objects. With IVariables I can only get access to properties of the variables inside the objects.
The IVariable/IValue interface provides a generic, language-independent way of getting debug information. This means, it is not really possible to get the current values directly from the debugger using these values.
However, the language environment, such as JDT provide a second, language-specific layer that helps getting that information, in case of JDT see org.eclipse.jdt.debug project.
For a more detailed sample to get values of the Java debugger, please see the source code of the Inspect action. Basically, this code shows how to communicate with the debugged JVM.
Warning: the solution presented here may rely on internal code from JDT (possibly still usable outside the jdt plug-ins); and communicating with the other JVM can be quite slow. Be careful.
The IDebugContextListener actually returns an IStackFrame that has a collection of IVariables that are specifically implementing the IJavaVariable interface. Knowing this, we can get an IJavaValue from the IJavaVariable, which can in turn be casted into an IJavaObject.
The IJavaObject provides a method called sendMessage(), where you can communicate with the debugger JVM to have methods on the stack be executed and return back an IValue of the return value of the method.
This is how I managed to solve this problem.

detect the end of the bootstrapping phase of the JVM

Is there a way to detect the end of the bootstrapping phase of the JVM?
edit::
so to provide a bit more context, what i am trying to do is to instrument the JDK. And this is a full blown instrumentation that records every LOAD, STORE, INVOKE byte code instruction. As the instructions are executed their data is sent to a static method, that is loaded from the xbootclasspath. This static method captures all this information and stores all of this as a trace for performing analysis at a later time.
Now, when i do this for the JDK, i do not want to disturb the way classes are loaded in the JVM, which might result in a program crash. I was guessing that the best way to go about it is to detect the point in time when the JVM is done bootstrapping, so that I can safely turn on my instrumentation thereafter. (I plan to not instrument any of the code, while the bootstrapping is taking place.) Is this even the right way to go about it?
In addition to my previous comment about looking into FERRARI and MAJOR I want to say several things:
Both tools are only available for download as compiled Java JAR archives.
So I wrote to the scientists who have created those tools today and asked them our question. As soon as I will receive an answer I will report back here.
Anyway, I have looked into FERRARI's architecture and think I may have found out how they do it.
So here is my educated guess (still untested) about what you could do:
Instrument your JDK classes.
Add one simple class BootstrapLock as described below.
Re-pack the instrumented + the new class into a modified rt.jar.
Write a little dummy Java agent as described below.
public class BootstrapLock {
private static volatile boolean inBootstrap = true;
public static boolean inBootstrap() {
return inBootstrap;
}
public static synchronized void setEndOfBS() {
inBootstrap = false;
}
}
public class DummyAgent {
public static void premain(String options, Instrumentation ins) {
BootstrapLock.setEndOfBS();
}
}
So basically the logic is as follows:
Agents are loaded before the main application class, but after bootstrapping.
Thus the very fact that the agent is active means that bootstrapping is finished.
Thus the agent can switch off the global marker inBootstrap.
Your instrumented classes can check the marker in order to determine if their additional instrumentation code should be bypassed or not.
I am unsure if I have enough time to test this anytime soon, but at least I wanted to post this answer here so maybe you, Vijai, can also look into it and provide some feedback. Four eyes see more than two...
Update: One of the FERRARI authors has answered my inquiry and confirmed my explanation above. You can just use a java agent as a marker of JVM having finished its bootstrapping. Maybe you do not even need the additional class, but just check if the agent has been loaded into the JVM yet. It would make things even simpler, I just do not know if it performs well. Just test it.

Java to JavaScript using GWT compiler

I have some Java code written that I'd like to convert to JavaScript.
I wonder if it is possible to use the GWT compiler to compile the mentioned Java code into JavaScript code preserving all the names of the methods, variables and parameters.
I tried to compile it with code optimizations turned off using -draftCompile but the method names are mangled.
If GWT compiler can't do this, can some other tool?
Update
The Java code would have dependencies only to GWT emulated classes so the GWT compiler would definitely be able to process it.
Update 2
This Java method :
public String method()
got translated to this JavaScript funciton :
function com_client_T_$method__Lcom_client_T_2Ljava_lang_String_2()
using the compiler options :
-style DETAILED
-optimize 0
-draftCompile
So names can't be preserved. But is there a way to control how they are changed?
Clarification
Say, for example, you have a sort algorithm written in Java (or some other simple Maths utility). The method sort() takes an array of integers. and returns these integers in an array sorted. Say now, I have both Java and JavaScript applications. I want to write this method once, in Java, run it through the GWT compiler and either keep the method name the same, or have it change in a predictable way, so I can detect it and know how to change it back to sort(). I can then put that code in my JavaScript application and use it. I can also automatically re-generate it if the Java version changes. I have a very good reason technically for this, I understand the concepts of GWT at a high level, I'm just looking for an answer to this point only.
Conclusion
The answer to the main question is NO.
While method name can be somewhat preserved, its body is not usable. Method calls inside it are scattered throughout the generated file and as such, they can't be used in a JavaScript library which was the whole point of this topic.
Although you can set the compiler to output 'pretty' code, I suggest you write export functions for the classes you want to call from outside your GWT project. I believe somewhere in the GWT documentation it's detailed how to do this, but I couldn't find it so here an example I just created.
class YourClass {
public YourClass() {
...
}
public void yourMethod() {
...
}
public static YourClass create() {
return new YourClass();
}
public final static native void export() /*-{
$wnd.YourClass = function() {
this.instance = new #your.package.name.YourClass::create()()
}
var _ = $wnd.YourClass.prototype;
_.yourMethod = function() {this.instance.#your.package.name.YourClass::yourMethod()()}
}-*/;
}
EDIT
To elaborate, your code will get obfuscated like normal, but thanks to the export function, you can easily reference those functions externally. You don't have to rewrite anything from your Java class in JavaScript. You only write the references in JavaScript, so you can do this:
var myInstance = new YourClass();
myInstance.yourMethod();
Of course you have to call the static export method from somewhere in your GWT app (most likely in your EntryPoint) to make this work.
More info about referencing Java methods from JavaScript:
http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html#methods-fields
No - this isn't possible with the GWT compiler, since the GWT compiler is build to generate optimized and very performant JavaScript out of Java.
The big advantage is, that you can maintain your projekt in Java and compile it with GWT to JavaScript. So there is no need to prevent the variable-names and method-names in the JavaScript result, since all changes and work is done in the JAVA-sources.
Working in the JavaScript-output of GWT just isn't that easy and is really a lot of work!
Update:
By a hint of David, I found the Compiler-Option "-style". You can have a try with the following options:
-style=PRETTY -optimize=0
I have no idea if this will really generate "human readable" code. I think it won't, since the GWT framework will still be part of the resulting JavaScript and so it will be difficult to make changes to the JavaScript-result. Have a try and let us know ...
Maybe I can answer your second question: "If GWT compiler can't do this, can some other tool?"
I am using Java2Script for quite a while now, also on quite large projects. Integration with native JavaScript is fine, names are preserved, and after some time one can even match the generated JavaScript (in the browser debugger) with the original Java code with little effort.
Udo
You can "export" your function by writing inline JavaScript that calls it, and there is a tool gwt-exporter that does this automatically when you annotate classes and methods with #Export and similar. More information: https://code.google.com/p/gwtchismes/wiki/Tutorial_ExportingGwtLibrariesToJavascript_en

Do I have any method to override System Properties in Java?

I am getting a practical issue and the issue can be dascribed as follows.
We are developing a component (Say a plugin) to do some task when an event is triggered within an external CMS using the API provided by them. They have provided some jar libraries, So what we are doing is implementing an Interface provided by them. Then an internal method is called when an event is triggered. (The CMS is creating only one instance of class when the first event triggers, then it just executes the method with each event trigger)
The function can be summarized as follows,
import com.external.ProvidedInterface;
public class MonitorProgram implements ProvidedInterface{
public void process(){
//This method is called when an event is triggered in CMS
}
}
Within our class we are using "javax.net.ssl.HttpsURLConnection" (JAVA 1.5). But HttpsURLConnection migrated to javax.net.ssl from com.sun.net.ssl for 1.4. But it seems the CMS I am referring to (We dont know their implementation actually) uses something like this
System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");
leading to a ClassCastException in our code.
I think my question is clear. In our case we cant set VM parameters,
-Djava.protocol.handler.pkgs=
Also we cant set it back using,
System.setProperty("")
because the VM instance is same for CMS and our program.
What can I do for get this problem resolved? And idea or experiences?
This is not clear for me.
Do you want to overwrite a system property?
You can do this.
Overwrite the System.property before calling the external library method and when the method returns you can set the old System.property back
final String propertyName = "Property";
String oldProperty = System.getProperty(propertyName);
System.setProperty(propertyName,"NEW_VALUE");
monitorProgram.process();
System.setProperty(propertyName,oldProperty);
Or do you want to prevent, that the called process overwrites the system.property?
And why you can not set the system property by hand?
I don't think you are going to have much success getting two pieces of code to use different properties.
In your own code however, you can define your own URLStreamHandlerFactory. Doing this will allow you to create a javax.net.ssl.HttpsURLConnection from a URL. While protocol handlers aren't the easiest thing to figure out, I think you can get them to do the job.
See http://java.sun.com/developer/onlineTraining/protocolhandlers/
Find the offending class in the stack trace
Use jad or a similar tool to decompile it.
Fix the name of the property
Compile the resulting file and either replace the .class file in the CMS's jar or put it into a place which is earlier in the classpath.
Use ant to automate this process (well, the compile and build of the JAR; not the decompiling)
When it works, make sure you save everything (original file, changed file, build file) somewhere so you can easily do it again.
While this may sound like a ridiculous or dangerous way to fix the issue, it will work. Especially since your CMS provider doesn't seem to develop his product actively.

Categories

Resources