How Javac works

Discussion in 'Java' started by Roedy Green, Jul 15, 2005.

  1. Roedy Green

    Roedy Green Guest

    I have been reorganising my entire code base so that dependencies
    don't force me to use Java 1.5 when I don't really need it.

    I have discovered something that surprised me.

    If I delete all the class files in the universe, and compile one class
    that references all sorts of other packages, the compile seems
    completely happy, but when it comes time to jar to bundle in code from
    other packages, the class files are not there yet.

    So it looks as if Javac peeked at the source, compiled it enough to
    deduce method signatures, but did not leave a class file behind.

    I wonder if there is some other explanation for my observations.

    I had thought java would automatically recompile and out of date class
    files from other packages when it went to check the signatures.

    This may explain why it sometimes feels as though my code changes
    don't "take" right away. It takes multiple compiles to propagate
    them.

    --
    Bush crime family lost/embezzled $3 trillion from Pentagon.
    Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
    http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

    Canadian Mind Products, Roedy Green.
    See http://mindprod.com/iraq.html photos of Bush's war crimes
     
    Roedy Green, Jul 15, 2005
    #1
    1. Advertising

  2. Roedy Green

    Joan Guest

    "Roedy Green" <> wrote in message
    news:...
    > I have been reorganising my entire code base so that dependencies
    > don't force me to use Java 1.5 when I don't really need it.
    >
    > I have discovered something that surprised me.
    >
    > If I delete all the class files in the universe, and compile one class
    > that references all sorts of other packages, the compile seems
    > completely happy, but when it comes time to jar to bundle in code from
    > other packages, the class files are not there yet.
    >
    > So it looks as if Javac peeked at the source, compiled it enough to
    > deduce method signatures, but did not leave a class file behind.
    >
    > I wonder if there is some other explanation for my observations.


    Maybe it is looking at the "import" statements.

    >
    > I had thought java would automatically recompile and out of date class
    > files from other packages when it went to check the signatures.
    >
    > This may explain why it sometimes feels as though my code changes
    > don't "take" right away. It takes multiple compiles to propagate
    > them.
    >
    > --
    > Bush crime family lost/embezzled $3 trillion from Pentagon.
    > Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
    > http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
    >
    > Canadian Mind Products, Roedy Green.
    > See http://mindprod.com/iraq.html photos of Bush's war crimes
     
    Joan, Jul 15, 2005
    #2
    1. Advertising

  3. Roedy Green

    E.Otter Guest

    javac is not a build program like make or ant. It does not check if a
    ..class file is out of date and recompile it. When you compile java code
    that references other classes, javac will check the classpath for those
    class files. If it finds a required class, even a horribly out-of-date
    file, it will use it. If it can't find a required class at all, but can
    find a .java file in a directory where the .class should be, it will compile
    that other java code too.

    If you want that a sophisticated build tool for Java code check out ant at
    http://ant.apache.org
     
    E.Otter, Jul 15, 2005
    #3
  4. Roedy Green

    Hemal Pandya Guest

    Roedy Green wrote:
    > I have been reorganising my entire code base so that dependencies
    > don't force me to use Java 1.5 when I don't really need it.
    >
    > I have discovered something that surprised me.
    >
    > If I delete all the class files in the universe, and compile one class
    > that references all sorts of other packages, the compile seems
    > completely happy, but when it comes time to jar to bundle in code from
    > other packages, the class files are not there yet.


    If the class files were not generated by javac then it was able to find
    the class definition somewhere in classpath. Since you deleted all the
    classfiles, it must be one of the jars in the classpath. May I suggest
    jwhich, which is trivial but useful.

    [....]
    >
    > I had thought java would automatically recompile and out of date class
    > files from other packages when it went to check the signatures.

    Not out of date, but it will (try to) compile from source if it can't
    find the class file.

    >
    > This may explain why it sometimes feels as though my code changes
    > don't "take" right away. It takes multiple compiles to propagate
    > them.


    I don't think it does. Try the -verbose switch with javac. The output
    might be large, but look for the missing class -- the one that did not
    make it into the jar. The "loading" line will show where javac found it.
     
    Hemal Pandya, Jul 15, 2005
    #4
  5. Roedy Green

    Dale King Guest

    E.Otter wrote:
    > javac is not a build program like make or ant. It does not check if a
    > ..class file is out of date and recompile it. When you compile java code
    > that references other classes, javac will check the classpath for those
    > class files. If it finds a required class, even a horribly out-of-date
    > file, it will use it. If it can't find a required class at all, but can
    > find a .java file in a directory where the .class should be, it will compile
    > that other java code too.


    That's not true. It will also compile out of date files if it finds both
    the source and the class file. From the javac documentation:

    "Search produces both a source file and a class file: javac determines
    whether the class file is out of date. If the class file is out of date,
    javac recompiles the source file and uses the updated class file.
    Otherwise, javac just uses the class file."

    That doesn't mean everything is rebuilt. Consider if I have three java
    files so that A depends on B and B depends on C. If A and C are out of
    date but B is not and you compile A.java then C will not get rebuilt. If
    B were out of date then all three would be compiled.

    > If you want that a sophisticated build tool for Java code check out ant at
    > http://ant.apache.org


    Ant is no more sophisticated than javac in this regard. It is trivial to
    have Ant say everything is OK, yet have things not be recompiled that
    need to be.

    --
    Dale King
     
    Dale King, Jul 16, 2005
    #5
  6. Roedy Green

    Hemal Pandya Guest

    Dale King wrote:
    > E.Otter wrote:
    >
    > Ant is no more sophisticated than javac in this regard. It is trivial to
    > have Ant say everything is OK, yet have things not be recompiled that
    > need to be.


    The Ant optional task Depend is slightly more sophisticated, but it too
    has subtle and important limitations.

    One argument I have often heard is: When it doubt rebuild all, javac is
    very fast anyway.


    >
    > --
    > Dale King
     
    Hemal Pandya, Jul 16, 2005
    #6
  7. Roedy Green

    Tim Tyler Guest

    Hemal Pandya <> wrote or quoted:

    > One argument I have often heard is: When it doubt rebuild all,
    > javac is very fast anyway.


    One argument I have often heard is to use Eclipse or JavaMake,
    which know how to keep track of dependencies, and - unlike
    javac - have the intelligence to avoid leaving your project
    in an inconsistent mess.
    --
    __________
    |im |yler http://timtyler.org/ Remove lock to reply.
     
    Tim Tyler, Jul 16, 2005
    #7
  8. Roedy Green

    Dale King Guest

    Hemal Pandya wrote:
    >
    > Dale King wrote:
    >
    >>E.Otter wrote:
    >>
    >>Ant is no more sophisticated than javac in this regard. It is trivial to
    >>have Ant say everything is OK, yet have things not be recompiled that
    >>need to be.

    >
    >
    > The Ant optional task Depend is slightly more sophisticated, but it too
    > has subtle and important limitations.
    >
    > One argument I have often heard is: When it doubt rebuild all, javac is
    > very fast anyway.


    And in my opinion if you ever have to do a "make clean" in order to get
    a correct build then your build system is broken. I don't know of any
    command line build system for Java that isn't slightly broken.

    Eclipse is the least broken build system that I know of as long as you
    aren't chaging your source files without its knowledge.

    --
    Dale King
     
    Dale King, Jul 16, 2005
    #8
  9. Roedy Green

    Roedy Green Guest

    On Sat, 16 Jul 2005 02:49:01 GMT, Dale King
    <> wrote or quoted :

    >That doesn't mean everything is rebuilt. Consider if I have three java
    >files so that A depends on B and B depends on C. If A and C are out of
    >date but B is not and you compile A.java then C will not get rebuilt. If
    >B were out of date then all three would be compiled.


    there are two reasons for a class file to be out of date:

    obvious -- its date is not after the source file date.

    subtle -- some class file it depends on has changed, e.g. a method
    changed from m( char ) to m( int ), or the value of some static final
    has changed, e.g. flipping DEBUGGING = true to DEBUGGING = false.
    The code to call it needs to be regenerated.

    Javac will handle obvious, but not the subtle, right?

    --
    Bush crime family lost/embezzled $3 trillion from Pentagon.
    Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
    http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

    Canadian Mind Products, Roedy Green.
    See http://mindprod.com/iraq.html photos of Bush's war crimes
     
    Roedy Green, Jul 23, 2005
    #9
  10. Roedy Green

    Dale King Guest

    Roedy Green wrote:
    > On Sat, 16 Jul 2005 02:49:01 GMT, Dale King
    > <> wrote or quoted :
    >
    >
    >>That doesn't mean everything is rebuilt. Consider if I have three java
    >>files so that A depends on B and B depends on C. If A and C are out of
    >>date but B is not and you compile A.java then C will not get rebuilt. If
    >>B were out of date then all three would be compiled.

    >
    >
    > there are two reasons for a class file to be out of date:
    >
    > obvious -- its date is not after the source file date.


    I really wish the world would move beyond this fantasy that the dates on
    files only go forward and not backwards. This notion of just doing a
    greater than comparison between the source and the object is not
    sufficient in my mind for a build system.

    I have this problem now at work. In this case it is with C++ and make. I
    can check things out from ClearCase and build. But if I decide that I
    don't want to check the changes in and just revert back to what is in
    ClearCase, I'll uncheckout the file but the file date goes back to the
    date it was checked in. Make won't rebuild the file because it went back
    in time.

    The problem is that to solve this you must save information about the
    build to overcome this. For every generated file you would have to keep
    a record of its timestamp and the timestamp of all its dependencies.
    Then when building again if any timestamp has changed then you rebuild.

    > subtle -- some class file it depends on has changed, e.g. a method
    > changed from m( char ) to m( int ), or the value of some static final
    > has changed, e.g. flipping DEBUGGING = true to DEBUGGING = false.
    > The code to call it needs to be regenerated.
    >
    > Javac will handle obvious, but not the subtle, right?


    If you compile A.java it will recompile any file that A references whose
    class file is older than its source. The issue is that it doesn't spider
    its way out to anything beyond a file that is up to date.

    So while A may depend on B and B is up to date with its source file
    there may be a hundred files that B depends on that are out of date but
    they won't be checked because the analysis stops at B because B was up
    to date.

    > Bush crime family lost/embezzled $3 trillion from Pentagon.
    > Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.


    Please stop repeating this off-topic lie that has no business in this group!


    --
    Dale King
     
    Dale King, Jul 23, 2005
    #10
  11. "Dale King" <> wrote in message
    news:GhkEe.196347$xm3.89457@attbi_s21...

    > I really wish the world would move beyond this fantasy that the dates on
    > files only go forward and not backwards. This notion of just doing a
    > greater than comparison between the source and the object is not
    > sufficient in my mind for a build system.
    >
    > I have this problem now at work. In this case it is with C++ and make. I
    > can check things out from ClearCase and build. But if I decide that I
    > don't want to check the changes in and just revert back to what is in
    > ClearCase, I'll uncheckout the file but the file date goes back to the
    > date it was checked in. Make won't rebuild the file because it went back
    > in time.


    That's a problem with ClearCase. SCM systems that are either archive-based
    (RCS, SCCS) or client-server (RCS, Perforce) wouild, on uncheckout, produce
    a client file whose date is "now". I agree, producing a build system that
    works with ClearCase's odd semantics would be tricky.

    My pet peeve is that build systems are generally unable to determine that a
    source file has been deleted, and to remove the .class file and rebuild the
    ..jar file (or .o file and .a file) accordingly.
     
    Mike Schilling, Jul 23, 2005
    #11
  12. "Mike Schilling" <> wrote in message
    news:EexEe.2228$...

    >
    > That's a problem with ClearCase. SCM systems that are either archive-based
    > (RCS, SCCS) or client-server (RCS, Perforce)


    That should read "client-server (CVS, Perforce)".
     
    Mike Schilling, Jul 23, 2005
    #12
  13. Roedy Green

    Dale King Guest

    Mike Schilling wrote:
    > "Dale King" <> wrote in message
    > news:GhkEe.196347$xm3.89457@attbi_s21...
    >
    >
    >>I really wish the world would move beyond this fantasy that the dates on
    >>files only go forward and not backwards. This notion of just doing a
    >>greater than comparison between the source and the object is not
    >>sufficient in my mind for a build system.
    >>
    >>I have this problem now at work. In this case it is with C++ and make. I
    >>can check things out from ClearCase and build. But if I decide that I
    >>don't want to check the changes in and just revert back to what is in
    >>ClearCase, I'll uncheckout the file but the file date goes back to the
    >>date it was checked in. Make won't rebuild the file because it went back
    >>in time.

    >
    >
    > That's a problem with ClearCase. SCM systems that are either archive-based
    > (RCS, SCCS) or client-server (RCS, Perforce) wouild, on uncheckout, produce
    > a client file whose date is "now". I agree, producing a build system that
    > works with ClearCase's odd semantics would be tricky.


    ClearCase is just one way such things happen. I could get the same
    result if I made a copy of the file I was going to edit and when done I
    delete the old one and rename the copy back to the original.

    For ClearCase dynamic views ClearCase's omake actually works as I
    described and keeps a record of what files were read to produce an
    output and if any changed rebuilds it.

    > My pet peeve is that build systems are generally unable to determine that a
    > source file has been deleted, and to remove the .class file and rebuild the
    > ..jar file (or .o file and .a file) accordingly.


    That's the sort of thing that could be handled by a system like I
    described. It would have records of everything that went into building it.

    The only way such a system would work with Java is to be tied into the
    compiler however.
    --
    Dale King
     
    Dale King, Jul 24, 2005
    #13
  14. Roedy Green

    Tim Tyler Guest

    Roedy Green <> wrote or quoted:
    > On Sat, 16 Jul 2005 02:49:01 GMT, Dale King


    > >That doesn't mean everything is rebuilt. Consider if I have three java
    > >files so that A depends on B and B depends on C. If A and C are out of
    > >date but B is not and you compile A.java then C will not get rebuilt. If
    > >B were out of date then all three would be compiled.

    >
    > there are two reasons for a class file to be out of date:
    >
    > obvious -- its date is not after the source file date.
    >
    > subtle -- some class file it depends on has changed, e.g. a method
    > changed from m( char ) to m( int ), or the value of some static final
    > has changed, e.g. flipping DEBUGGING = true to DEBUGGING = false.
    > The code to call it needs to be regenerated.
    >
    > Javac will handle obvious, but not the subtle, right?


    Javac doesn't even handle the obvious - unless there's a
    chain of references in out-of-date class files leading
    from the file you told it to compile to all the ones
    that are out of date.

    What /would/ handle the obvious is Javac plus a build system that
    fed it a list of out-of-date files. However that would not
    deal with the subtle - for that you need a slightly more intelligent
    tool that knows about class dependencies.
    --
    __________
    |im |yler http://timtyler.org/ Remove lock to reply.
     
    Tim Tyler, Jul 26, 2005
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. xarax
    Replies:
    1
    Views:
    1,487
    Andy Flowers
    Jul 2, 2003
  2. Jon Skeet
    Replies:
    5
    Views:
    596
    xarax
    Jul 4, 2003
  3. F. GEIGER
    Replies:
    3
    Views:
    799
    F. GEIGER
    Aug 6, 2004
  4. Alexander Burger

    getMethod() works and works not

    Alexander Burger, Nov 27, 2010, in forum: Java
    Replies:
    25
    Views:
    1,825
    Alexander Burger
    Nov 29, 2010
  5. abargaddon
    Replies:
    1
    Views:
    210
    clintmazur
    Feb 4, 2008
Loading...

Share This Page