Javassist how to debug modified java method - eclipse

use Javassist to add some code statically at the beginning of a method right after the class is compiled. For example,
public String getFoo() {
// add some code here
return "foo";
}
From Eclipse debug, I can not see the added code. Is there a way for Eclipse to show de-compiled code instead of original source?
How to debug it?

Once you've created the CtClass, you can call CtClass.writeFile to save the bytecode of the resulting java class. Then you can use a java decompiler to view the source. The generated source is not perfect ( it would probably not compile ) but it gives you a good idea of what's going on. I use the decompiler built into IntelliJ ( community edition ) but some googling will find you a few other options.

Related

cannot debug GWT native code within gwtmockito

I have a GwtMockitoTestCase and the debugger seems not to enter inside any vanilla GWT class like Widget, ResizeLayoutPanel, etc.
However, when running the same code inside DevMode, the debugger steps correctly through that code.
Does this have to do with GWT running inside a JRE? If not, could it be that my classpath is wrong somehow? Or maybe the gwt-user jar doesn't have debugging information?
I've also tried to extend a GWT class:
ResizeLayoutPanel w = new ResizeLayoutPanel() {
#Override
public void setWidget(Widget pW) {
super.setWidget(pW); (1)
}
};
And breakpoint on line (1) is working but pressing F5, it doesn't go inside ResizeLayoutPanel's setWidget method.
Thank you!
After digging in the GwtMockito code, it seems there are a certain set of classes that are stubbed and some methods' body is removed. Therefore it's not possible to debug those methods.
The question that remains is that somehow GWTMockito breaks the code coverage tool(EclEmma) which shows less code covered than it's supposed to. I've posted a separate question on this topic on SO: false code coverage reported using GwtMockito
Some technical background:
GwtMockitoClassLoader stubs some classes from GWT completely, please check GwtMockitoTestRunner#getClassesToStub() which includes Widget and ResizeLayoutPanel classes.
The stubbing process removes the body completely for the methods returning primitive values or void, see GwtMockitoClassLoader#onLoad. If the return is a java bean, it will return a mocked version for it.

How can I use JDT compiler programmatically?

I use JDT to compile my java classes. BatchCompiler returns a string but I need an array of problems/errors with their column and row information. compiler.compile(units); prints the error to its printwriter, compiler.resolve(unit) does exactly what I want but it can compile only one java file.
I created a compiler object in this way:
Compiler compiler = new Compiler(env, DefaultErrorHandlingPolicies.exitAfterAllProblems(), new CompilerOptions(), requestor, new DefaultProblemFactory());
And create CompilationUnits that contains filenames and file contents to the compiler.
CompilationUnit[] units = project.toCompilationUnit();
AFAIK, there are 2 ways to compile, one of them is compile(units) method that returns void and prints errors and problems to its PrintWriter, because it doesn't return column information it's not useful for me. The other way is resolve(unit) method but it can work with only one CompilationUnit.
compiler.resolve(units[index], true, true, true);
Does anyone know how I can use JDT compiler programmatically to compile multiple files?
org.eclipse.jdt.internal.compiler.Compiler is internal API. According to the JavaDoc of its resolve method: Internal API used to resolve a given compilation unit. Can run a subset of the compilation process.
Instead, the official way of compiling Java files and determining the compilation problems is described here. Basically, you create a Java project and invoke Eclipse's builder on it, then query the project's Java problem markers.

Eclipse is not showing method parameters properly

In my eclipse, when i check for method help with ctrl+space i see the method parameters are showing like strings, int as arguments. Not showing like, string name/int id .
getAttribute(String arg0)
How can i make the eclipse to show the method as getAttribute(String name)
This is really difficult to me identify which param i should pass fro a method.
Any idea, where should i set the settings?
This problem happens when eclipse can't find the source or attached Javadoc, since java argument names are usually not present in the .class files (it would only be present in debug, and not for the interfaces).
You can check if a source or a documentation is attached using the helper F3.
You can increase the timeout eclipse uses for fetching a parameter name from attached Javadoc in the settings.
You can also attach the corresponding documentation jar or source jar as a dependency in order to allow eclipse to look-up the corresponding source.

How to compare files programmatically in eclipse?

I am developing an eclipse plugin that runs code violation checker on the difference of two versions of a file. Right now I am using diff.exe to get the difference between the two files. But as diff.exe is an extrenal app, I realized that its better to use eclipse built-in compare tool to get the file difference.
So I used org.eclipse.compare and reached up to this point:
public static List<Patch> compare(String old, String recent) {
try{
IRangeComparator left = new TokenComparator(old); //what exactly to be passed in this constructor, a file path, a literal value or something else?
IRangeComparator right = new TokenComparator(recent);
RangeDifference[] diffs = RangeDifferencer.findDifferences(left, right); // This line is throwing NPE
//..
// Process RangeDifferences into Collection of Patch collection
//..
}catch(Exception e){}
//Returns a collection of file differences.
return null;
}
Now the problem is I am not sure what exactly to be passed in the constructor TokenComparator(String). The document says this constructor Creates a TokenComparator for the given string. But it is not written what exactly to be passed in this constructor, a file path, a literal value or something else? When I'm passing a file path or a string literal I am getting NullPointerException on the next line of finding differences.
java.lang.NullPointerException
at org.eclipse.compare.internal.core.LCS.isCappingDisabled(LCS.java:98)
at org.eclipse.compare.internal.core.LCS.longestCommonSubsequence(LCS.java:55)
at org.eclipse.compare.rangedifferencer.RangeComparatorLCS.longestCommonSubsequence(RangeComparatorLCS.java:186)
at org.eclipse.compare.rangedifferencer.RangeComparatorLCS.findDifferences(RangeComparatorLCS.java:31)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:98)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:82)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:67)
at com.dassault_systemes.eclipseplugin.codemonview.util.CodeMonDiff.compare(CodeMonDiff.java:48)
at com.dassault_systemes.eclipseplugin.codemonview.util.CodeMonDiff.main(CodeMonDiff.java:56)
Someone please tell what is right way to proceed.
If the question is What value the token comparators constructor takes then the answer is it takes the input string to compare. Specified in javadoc here http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcompare%2Fcontentmergeviewer%2FTokenComparator.html
TokenComparator(String text)
Creates a TokenComparator for the given string.
And the null pointer yo are getting is because in function isCappingDisabled it tries to open the compare plugin which seems to be null. You seem to be missing a direct dependency to the plugin "org.eclipse.compare.core"
The org.eclipse.compare plugin was never meant to be used in standalone : many of its functionalities require a running instance of Eclipse. Furthermore, it mixes core and UI code within the same plugin, which will lead to unexpected behavior if you are not very careful about what you use and what dependencies are actually available in your environment.
You mentionned that you were developping an Eclipse plugin. However, the NPE you get indicates that you are not running your code as an Eclipse plugin, but rather as a standard Java program. In an Eclipse environment, ComparePlugin.getDefault() cannot return null : the plugin needs to be started for that call to return anything but null.... and the mere loading of the ComparePlugin class within Eclipse is enough to start it.
The answer will be a choice :
You need your code to run as a standalone Java program out of Eclipse. In such an event, you cannot use org.eclipse.compare and diff.exe is probably your best choice (or you could switch to an implementation of diff that was implemented in Java in order to be independent of the platform).
You do not need your program to work in a standalone environment, only as an Eclipse plugin. In this case, you can keep the code you're using. However, when you run your code, you have to launch it as a new "Eclipse application" instead of "Java Application". You might want to look at a tutorial on how to develop Eclipse plugins for this, This simple tutorial from Lars Vogel shows how to run a new Eclipse Application to test an Hello World plugin. You will need a similar code, with a menu entry to launch your plugin somewhere (right-click on a file then select "check violations" in your case?).

Why eclipse is generating argument names as arg0,arg1,arg2.... for methods?

When I try to access some class's method; eclipse gets that method but arguments inside that method are replaced by arg0, arg1, arg2...
Example:-
Suppose I have this method in some class named ReadFile.java
#Override
public int readXXX(int start, int end, String xxx) throws IOException {
return 0;
}
When I try to access that method from an instance of class it shows me as follows:
readFile.readXXX(arg0, arg1, arg2);
It becomes hard to identify what I should pass in argument. The same thing also happens for java methods. i.e. when I implement interface all method under that will be generated but arguments in that methods are arg0, arg1.....
Is there any setting I can do prevent this?
I'm using Eclipse Galelio.
Eclipse can't work out the arguments because it can't find the source or javadoc attachments.
Make sure your source is attached.
To check, click on the method call readXXX and press F3 which should open the method declaration. If the source is not attached, Eclipse will say "Source not found" and will allow you to "Attach Source...".
Anyone having the same issue, try performing a Project > Clean, this will delete the old class files, and Eclipse will recompile them in debug mode this time. Worked for me in Indigo 3.7.2
The problem is that your class files lacks debug information embedded in them. JDT doesn't reparse the source files or the javadoc for dependencies, when building the AST for your project, so it doesn't have idea what the name of the parameter is, even when you are able to open the class and clearly see what are the method names.
In order to correct this, you need to recompile your class files with debug information enabled, which makes the class file considerably larger, but unless you are developing for memory-constraint devices, you should be fine.
for those like me who tried to apply one of our colleagues suggestions and unfortunately hasn't worked, please, give a try to check the option "Add variable attributes to generated class files (used by the debugger)" within Window -> Preferences -> Java + Compiler.
Once you've done that, try to build the project again.
Cheers.
I solved this by going to preferences
Java / Content Assist
On this page under "Sorting and Filtering" I unchecked "Hide proposals not visible in the invocation context" now instead of seeing (arg0, arg1, arg2) etc in autocomplete I see (catalog, schemaPattern, tableNamePattern...)
I am using Spring Tools Suite 3.7.2 which runs on the Eclipse Mars 4.5.1 platform.
This link helped me to solve this problem.
1) Right click on your android.jar and select Properties.
2) Select Java Source Attachment. Enter the source directory location (you can also use External Folder… to browse to the directory) and click on “Apply“.
The code names match the following version numbers, along with API levels and NDK releases provided for convenience: