Cannot view variables values from Java sources during debug - java

While debugging a Java program, I cannot view variables values in java source code, for example in function Integer.valueOf(). I try to add variables in Expressions or Inspect, but get 'a cannot be resolved'

This is known problem. Typically you can see the argument values as arg0, arg1 etc and sometimes member variables. If lhballoti is right and the problem is that the JDK is compiled without debug information try to compile it yourself from sources (src.zip). I believe that it is hard to compile whole JDK but I think that you can compile only interesting classes. Then push this classes into bootclasspath when you are running your java program (using -Xbootclasspath/p).
I hope this will work.

'a' is not a local variable in this method, however I don't think the JRE classes are enabled with full debugging information. It might not be possible to see local variables in the JRE.

Related

How does the terminal compile java programs when $CLASS_PATH is not set? [duplicate]

I'm trying to look under the hood about java compilation. So I put my IDE away and started using MS-DOS command-line...
I created a simple project, as described in the tree below :
SampleApp
|____**src**
|_____pack
|______Sample.java
|____**classes**
This is the Sample.java source code :
public class Sample
{
private String s = new String("Hello, world");
public Sample(){
System.out.println(s);
}
}
I just want to compile this class, so I used the javac command :
prompt\SampleApp\src>javac -d ..\classes -sourcepath . pack\Sample.java
All works fine, but i didn't expect that because I deleted my CLASSPATH environment variable before compiling my Sample.java file. So I was expecting a compiler error due to the fact that the compiler would not be able to find the java.lang.String class file.
I read this article http://www.ibm.com/developerworks/java/library/j-classpath-windows/ which helped me understand many things. The article author says that the default classpath is the current working directory. But I don't understand why my source code compile without error. Could someone explain this to me?
So I was expecting a compiling error due to the fact that the compiler would not be able to find the java.lang.String class file.
The short answer is that the compiler knows where to find all of the standard Java SE library classes without you telling it.
The longer answer is that String class is being found on the bootclasspath. This is implicitly set by the javac command to refer to the relevant JARs in the JDK installation. The javac command searches the bootclasspath before it looks for stuff on the regular classpath.
The classpath variable doesn't do what you think. To cite the oracle documentation:
The CLASSPATH variable is one way to tell applications, including the
JDK tools, where to look for user classes. (Classes that are part of
the JRE, JDK platform, and extensions should be defined through other
means, such as the bootstrap class path or the extensions directory.)
Source: http://docs.oracle.com/javase/tutorial/essential/environment/paths.html
Basically since java.lang.* is part of the platform and delivered with the JDK/JRE, the compiler doesn't have to be told by you where to look for them.

C-namespace section in spring reference document

I am reading spring document and I couldn't understand below statement from c-namespace section in the reference document
For the rare cases where the constructor argument names are not available (usually if the bytecode was
compiled without debugging information), one can use fallback to the argument indexes
My questions are :
In what cases constructor argument is not available.
What does it mean that -byte code compiled without debugging information. Can be it checked using eclipse ?
I was checking for this over web, but could get any reference. I found Constructor injection using c:namespace but it didn't explain any thing
Constructor argument names are only available if the class is compiled with variable debugging information. When using javac, this is the -g:vars option. In Eclipse, this is Windows > Preferences > Java > Compiler > Add variable attributes to generated class files.
If the class in question was compiled by javac without the -g flag ("debug info" - see javac docs), then the compiled class bytecode will not contain the names of the constructor parameters. This means that Spring cannot use reflection to match the constructor parameter names, so you need to inject them by position (i.e. by index) instead.
It's up the build environment that generates the compiled bytecode to ensure that debug info is supplied. Once the code is compiled, there's nothing you can do to retrieve that information, short of recompiling it.
See also What does the javac debugging information option -g:vars do?

Eclipse / conditional breakpoint results in BreakpointException

I want to debug a static inner class, which is actually a Callable. Whenever I try to set a conditional breakpoint in Eclipse I get the breakpoint error:
The type com.sun.source.tree.Tree$Kind cannot be resolved. It is
indirectly referenced from required .class files.
What is causing this error? Is it a bug in the class/package that uses com.sun.source.tree.Tree$Kind but does not provide it? How do I find out which class it is? How do I resolve it?
An example expression which should be correct is: return mRtx.getNode().getNodeKey() == 74;
I have changed it to mRtx.getNode().getNodeKey() == 74 but still the same error. Recently I've found the bug and simply used:
if (mRtx.getNode().getNodeKey() == 74) {
System.out.println("bla");
}
and set a "normal" breakpoint on the "sysout" statement just in case someone has the same problem.
I am not sure on how I would reproduce it as your description is not exactly telling much.
The com.sun.source.tree package is included in tools.jar, which is part of JDK but not of JRE, so make sure you run your Eclipse in JDK (JAVA_HOME variable?), maybe try setting projects JRE to a JDK folder.
I also think that the Compiler API was introduced in Java 6, so check if you are not using a lower version.
Maybe you should try to edit the debugger's source lookup.
To do this, go to debug perspective, in the debug view (where the stack is normally shown) right click on the terminated run, and choose 'Edit Source Lookup...'.
Then you can add a lookup place. In this case you should maybe add the tools.jar that is in the jre folder.
The compiler can't find the type, that is the root issue, but in my thinking, this should only be a compile time error, but by implication from what I read, it's a run time error. Is that correct?
Here is are some tips:
http://java.syntaxerrors.info/index.php?title=Cannot_resolve_type
Indirectly referenced from required .class file
Maybe you could post more code or use "control + T" in Eclipse on the class to look at the type hierarchy, I would like to know what other classes are referenced.
HTH,
James

Which Java compilers are available on Windows?

So, long story short, I need to use another Java compiler than what came with my Eclipse installation(Windows). I have to run some code that runs well in my other team member's computers (osx) but fails to run here. It seems the compiler I am using is way more strict than theirs, so I am looking for a more relaxed compiler (until they fix their code to comply to my actual compiler).
What are the options available?
So, a totally stripped down version of the code is like this:
public class TreeSet <E extends Xpto & IOrderable<E>> implements SortedSet<E>, Cloneable {
...
}
public interface Xpto {}
interface IOrderable<E> extends Cloneable{
boolean greaterEq(E e);
IOrderable<E> clone();
}
being the error
"The inherited method Object.clone()
cannot hide the public abstract method
in IOrderable"
You have these options
Sun/Oracle (recommended)
IBM Jikes
gjc
But your main description sounds more like build specific problem. You can tweak them by right click on the project->Properties->Java Compiler.
UPDATE Clonable already provides a clone Method which is hidden. So you should strip that line from the IOrderable interface. In TreeSet clone has to be public.
Eclipse uses its own built-in one. You should probably try using the one which comes with the JDK.
Alternatively, have you tried changing the Eclipse compiler options, there's a lot you can tweak, including whether some code ends up with errors, warnings, or nothing. Look in either the project preferences or your workspace preferences, under Java > Compiler > Errors/Warnings. If you could give an example of the errors you're getting (and ideally the code which is failing), we could give more advice.
You should use an Ant build script, which when executed will in turn use the normal Sun Java compiler. See here for a simple build script. It's a good way of getting around the problems :)
Eclipse probably uses the one in the JDK, right? (wrong. from the comments: according to 1 commenter and 3 upvoters, Eclipse uses its own internal compiler, my bad. But that means you can use the one in the JDK too :D)
Anyway, you can try http://en.wikipedia.org/wiki/GCJ
Comments suggest this is not a compiler, although I do not agree. Please educate me on my wrongness and I'll gladly update or remove this answer.
From the wikipedia page :
The GNU Compiler for Java (GCJ or gcj)
is a free software compiler for the
Java programming language and a part
of the GNU Compiler Collection. GCJ
can compile Java source code to either
Java Virtual Machine bytecode, or
directly to machine code for any of a
number of CPU architectures. It can
also compile class files containing
bytecode or entire JARs containing
such files into machine code.

Java "NoSuchMethodError"

I'm getting:
NoSuchMethodError: com.foo.SomeService.doSmth()Z
Am I understanding correctly that this 'Z' means that return type of doSmth() method is boolean? If true, then that kind of method really does not exist because this method returns some Collection. But on the other hand if I call this method, I'm not assigning its return value to any variable. I just call this method like this:
service.doSmth();
Any ideas why this error occurs? All necessary JAR files exist and all other methods from this class seems to exist.
Looks like method exists in classpath during compilation, but not during running of your application.
I don't think return type is a problem. If it was, it wouldn't compile. Compiler throws error when method call is ambiguous, and it is when two methods differ only by return type.
Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.
In short - a class/jar file at runtime is not the same that you used at compile time.
This is probably a difference between your compile-time classpath and you run-time classpath.
Here is what seems to be going on:
The code is compiled with a class path that defines the doSmth() method returning a boolean. The byte-code refers to the doSmth()Z method.
At runtime, the doSmth()Z method isn't found. A method returning a Collection is found instead.
To correct this problem, check your (compile time) classpath.
The current reply just tell you why is failing. Usually is even nicer to know how to fix problems. As it is mentioned, the problem usually is that you built your program but when running or exporting it, the library is not included. So the solution is...
If you are running, check the the run configuration
Select Run tab -> Run configurations -> Select the configuration you are running -> Check the Classpath tab -> Ensure the libraries you need are there
If you are exporting (for example a war file), follow this
Select project -> Select properties -> Select Deployment Assembly -> Press Add -> Select Java Build Path Entries -> Select the libraries you want to be included in your exported file (for example a war file)
In both cases, ensure the library which you are referencing in included.
Other frequent problems for this error are not the right type of parameters or visibility but then, the compiler will detect the error before running. In this case, just check the documentation to match the function and package visibility, and ensure that the library is found in Java Build Path in your project properties.
Maybe still can help somebody, but this exception can happen also when you have on the classpath two classes in different jar files that have the same exact signature but they haven't the same public methods.
For example:
On file mylibrary1.jar you have class com.mypackage.mysubpackage.MyClass with method doSmth()
On file mylibrary2.jar you have class com.mypackage.mysubpackage.MyClass without method doSmth()
When searching the class, the classloader may find first mylibrary2.jar depending on the path precedence but can't find the method on that class.
Be sure you don't have the same package + class on two different files.
I noticed this problem occurring while testing some experimental changes in multiple linked projects, after updating them from SVN in Eclipse.
Specifically, I updated all projects from SVN, and reverted the .classpath file rather than edit it manually to keep things simple.
Then I re-added the linked projects to the path, but forgot to remove the related jars. This was how the problem occurred for me.
So apparently the run time used the jar file while the compiler used the project files.
Another way this can happen and is difficult to find:
If a signature of a method in an external jar changes in a way that there is no error found in the IDE because it's still compatible with how you call it the class might not be re-compiled.
If your build checks the files for changes and only then recompiles them, the class might not be recompiled during the build process.
So when you run it this might lead to that problem. Although you have the new jar, your own code expects still the old one but does never complain.
To make it harder it depends on the jvm if it can handle such cases. So in the worst case it runs on the test server but not on the live machine.

Categories

Resources