Nic,

I would like to add to some of what you have said....

Nic Ferrier wrote:
> snip --------8<---------snip
> It struck me that there is a possible solution to this. When a class
> file is compiled with the -g switch the source file name that is was
> compiled from is embedded in the class (this is how the debugger knows
> which class file to load).
>

The name of the source file (without the directory part) is always stored
in the .class file whether or not you compile the source .java file
with -g option. The name of the java source file is stored
as a class file attribute. It is not required by the JVM Spec but is
true for most compilers (i.e. to store the source file name even if -g
was not specified).
(Reference -
http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#79
868)

In fact you have to use -g:none to prevent the javac from storing that
attribute...

Here is the output from my JDK1.3 javac -

"
Usage: javac <options> <source files>
where possible options include:
  -g                        Generate all debugging info
  -g:none                   Generate no debugging info
  -g:{lines,vars,source}    Generate only some debugging info
  snip --------8<---------snip
"

Mind you - this gives you only the name of the source file. Fortunately the
.class file also contains the information about the name of the package
to which this Class belongs. Putting these two pieces together it is
possible to come up with the name the source file relative to the
SOURCEPATH.
This assumes though that the user is following the same directory structure
for
the sources as for the packages of classes. I have known instances where
that was not being followed. This is a problem only for novice Java
programmers
though - because they soon learn that the tools like debuggers cannot find
their
source files. This has been a big problem for people coming from c/c++
environments.

This is one of the biggest point I wanted to make in my write-up earlier.

> It wouldn't be hard to adapt the debugger's strategy for finding a
> source file based on the class file to a rebuilder.
>
> This is what a rebuilder based on this would do:
>
> - create a list 'classeslist' of all the .class files in the
> destination directory
> - create an assoc-list 'sourceslist' of all the .source files in the
> source path
> - for each .class file in 'classeslist'
>     - obtain the source file from the class file
>     - get the source file name from the 'sourceslist'
>     - compare the .class last modified time with the .java last
> modified time
>     - add the .java to a list 'recompilelist' if the .class time is
> eariler
> - for each source file in the 'sourceslist' that isn't in the
> 'classeslist'
>     - add the source file to the 'recompilelist'
> - compile all the files in 'recompilelist' with an @ list argument to
> the compiler
>
> I think this would work. It could be done in elisp (with a java tool
> [use the bsh?] to help extract the source file name for class files).

[[[[
There are a few toolkits available to get the info from class files -

BECL            - http://bcel.sourceforge.net/
IBM's BCT       -
http://www.alphaworks.ibm.com/aw.nsf/techmain/B1DD3263E75AD55C882568AC008364
A9?OpenDocument
C. Mcmanis's- http://www.mcmanis.com/~cmcmanis/java/dump/index.html

and others.
]]]]

The above only deals with the out datedness of the class with respect
to it's source file. This does not deal with how other classes that
may depend on the class, that may have to be compiled.

The "Depend" optional task available with Ant does it the way it should
really be done. Read all about it at -

http://jakarta.apache.org/ant/manual/OptionalTasks/depend.html


Here is an excerpt from the web page -

"To determine the class dependencies, the depend task analyses the class
files of all class files passed to it. Depend does not parse your source
code in any way but relies upon the class references encoded into the class
files by the compiler. This is generally faster than parsing the Java
source."

Mind you - it is a separate task from the 'javac' task. In other words it
has nothing to do
with -depend flag of javac task or compiler.

I have heard that "Depend" task works very well for most cases.

I suspect that the Ant tasks can be run outside of Ant also (with some
tweacking). May be that's
what we need to do for adapting it for JDE ...

Hope this clarifies things...

-sandip

Reply via email to