Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / August 2005

Tip: Looking for answers? Try searching our database.

Im getting frustrated and angry!

Thread view: 
pete_abel@hotmail.com - 22 Jun 2005 03:02 GMT
hello everyone,

Ive been using C/C++/VC++ for a long time. And recently I attempted to
check java out, web-programming in specifc, well so far, it was NOT a
good experience.

What Im trying to do is very simple and straighforward, an applet and a
servlet. The applet sends a simple serialized object, and the servlet
replies(Acknowledges) with a string. and to have the connection
available for many other transfers until the session is over.

Ive looked all over the internet, and all I found was pathetic! Only
code snippets here and there, nothing complete. I really dont know why
didnt anybody write a FULLY working example that does a STRAIGHTFORWARD
communication.

I would really appreciate it if any of you can give me a SIMPLE,
working example of what Im trying to do.

Thanks guys.

Regards,
Pete

p.s. Im using "MyJavaServer" for development, and I think tomcat is
installed on it, isnt it?
HansF - 22 Jun 2005 03:14 GMT
> Ive been using C/C++/VC++ for a long time. And recently I attempted to
> check java out, web-programming in specifc, well so far, it was NOT a
> good experience.

How many of the Java Tutorials at http://java.sun.com have you worked?
How about the Code Camps from the same site?  

Or the stuff from the JavaRanch.com?  
Oracle's complete examples at their TechNet site (albeit database oriented)?  
IBM's samples at http://www.developer.ibm.com/isv/tech/sampjava.html?
Tutorials and samples at http://javaboutique.internet.com/javasource/?

You might have some luck with the O'Reilly Nutshell books - 'Java in a
Nutshell' and 'Java Examples in a Nutshell' (java.oreilly.com)

Signature

Hans

pete_abel@hotmail.com - 22 Jun 2005 03:51 GMT
Thanks for ur reply.

Ive Googled for the following keywords: applet <send> serialized object
servlet. And for 2 days now, Ive been thru 30 or 40 of those links. The
links covered java.sun.com, JavaRanch and javaboutique... And Im not
sure at this point if I want to buy books when, supposedly, Java has a
very wide base of online community support.

Best regards,
Pete
HansF - 22 Jun 2005 04:07 GMT
> sure at this point if I want to buy books when, supposedly, Java has a
> very wide base of online community support.

Books have a slight advantage - you can take 'em to bed with you. <g>  

The two I mentioned are in my reference library and are well worn, in spite
of my fairly reasonable Google skills.

Never the less - I get the feeling you have not had a serious look at the
tutorials.  Sure, you can skip the basic language stuff (but there is
enough to open the eyes of someone with your skills - 'gotcha' differences
with C++), but you really gotta get aquainted with the API libraries which
is where your question is answered.  The tutorials take you there in
quick order.

Aside from that, I think the requirement of 'serializable' in your
search is causing some serious side-tracking.  Consider simplifying to
"applet servlet communication"

Signature

Hans Forbrich

HansF - 22 Jun 2005 04:16 GMT
> Aside from that, I think the requirement of 'serializable' in your
> search is causing some serious side-tracking.  Consider simplifying to
> "applet servlet communication"

Also, I seriously question whether there is much call for applets these
days.  I find that pure HTML front end with JSP/Servlet middle tier is
becoming quite the rage, and applets are nowhere to be found - in the
communities I see.

Finally - I really think you want to be looking at the RMI libraries to
answer your serialization issues.

And soon - welcome to full-blown J2EE and http://theserverside.com (and a
strong recommendation to read O'Reilly "Better, Faster, Lighter Java")

Signature

Hans Forbrich                          

pete_abel@hotmail.com - 22 Jun 2005 04:21 GMT
OK. Following is a listing of the servlet code that, despite its
simplicity, is not working(i.e. is not creating the file myobject.data
on the server). Comments are appreciated.

/*
* Servlet
*/

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class receiver extends HttpServlet
{
    ObjectInputStream inputFromClient;
    Foo theData = null;

   public void doPost (HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException
    {
        try
        {
           inputFromClient = new ObjectInputStream(req.getInputStream());
             theData = (Foo) inputFromClient.readObject();
        }
        catch (ClassNotFoundException cnfE)
        {
           cnfE.printStackTrace();
           }

//*************************************************************
        // Write to disk with FileOutputStream
        FileOutputStream fout = new FileOutputStream("myobject.data");

        // Write object with ObjectOutputStream
        ObjectOutputStream s = new ObjectOutputStream (fout);

        // Write object out to disk
        s.writeObject ( theData );
        s.flush();
//*************************************************************
        inputFromClient.close();
   }  // end doPost
}
Alan Krueger - 22 Jun 2005 05:10 GMT
> OK. Following is a listing of the servlet code that, despite its
> simplicity, is not working(i.e. is not creating the file myobject.data
> on the server). Comments are appreciated.
[...]
> public class receiver extends HttpServlet

Just a nitpick, class names in Java are by convention Capitalized.

> {
>     ObjectInputStream inputFromClient;
>     Foo theData = null;

Why are these out here and not in the doPost method?  One instance of
the servlet object may be used to service multiple threads, and putting
these here is definitely not thread-safe.

>     public void doPost (HttpServletRequest req, HttpServletResponse
> resp) throws ServletException, IOException
[quoted text clipped - 19 lines]
>         s.writeObject ( theData );
>         s.flush();

Is an IOException being thrown by any of the above?  Where do you expect
the myobject.data file to be placed?  You might be trying to write it to
an inappropriate spot.  Try using fully-specified path to a
definitely-writeable directory.

> //*************************************************************
>         inputFromClient.close();
>     }  // end doPost
> }
pete_abel@hotmail.com - 22 Jun 2005 17:55 GMT
Im going to rephrase my questions.

QUESTIONS:

Q1) Is there something in this code thats causing the problem of not
creating the file "myobject.data" by the servlet?
Q2) What are the ways to see whether the servlet has actually received
the serialized object or not?
Q3) What path should be stored in ServletPath: the directory of the
servlet or the the name of the servlet added to that path?

COMMENTS:

C1) When executing the code, no exceptions are caught, and the servlet
doesnt create the file.
C2) As far as the notation is concerned, I reserve that for C++/VC++
(where class names start with a 'C' e.g. "CMyClass", and methd names
are capitalized e.g. "SendData()", and member variables start with "m_"
e.g. "m_nIterations". In java, I really dont care ;)

CODE:

/********************************
* Applet
*/
import java.applet.Applet;
import java.awt.Graphics;
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.net.*;

public class sender extends Applet
{
    String m_MyOutputString;
    Foo MyFoo;
    URL url = null;
    URLConnection conn = null;
    ObjectOutputStream toServlet;
    String ServletPath = "http://myjavaserver.com/~shaiian/receiver";

       public void init()
       {
       try
       {
        url=new URL(ServletPath);
        conn=url.openConnection();
           conn.setDoInput(true);
           conn.setDoOutput(true);
           conn.setUseCaches(false);
           conn.setDefaultUseCaches(false);

conn.setRequestProperty("Content-Type","application/octet-stream");
           toServlet=new ObjectOutputStream(conn.getOutputStream());
           }

           catch (IOException ioe)
           {
        JOptionPane.showMessageDialog(null,"IOException caught");
           }

           MyFoo=new Foo();
       }

       public void SendData()
       {
        try
        {
              toServlet.writeObject(MyFoo);
               }

               catch (SecurityException e)
               {
               JOptionPane.showMessageDialog(null,"Caught a security
exception\n\n" + e.getMessage());
               }

               catch (IOException ioe)
               {
          JOptionPane.showMessageDialog(null,"IOException caught");
               }
      }

      public void destroy()
      {
       try
       {
        toServlet.flush();
           toServlet.close();
       }

           catch (IOException ioe)
           {
        JOptionPane.showMessageDialog(null,"IOException caught");
           }
     }
}

/**************************
* Servlet
*/

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class receiver extends HttpServlet
{
       ObjectInputStream inputFromClient;
       Foo theData = null;

   public void doPost (HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException
       {
               try
               {
                   inputFromClient = new
ObjectInputStream(req.getInputStream());
                   theData = (Foo) inputFromClient.readObject();
               }
               catch (ClassNotFoundException cnfE)
               {
                   cnfE.printStackTrace();
               }

//*************************************************************
               // Write to disk with FileOutputStream
               FileOutputStream fout = new
FileOutputStream("myobject.data");

               // Write object with ObjectOutputStream
               ObjectOutputStream s = new ObjectOutputStream (fout);

               // Write object out to disk
               s.writeObject ( theData );
               s.flush();
//*************************************************************
               inputFromClient.close();
   }  // end doPost
}
Alan Krueger - 22 Jun 2005 23:08 GMT
> QUESTIONS:
>
> Q1) Is there something in this code thats causing the problem of not
> creating the file "myobject.data" by the servlet?

Where were you looking for that file?  Did you look anywhere else?
You've specified a relative pathname to the FileOutputStream.  Do you
know for *certain* where that will go?  Is that directory writeable by
the servlet engine?  Try using a full path to a file in a temp directory
or something.

> Q2) What are the ways to see whether the servlet has actually received
> the serialized object or not?

Using a debugger, trace output, dumping to file, etc.

> Q3) What path should be stored in ServletPath: the directory of the
> servlet or the the name of the servlet added to that path?

Depends on how your servlet is configured to be invoked.  I think you
should probably work through some tutorials on servlets.

> COMMENTS:
>
> C1) When executing the code, no exceptions are caught, and the servlet
> doesnt create the file.

Do you know for certain that the servlet is even being invoked?  What's
calling the SendData method on your applet?  You've expressed a lack of
confidence that you've got the right URL for your applet, so you should
make sure of that, too.
pete_abel@hotmail.com - 22 Jun 2005 20:07 GMT
Let me rephrase my questions.

QUESTIONS:

Q1) After looking at the code at the end of this post, is there a
problem with it thats causing the servlet not to create the file
"myobject.dat"?
Q2) What are the possible ways to check if a servlet has received a
serialized object?
Q3) Which path should be stored in "ServletPath": the path of the
directory containing the servlet or the path of the servlet itself?

COMMENTS:

C1) The code runs with no exceptions. The only problem is that the file
"myobject.data" is not created by the servlet
C2) I thought that if an absolute path was not given for the output
file, the file will be created in the directory of the servlet, hmmm.
C3) As far as the notation of class names is concerned, class names
start with 'C' (e.g. "CMyClass"), method names, capitalized (e.g.
"SendData()"), member-variable names start with "m_" (e.g.
"m_nInterations"). Thats in C++/VC++. In Java, I really dont care ;)

Regards,
Pete

CODE:

/********************************************
* The Applet
*/

import java.applet.Applet;
import java.awt.Graphics;
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.net.*;

public class sender extends Applet
{
    Foo MyFoo;
    URL url = null;
    URLConnection conn = null;
    ObjectOutputStream toServlet;
    String ServletPath = "http://myjavaserver.com/~shaiian/receiver";

  public void init()
  {
    try
    {
        url=new URL(ServletPath);
        conn=url.openConnection();
              conn.setDoInput(true);
           conn.setDoOutput(true);
           conn.setUseCaches(false);
           conn.setDefaultUseCaches(false);
conn.setRequestProperty("Content-Type","application/octet-stream");
               toServlet=new
ObjectOutputStream(conn.getOutputStream());
    }

    catch (IOException ioe)
    {
        JOptionPane.showMessageDialog(null,"IOException caught...");
    }

    MyFoo=new Foo();
   }

  public void SendData()
  {
    try
    {
        // assuming that MyFoo member variables have been set
        toServlet.writeObject(MyFoo);

    }
    catch (SecurityException e)
    {
        JOptionPane.showMessageDialog(null,"Caught a security exception\n\n"
+ e.getMessage());
    }

    catch (IOException ioe)
    {
        JOptionPane.showMessageDialog(null,"IOException caught...");
          }
   }

  public void destroy()
  {
    try
    {
        toServlet.flush();
              toServlet.close();
    }

    catch (IOException ioe)
          {
        JOptionPane.showMessageDialog(null,"IOException caught...");
          }
  }
}

/********************************************
* The Servlet
*/

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class  receiver extends HttpServlet
{
       ObjectInputStream inputFromClient;
       Foo theData = null;

   public void init()
   {
    inputFromClient = new ObjectInputStream(req.getInputStream());
   }

   public void doPost (HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException
   {
               try
               {
                       theData = (Foo) inputFromClient.readObject();
               }
               catch (ClassNotFoundException cnfE)
               {
                       cnfE.printStackTrace();
               }

//*************************************************************
               // Write to disk with FileOutputStream
               FileOutputStream fout = new
FileOutputStream("myobject.data");

               // Write object with ObjectOutputStream
               ObjectOutputStream s = new ObjectOutputStream (fout);

               // Write object out to disk
               s.writeObject ( theData );
               s.flush();
//*************************************************************
               inputFromClient.close();
   }  // end doPost
}
hiwa - 23 Jun 2005 07:27 GMT
>Let me rephrase my questions.
>  

Hi Pete,
I could write an example code  for you but I didn't have enough time to
do so.
My example code would be based on the description from:

http://pdf.coreservlets.com/

This is the free download of Marty  Hall's  Core  Servlets  and  
JavaServer  Pages ,  first
edition.

For your applet-servlet communications issue, read chapter 17 of the
book. Especially
for sending  serialized  object  from  applet to  server,  the  
description  from  17.5  and
17.6 will help.

And beware that the exact URL of the servlet depends on your web.xml
file entries.

Hope this helps. Good luck.


Patricia Shanahan - 22 Jun 2005 15:06 GMT
> Thanks for ur reply.
>
[quoted text clipped - 6 lines]
> Best regards,
> Pete

I think you would do better by splitting the job into three pieces,
applet writing, servlet writing, and serialization. Learn to do each of
those first, and then combine them.

There are many options for how each of those concepts can be used, so
you are very unlikely to find any example that does exactly the
combination you want. You should be able to find good examples of each
of them done separately.

I think you are making a big mistake in ignoring books. Community
support and books are not substitutes for each other. They are much more
powerful used in combination. Use books for big building blocks of
knowledge. Use community support when you need individual help.

Is Java your second programming language, counting C/C++ as one
language? If so, expect to find it difficult and frustrating. I try to
encourage new programmers to learn another language or so as early as
possible, rather than working for years in one language before learning
another. The first language mindset can become entangled into one's
general programming skills.

Patricia
Thomas G. Marshall - 22 Jun 2005 23:46 GMT
Patricia Shanahan coughed up:
>> Thanks for ur reply.
>>
[quoted text clipped - 27 lines]
> learning another. The first language mindset can become entangled
> into one's general programming skills.

I think that is very true.  There are many who believe, for instance, that a
language must have curly braces.  Or that there need to be static types.

Signature

Unix users who vehemently argue that the "ln" command has its arguments
reversed do not understand much about the design of the utilities.  "ln
arg1 arg2" sets the arguments in the same order as "mv arg1 arg2".
Existing file argument to non-existing argument.  And in fact, mv
itself is implemented as a link followed by an unlink.

Onkell Wang - 24 Jun 2005 09:08 GMT
Would you please recommend a second programming language?

Onkell

>> Thanks for ur reply.
>>
[quoted text clipped - 29 lines]
>
> Patricia
Patricia Shanahan - 24 Jun 2005 12:05 GMT
> Would you please recommend a second programming language?

Almost anything that embodies different assumptions from your first
language. Forth is interesting, and properly mind-stretching for someone
whose first language is Java. Assembly languages are good for learning
about what goes on under the hood.

Of course, if you have some reason to expect to need a particular
language in the future, that is the one to learn next.

>>Is Java your second programming language, counting C/C++ as one
>>language? If so, expect to find it difficult and frustrating. I try to
[quoted text clipped - 4 lines]
>>
>>Patricia
Thomas G. Marshall - 07 Aug 2005 04:23 GMT
Patricia Shanahan coughed up:
>>> Is Java your second programming language, counting C/C++ as one
>>> language? If so, expect to find it difficult and frustrating. I try
[quoted text clipped - 9 lines]
> Almost anything that embodies different assumptions from your first
> language.

If the goal is to be exposed to different things, then prolog is one of the
weirder, yet useful, ones.  It is a blurring of what-is-data and
what-is-code, since it is entirely a set of relationships.  Like an
executable BNF of sorts.  Is it data or code?

But I suspect your (Patricia's) latter (snipped) comment is the most
appropos.  (OP), go with what you are likely to need in the future.

...[rip]...

Signature

If I can ever figure out how, I hope that someday I'll
succeed in my lifetime goal of creating a signature
that ends with the word "blarphoogy".

Stefan Schulz - 07 Aug 2005 09:59 GMT
> If the goal is to be exposed to different things, then prolog is one of the
> weirder, yet useful, ones.  It is a blurring of what-is-data and
> what-is-code, since it is entirely a set of relationships.  Like an
> executable BNF of sorts.  Is it data or code?

Speaking of it, if you think you understood prolog and imperative coding,
take a look at Haskell, and find your assumptions challenged again.
Beautiful language, but if you try to think about flow of execution (as is
easy to do even in Prolog), you won't get far.

Signature

You can't run away forever,
But there's nothing wrong with getting a good head start.
          --- Jim Steinman, "Rock and Roll Dreams Come Through"
         

Thomas G. Marshall - 07 Aug 2005 14:41 GMT
Stefan Schulz coughed up:

>> If the goal is to be exposed to different things, then prolog is one
>> of the weirder, yet useful, ones.  It is a blurring of what-is-data
[quoted text clipped - 5 lines]
> again. Beautiful language, but if you try to think about flow of
> execution (as is easy to do even in Prolog), you won't get far.

Perhaps the very first introduction to absurd-flow of execution are
makefiles.  They are god-awfully tough for the newbie to figure out.  Even
very seasoned programmers end up going "huh" once in a while.  GnuMake made
things much more sane with a few very select changes that made the world
better, but it still a fairly strong hammer to the top to bottom intuitions.

Signature

Framsticks.  3D Artificial Life evolution.  You can see the creatures
that evolve and how they interact, hunt, swim, etc. (Unaffiliated with
me). http://www.frams.alife.pl/

Dale King - 10 Aug 2005 06:01 GMT
> Perhaps the very first introduction to absurd-flow of execution are
> makefiles.  They are god-awfully tough for the newbie to figure out.  Even
> very seasoned programmers end up going "huh" once in a while.  GnuMake made
> things much more sane with a few very select changes that made the world
> better, but it still a fairly strong hammer to the top to bottom intuitions.

I'll second that. I've spent many, many hours over the past week refinig
the makefiles for a C/C++ project being sure that my make is
non-recursive (see Recursive make considered harmful), and that it works
when run using the -j option to build in parallel, and dealing with bugs
in gnu make (that have not been fixed in a release of gnu make even
though it was fixed 3 years ago). I ended up using many of the advanced
options of gnu make (target and pattern specific variables, order only
prerequisites, etc.)

Signature

 Dale King

Kenneth P. Turvey - 10 Aug 2005 07:16 GMT
> I'll second that.

Third!  What was with the invisible tab character being all important in the
syntax of the language. It was a bad design.  

Although I've used ant I haven't really gotten down to the nitty gritty of
it.  The tool, Netbeans, mostly hides ant from me.  

Signature

Kenneth P. Turvey <kt@squeakydolphin.com>

blmblm@myrealbox.com - 11 Aug 2005 01:58 GMT
>> I'll second that.
>
>Third!  What was with the invisible tab character being all important in the
>syntax of the language. It was a bad design.  

Even the inventor may think so.  A while back I came across the
following, said to be a paraphrase from an article by Brian Kernighan
on the origins of Unix:

   The tab in makefile was one of my worst decisions, but I
   just wanted to do something quickly. By the time I wanted
   to change it, twelve (12) people were already using it,
   and I didn't want to disrupt so many people.

"FWIW", maybe.

[ snip ]

| B. L. Massingill
| ObDisclaimer:  I don't speak for my employers; they return the favor.
Signature

-- blm

Thomas G. Marshall - 11 Aug 2005 02:41 GMT
blmblm@myrealbox.com coughed up:
>>> I'll second that.
>>
[quoted text clipped - 9 lines]
>    to change it, twelve (12) people were already using it,
>    and I didn't want to disrupt so many people.

LOL.  TWELVE PEOPLE!

Oh man.  Good thing he didn't make the thing more sensible---he could have
ruined the productivity of a dozen people for maybe 10 minutes.

Signature

Sometimes life just sucks and then you live.

Dale King - 12 Aug 2005 03:19 GMT
>>I'll second that.
>
> Third!  What was with the invisible tab character being all important in the
> syntax of the language. It was a bad design.  

While it is a bit of nuisance, in practice it isn't that big of a deal.
Make will usually tell you.

> Although I've used ant I haven't really gotten down to the nitty gritty of
> it.  The tool, Netbeans, mostly hides ant from me.  

There is very little realationship between make and Ant in my opinion.
Ant is much closer to batch files than make. Make is all about
dependencies between files and making sure things get built built in the
right order and that no more than is necessary is rebuilt. Ant has
almost none of that. A good makefile should always guarantee a good
build (as long as you abide by the assumption of make that files only
get newer and can never get older). It is trivial to have Ant tell you
everything is built when it doesn't build all that it needs to.

Unfortunately, Java is a different environment than older language. Make
doesn't work well with Java because Java can have circular dependencies
which require compiling more than one file at a time and compiling a
single file can produce many files.

There is no good command line build system for Java.

Signature

 Dale King

Thomas G. Marshall - 10 Aug 2005 14:56 GMT
Dale King coughed up:

>> Perhaps the very first introduction to absurd-flow of execution are
>> makefiles.  They are god-awfully tough for the newbie to figure out.
[quoted text clipped - 11 lines]
> the advanced options of gnu make (target and pattern specific
> variables, order only prerequisites, etc.)

I often thought that perhaps make was a good /very/ simple idea that grew an
inch at a time into an unwieldy multi-ton high inertia rolling pile of
steaming crap.  (You've just rekindled some very bitter memories with your
story.)  I'm sure there has been more than a few engineers out there who
have punted and "rolled their own" builder out of some shell script.

<idle thought> I wonder if a make->csh converter (or make->perl, etc.) would
produce anything more intuitive? </idle>

Signature

"It's easier to be terrified by an enemy you admire."
-Thufir Hawat, Mentat and Master of Assassins to House Atreides

Tor Iver Wilhelmsen - 10 Aug 2005 15:27 GMT
> I'll second that. I've spent many, many hours over the past week
> refinig the makefiles for a C/C++ project being sure that my make is
> non-recursive

May I suggest installing Ant and use that for the C compilation? Ant
is "make" done right.
Dale King - 12 Aug 2005 03:25 GMT
>>I'll second that. I've spent many, many hours over the past week
>>refinig the makefiles for a C/C++ project being sure that my make is
>>non-recursive
>
> May I suggest installing Ant and use that for the C compilation? Ant
> is "make" done right.

Hardly! Ant is a glorified batch file. It's a very nice batch file but
is nothing like make. It's OK for distributing a project where someone
is just going to build your stuff from scratch. For day to day
development I sure wouldn't trust Ant.

Unfortunately, there's not really an ideal solution for command line
builds of Java. There's JavaMake which is pretty good, but I don't think
works with 1.5.
Signature

 Dale King

Tor Iver Wilhelmsen - 12 Aug 2005 15:16 GMT
> Hardly! Ant is a glorified batch file.

Nonsense, and actually using Ant, with filesets, depends and
everything would tell you this.

Though using the bare minimum tasks instead of all the possibilities
can lead you to such a conclusion.
Dale King - 13 Aug 2005 14:43 GMT
>>Hardly! Ant is a glorified batch file.
>
[quoted text clipped - 3 lines]
> Though using the bare minimum tasks instead of all the possibilities
> can lead you to such a conclusion.

No the conclusion is still valid.

Depends does not work in all cases. I think you meant dependset not
fileset, but all it does is delete files.

It's nice that Ant got rid of using tabs, that it created standardized
cross-platform actions so you don't have to rely on going out to the
shell to perform most actions, and that it is easily extendible with
your own cross-platform actions. But they threw away the basic
expression of how files depend on each other. They bolted on some
hit-and-miss ad-hoc dependency checks. Some of the tasks will check if
they need to be rebuilt, others do not.

The fundamental abstraction of Ant are actions to perform (just like a
batch file). The fundamental absraction of make are the dependency
relationships among the actual artifacts.

Of course I am not saying that everyone should switch to make for
building Java. Make doesn't work for Java. Java is a difficult build
problem.

But Ant definitely does not deserve being called "make" done right. It's
a nice form of cross platform batch file. You can build using batch
files and in fact the one time I need command line building the solution
was to use a batch file and build clean every time.

The best build advice right now is to use an IDE like Eclipse, but that
really only addresses the Java compilation.

Signature

 Dale King

Thomas G. Marshall - 13 Aug 2005 18:17 GMT
Dale King coughed up:

>>> Hardly! Ant is a glorified batch file.
>>
[quoted text clipped - 20 lines]
> batch file). The fundamental absraction of make are the dependency
> relationships among the actual artifacts.

Which is *precisely* the problem.  That relationship does not lend itself to
intuitive control flow.  Make and top-down execution are strangers to each
other.  Add to that variable passing, and you have a huge mess.

The fact that you refer to ant as a glorified batch file is to me one of the
greatest compliments you can give it.

...[rip]...

Signature

http://www.allexperts.com is a nifty way to get an answer to just about
/anything/.

Dale King - 15 Aug 2005 02:40 GMT
> Dale King coughed up:
>
[quoted text clipped - 26 lines]
> intuitive control flow.  Make and top-down execution are strangers to each
> other.  Add to that variable passing, and you have a huge mess.

That's because the problem of knowing what to build and the order to
build it does not lend itself to "control flow".

> The fact that you refer to ant as a glorified batch file is to me one of the
> greatest compliments you can give it.

As long as you're happy with a build system that will build things that
don't need to be rebuilt and will sometimes not rebuild things that need
to be built then more power to you. Just don't try to fool people into
thinking that Ant is "make done right".

In my opinion if your build system requires you to sometimes do a "make
clean" in order to get a correct build then your build system is broken.
The only way to guarantee a correct build with Ant (and batch files) is
to always rebuild everything.

Signature

 Dale King

Tor Iver Wilhelmsen - 14 Aug 2005 08:28 GMT
> But they threw away the basic expression of how files depend on each
> other.

That's because such dependencies (I assume you mean the file extension
mappings like .c to .o) aren't necessarily the same for all source
files in more complex projects, where make requires multiple makefiles
to use different compiler flags etc.

So the expression is not basic.

> They bolted on some hit-and-miss ad-hoc dependency checks.

They leave dependency checking to the particular task; e.g. the docs
for the javac task says: "Only Java files that have no corresponding
.class file or where the class file is older than the .java file will
be compiled."

> Some of the tasks will check if they need to be rebuilt, others do
> not.

Exactly; so it's a choice the task writer makes. Make needs to check
dependencies because the C compiler doesn't. And which tasks other
than javac do you feel would need to check a dependency?

> The fundamental abstraction of Ant are actions to perform (just like a
> batch file).

Not just like a batch file, since a batch file consists of invocation
of multiple independent programs that take varying options, parameters
etc.

Ant has a framework that unifies how you deal with paths, filesets,
directories and other elements.

> The fundamental absraction of make are the dependency relationships
> among the actual artifacts.

You are focusing on the one feature make has that Ant lacks, but it's
not as useful (for Java development) as you believe it is, and looks
more like a workaround for a deficiency in the C compiler. Yes, an
author of a C-compiler task would need to add code to check
dependencies. But Ant has several advantages that more than make up
for the lack of this automated dependency checking.

> Of course I am not saying that everyone should switch to make for
> building Java. Make doesn't work for Java. Java is a difficult build
> problem.

No, it's not: It just adds the package-to-path dependency that C++/C#
etc. avoids.

Make is unsuited to Java because Make is there to add "smartness" to
dumb old compilers (including the use of makedepend/mkdep to find
preprocessor dependencies), and otherwise act as a "glorified batch
file". Make is for people who thought #ifdef __SYSV__ is a good idea.

Ant however is there to provide a framework for cross-platform
development with smart compilers.

> But Ant definitely does not deserve being called "make" done right.
> It's a nice form of cross platform batch file.

Not any more than make is. Unless you only use "exec"-type tasks to
run command-line programs.
Thomas G. Marshall - 15 Aug 2005 01:34 GMT
Tor Iver Wilhelmsen coughed up:

>> But they threw away the basic expression of how files depend on each
>> other.
[quoted text clipped - 19 lines]
> dependencies because the C compiler doesn't. And which tasks other
> than javac do you feel would need to check a dependency?

Javac isn't perfect either (think public static final id's), but your
assessment is correct.

>> The fundamental abstraction of Ant are actions to perform (just like
>> a batch file).
[quoted text clipped - 11 lines]
> You are focusing on the one feature make has that Ant lacks, but it's
> not as useful (for Java development) as you believe it is,

Dale doesn't seem particularly thrilled with make for java either.  I
understand that position.  Lacking all else, I've used make in the distant
past, but they are /very/ small makefiles, and I absolutely loathe having to
maintain makefiles that have been written by others willing to develop
multi-page monstrosities.

I go further though, in that I firmly believe that most engineers believe
that there is an intrinsic value to make that is not entirely summed up in
speed-to-compile.  That is, I think that most miss the point (or outright
disagree for some reason) that if compilation time was 0 seconds, make would
never have existed at all, and everyone would be compiling everything, top
to bottom, every time.

Make has /no/ value other than this.  I've been told emphatically by an
engineer before "you're wrong, it gives you a way to organize your sources."
It does not.  Such organization that you might perceive is only there to
save compilation time.

Compilation time is still an issue these days however, I'm not denying this.
But computing speed has IMO fairly well outraced the increased number of
source modules.  I remember back when things were rotten how long it might
take to compile an application of merely 70 C modules.  {author shudders}.

> and looks
> more like a workaround for a deficiency in the C compiler. Yes, an
[quoted text clipped - 22 lines]
> Not any more than make is. Unless you only use "exec"-type tasks to
> run command-line programs.

Signature

If I can ever figure out how, I hope that someday I'll
succeed in my lifetime goal of creating a signature
that ends with the word "blarphoogy".

Dale King - 15 Aug 2005 14:34 GMT
> Tor Iver Wilhelmsen coughed up:
>
[quoted text clipped - 16 lines]
> Dale doesn't seem particularly thrilled with make for java either.  I
> understand that position.

As I've said the model of Java compilation is incompatible with make's
model. But that doesn't mean I am willing to accept another build system
that discards the correctness and efficiency that make provides.

> Lacking all else, I've used make in the distant
> past, but they are /very/ small makefiles, and I absolutely loathe having to
> maintain makefiles that have been written by others willing to develop
> multi-page monstrosities.

The make system I developed was for a very large system with 20
developers and hundreds of object files. The makefiles are not that
large. They are only difficult to understand due to make's cryptic
syntax and workarounds for bugs in gnu make. I won't deny make has huge
warts.

> I go further though, in that I firmly believe that most engineers believe
> that there is an intrinsic value to make that is not entirely summed up in
> speed-to-compile.  That is, I think that most miss the point (or outright
> disagree for some reason) that if compilation time was 0 seconds, make would
> never have existed at all, and everyone would be compiling everything, top
> to bottom, every time.

I agree with you there. The necessary characteristics of a build system
are correctness and efficiency. Any system that achieves that is
acceptable. If building from scratch were efficient (it already
guarantees correctness) then that would be the way to go. And it would
not have to be zero. As long as it is fast enough that I don't divert my
attention elsewhere that is good enough.

In fact the one time I cared about building from the command line for
Java (when I originally looked at Ant due to the hype about it being
make done right) I eventually settled on using batch files and building
from scratch. This was for delivering demos to a partner. Day to day
development was in Visual Age for Java.

> Make has /no/ value other than this.  I've been told emphatically by an
> engineer before "you're wrong, it gives you a way to organize your sources."
> It does not.  Such organization that you might perceive is only there to
> save compilation time.

I'll agree with you. But remember that make is for efficient *AND*
correct builds.

> Compilation time is still an issue these days however, I'm not denying this.
> But computing speed has IMO fairly well outraced the increased number of
> source modules.  I remember back when things were rotten how long it might
> take to compile an application of merely 70 C modules.  {author shudders}.

And the C/C++ application where you told me to use Ant takes 7-8 minutes
to build from scratch.

And you seem to ignore the correctness aspect of the build system.
Computing speed has little benefit if it quickly generates a bad build.

Once again Ant guarantees neither correctness nor efficiency.
Signature

 Dale King

Thomas G. Marshall - 15 Aug 2005 17:27 GMT
Dale King coughed up:

...[rip]...

>> Compilation time is still an issue these days however, I'm not
>> denying this. But computing speed has IMO fairly well outraced the
[quoted text clipped - 4 lines]
> And the C/C++ application where you told me to use Ant takes 7-8
> minutes to build from scratch.

I did not tell you to use anything.  Nor, fwiw, did I ever say that ant was
"make done right".

Are you confusing me with someone else here?

> And you seem to ignore the correctness aspect of the build system.

No.

The "correctness" that you refer to is what I consider to be something that
goes without saying.  If it is not correct enough to use, then it's not part
of this conversation. make and (I assume) ant are correct enough to use, so
it's not sensible to add another variable-axis of complexity to our
discussion.  I can vouche for make to be correct enough---I've used it.  I
just hate the thing, for the reasons already described.

Actually, I don't even have, nor have I claimed to have, any real experience
with ant.  My entire contribution concerning ant here was to point out that
if you called ant a glorified batch file, that it was an appealing
attribute, not a condemning one.  For example, I often speculate just how
many times make has been abandoned for some scripting language concoction.

...[rip]...

Signature

"Well, ain't this place a geographical oddity!
Two weeks from everywhere!"

Dale King - 16 Aug 2005 12:57 GMT
> Dale King coughed up:
>
[quoted text clipped - 13 lines]
>
> Are you confusing me with someone else here?

Oops, sorry that was Tor. Got the T's confused.

>>And you seem to ignore the correctness aspect of the build system.
>
[quoted text clipped - 6 lines]
> discussion.  I can vouche for make to be correct enough---I've used it.  I
> just hate the thing, for the reasons already described.

Then you assume incorrectly. For something like C with a well-written
makefile correctness is guaranteed (if you abide by the rule that files
can only get newer).

For ant that correctness is not guaranteed at all. That comes about by
making the dependency checking ad-hoc.

For Java compilation in Ant specifically the javac task only gives you
the correctness of javac which is not good enough. They added a depends
task to try to make up for the lack of dependency checking, but it has
limitations and will fail to rebuild dependencies on constants. There is
the JavaMake program that has an ant task which does guarantee
correctness, but at a sacrifice of efficiency.

> Actually, I don't even have, nor have I claimed to have, any real experience
> with ant.

And the problem is there is a lot of hype with Ant that isn't true.
People here that Ant is a better make and believe it.

>  My entire contribution concerning ant here was to point out that
> if you called ant a glorified batch file, that it was an appealing
> attribute, not a condemning one.  For example, I often speculate just how
> many times make has been abandoned for some scripting language concoction.

It would not be appealing to anyone that has actually used a batch file
for day-to-day building.
Signature

 Dale King

Thomas G. Marshall - 16 Aug 2005 15:07 GMT
Dale King coughed up:
>> Dale King coughed up:
>>
[quoted text clipped - 34 lines]
> For ant that correctness is not guaranteed at all. That comes about by
> making the dependency checking ad-hoc.

You said "well-written makefile".  Does not ant require something
"well-written" as well?  If make is not "well-written", it does not
guarantee anything either.

> For Java compilation in Ant specifically the javac task only gives you
> the correctness of javac which is not good enough. They added a
> depends task to try to make up for the lack of dependency checking,
> but it has limitations and will fail to rebuild dependencies on
> constants. There is the JavaMake program that has an ant task which
> does guarantee correctness, but at a sacrifice of efficiency.

I'll be glad to take your word for it here.  That sacrifice for efficiency
can't possibly be all that much, or can it?

>> Actually, I don't even have, nor have I claimed to have, any real
>> experience with ant.
[quoted text clipped - 10 lines]
> It would not be appealing to anyone that has actually used a batch
> file for day-to-day building.

That's a stretched assumption.  I had a home grown set of csh scripts that I
used for over 5 1/2 years, and loved it.  I had used make prior, and have
since, but I miss my concoction.
kevindotcar@gmail.com - 17 Aug 2005 19:15 GMT
[---]

> That's a stretched assumption.  I had a home grown set of csh scripts that I
> used for over 5 1/2 years, and loved it.  I had used make prior, and have
> since, but I miss my concoction.

Sorry, but one question I just have to ask;

Do you miss it because it's frozen?

kDot
Andrew Thompson - 17 Aug 2005 19:27 GMT
> Sorry, but one question I just have to ask;

Please ask it on c.l.j.advocacy, where this matter
seems to have originated.
<http://groups.google.com/group/talk.bizarre/msg/64bffd268aa7896e>

Oh, and stop setting the headers on posts to c.l.j.help,
as cross-posts to other groups.  Newsgroups reset to
c.l.j.help only.  

Do your trolling elsewhere.

Signature

Andrew Thompson
physci.org 1point1c.org javasaver.com lensescapes.com athompson.info
"I know what I want but I just don't know ..how to go about gettin' it."
Jimi Hendrix 'Manic Depression'

Andrew Thompson - 17 Aug 2005 19:37 GMT
>> Sorry, but one question I just have to ask;
>
> Please ask it on c.l.j.advocacy, where this matter
> seems to have originated.
> <http://groups.google.com/group/talk.bizarre/msg/64bffd268aa7896e>

Got it now.  Having not contributed to the thread I observed
on c.l.j.advocacy, I had not noticed you (or someone) were
x-posting/trolling there as well..

(shrugs) The posters to c.l.j.a. are big enough and ugly enough
to look after themselves, but keep this crap off c.l.j.help.

Signature

Andrew Thompson
physci.org 1point1c.org javasaver.com lensescapes.com athompson.info
"The rich getting richer, the poor get the picture."
Midnight Oil 'Read About It'

Dale King - 18 Aug 2005 12:50 GMT
> Dale King coughed up:
>
[quoted text clipped - 40 lines]
> "well-written" as well?  If make is not "well-written", it does not
> guarantee anything either.

You and Tor have both mentioned this now and I fail to see the point.
Yes you can write bad make files and bad Ant scripts that do not work
correctly. You can write good make files that guarantee correctness and
efficiency. However you *cannot* write Ant scripts that guarantee both.

If you are interested in a formal theory on the necessary conditions for
a makefile to achieve this see:

http://ep.lib.cbs.dk/download/ISBN/x648032182.pdf

>>For Java compilation in Ant specifically the javac task only gives you
>>the correctness of javac which is not good enough. They added a
[quoted text clipped - 5 lines]
> I'll be glad to take your word for it here.  That sacrifice for efficiency
> can't possibly be all that much, or can it?

Well the sacrifice using JavaMake is first that if you change a public
static final constant everything is rebuilt. That is the only way it
guarantee correctness because it has no idea who might have used that
constant. In the same situation with Ant using the depends task you just
get a bad build.

It is also a little slower in general because it does a more thorough
analysis of the classfiles. It parses them and saves information about
them. On the next run if they change it actually figures out what
changed and who depended on that. So on the good side if you change a
comment it doesn't recompile other things, but on the bad side all that
extra analysis slows things down.

I was going to point you to the web pages for JavaMake that talked about
it, but it appears it may have been a victim of the worm.

That extra analysis is why it would be really nice to truly have a smart
compiler that integrated the logic of JavaMake. The compiler already has
all the information that JavaMake gets from analyzing the class files
and more.

>>> My entire contribution concerning ant here was to point out that
>>>if you called ant a glorified batch file, that it was an appealing
[quoted text clipped - 8 lines]
> used for over 5 1/2 years, and loved it.  I had used make prior, and have
> since, but I miss my concoction.

I was thinking more of the inefficiency of the batch files recompiling
things that don't need to be recompiled.
Signature

 Dale King

hawat.thufir@gmail.com - 18 Aug 2005 19:38 GMT
...
> >>>The "correctness" that you refer to is what I consider to be
> >>>something that goes without saying.  If it is not correct enough to
[quoted text clipped - 7 lines]
> >>makefile correctness is guaranteed (if you abide by the rule that
> >>files can only get newer).
...
> You and Tor have both mentioned this now and I fail to see the point.
> Yes you can write bad make files and bad Ant scripts that do not work
[quoted text clipped - 5 lines]
>
> http://ep.lib.cbs.dk/download/ISBN/x648032182.pdf
...

What's meant by correctness?

-Thufir
Dale King - 24 Aug 2005 14:15 GMT
> ....
>
[quoted text clipped - 23 lines]
>
> What's meant by correctness?

It's in the paper I linked to which calls it "safeness", but to
summarize it basically means that if I change some files and invoke the
builder then it must give you the same result as you would have gotten
by building from scratch.

Ant using just the javac task definitely does not achieve that and it is
trivial to produce a case that shows this as I have done in this thread.

Using the depends task will handle some more modifications but doesn't
handle changes in static final constants.

Using the JavaMake task does achieve "correctness" at the expense of
efficency. In cases like public static final constant being changed it
punts and rebulds from scratch.

I saw in another thread that the Eclipse compiler can be run as a
separate tool and has an Ant task. I need to investigate how it performs.

Signature

 Dale King

Dale King - 15 Aug 2005 13:31 GMT
>>But they threw away the basic expression of how files depend on each
>>other.
[quoted text clipped - 5 lines]
>
> So the expression is not basic.

And such dependencies don't have to be the same for all source files.
The project I am working on is a complex project. The make file system
we have allow you to have different settings per directory. Each
directory has a kind of makefile, but that makefile is nothing more than
setting of variables. It is included into the master make file.

Perhaps you aren't aware of static pattern rules, target specific
variables, and pattern specific variables.

>>They bolted on some hit-and-miss ad-hoc dependency checks.
>
> They leave dependency checking to the particular task; e.g. the docs
> for the javac task says: "Only Java files that have no corresponding
> ..class file or where the class file is older than the .java file will
> be compiled."

That is why I called it ad-hoc.

>>Some of the tasks will check if they need to be rebuilt, others do
>>not.
>
> Exactly; so it's a choice the task writer makes. Make needs to check
> dependencies because the C compiler doesn't. And which tasks other
> than javac do you feel would need to check a dependency?

Thus why it is hit-and-miss. One task might always do its task whether
it needs to or not and another might decide that it doesn't need to yet
it really did need to.

The correctness of building is not something to be left to the whim of
those writing the tasks.

>>The fundamental abstraction of Ant are actions to perform (just like a
>>batch file).
>
> Not just like a batch file, since a batch file consists of invocation
> of multiple independent programs that take varying options, parameters
> etc.

And that differs from Ant in what way?

> Ant has a framework that unifies how you deal with paths, filesets,
> directories and other elements.

As I said it is a very nice batchfile.

>>The fundamental absraction of make are the dependency relationships
>>among the actual artifacts.
>
> You are focusing on the one feature make has that Ant lacks,

Because it is the most important feature for doing builds that are
correct (builds everything that needs to be built) and efficient (don't
build more than needs to be built). Ant achieves neither. A well written
makefile for something like C does both.

> but it's
> not as useful (for Java development) as you believe it is,

I've been very clear that make does not work for Java. This particular
subthread was started with Thomas suggesting I should use Ant for C
compilation because "Ant is make done right". Ant is definitely not make
done right!

> and looks
> more like a workaround for a deficiency in the C compiler. Yes, an
> author of a C-compiler task would need to add code to check
> dependencies.

No, the reason it works for C and not Java is not that C is deficient.
It is that the two have different compilation models.

The dependencies in C always look like this:

  foo.o ----> foo.c ----> header files

Java is not that simple. First one source file can produce more than one
 class file. Secondly, compilation does not depend on text header
files, but on other class files. Thirdly, Java allows circular
dependencies which can only be resolved by compiling the source files at
the same time.

Those rules are incompatible with make's DAG.

The only truly correct way to do efficient and correct builds in Java is
to get into the compiler. That is what Eclipse does for instance. They
have their own compiler from which they extract the necessary dependencies.

There are class-file analysis tools that try to figure out the
dependencies from the class files. The problem is that some dependencies
are not expressed in the class file (e.g. dependencies only on a constant).

One is the Ant depends task, which doesn't work if the dependency is not
in the classfile. There is another tool called JavaMake (which has an
Ant task) that sacrifices efficiency for correctness. It maintains state
of what it analyzed in the class files last time and compares it with
the current contents of the class file. It can detect that a constant
changes, but if one does it recompiles any class that could have
depended on it. For a public constant that means recompiling everything.

> But Ant has several advantages that more than make up
> for the lack of this automated dependency checking.

In other words, if you are willing to sacrificed correctness of builds
and efficiency of builds then it has some nice window dressing to make
expressing those inefficent, incorrect builds.

I used to live in a world of incorrect builds when developing under
Windows CE Platform builder. It was routine to have a build not work,
rebuild from scratch and then have it work. And at one time a build from
scratch took 30 minutes (when we got new machines it went to 10
minutes). A build where there was nothing to do would also take minutes
as it did work that wasn't necessary.

Believe me that is not a fun world to develop in. I get a little
skeptical of people telling me that build correctness and build
efficiency are not that important.

>>Of course I am not saying that everyone should switch to make for
>>building Java. Make doesn't work for Java. Java is a difficult build
>>problem.
>
> No, it's not: It just adds the package-to-path dependency that C++/C#
> etc. avoids.

See above. The difference is the compilation model.

> Make is unsuited to Java because Make is there to add "smartness" to
> dumb old compilers (including the use of makedepend/mkdep to find
> preprocessor dependencies),  and otherwise act as a "glorified batch
> file". Make is for people who thought #ifdef __SYSV__ is a good idea.

Dependencies are always there in building programs. You can't just
assert your bias against C/C++ development and assume that it all was
because of stupid people. Java didn't get rid of dependencies, it just
moved those dependencies from being dependent only on source files to
being dependent on the output of the compilation for other source files.
That leads to circular dependencies that can only be solved by the fact
that Java can sort it out if the files are compiled at the same time.

> Ant however is there to provide a framework for cross-platform
> development with smart compilers.

What smart compilers are these? Javac is a pretty dumb compiler.

>>But Ant definitely does not deserve being called "make" done right.
>>It's a nice form of cross platform batch file.
>
> Not any more than make is. Unless you only use "exec"-type tasks to
> run command-line programs.

No make was created to ensure efficent builds that were also correct. A
correctly written makefile can guarantee that.

Java however breaks the model of make. The make model assumes:

- No circular dependencies. Make uses a directed *acyclic* graph.
Dependencies in Java are routinely cyclic. Dependencies in C/C++ are
never cyclic.
- Artifacts can be built independent of each other. There are cases in
Java where you cannot compile A.java and B.java separately. You have to
compile them at the same time. In C/C++ you can always compile separately.
- One set of commands produces one output. Make has some support for
this but only in pattern rules. Compiling one Java source file can
produce many class files. In C/C++ one source file produces one object
file. It can also produce dependencies and other listing files. To
express that in make requires a pattern rule.

So there is a difference between make and Ant. Make guarantees correct
and efficient builds if your build fits in its model. Ant guarantees
neither. Ant's guarantees are no greater than using a batch file which
is why I call it one. Make is an expert system. You give it the rules
and it applies the rules.
Signature

 Dale King

Tor Iver Wilhelmsen - 15 Aug 2005 15:19 GMT
> The dependencies in C always look like this:
>
>    foo.o ----> foo.c ----> header files

Yes, prior to linking, they are that simple. Javac, however, resolves
the "link relationships" at compile time.

> Java is not that simple. First one source file can produce more than
> one class file.

Yes, but in a deterministic location.

> Secondly, compilation does not depend on text header
> files, but on other class files.

Correct: The horrid header files, an artifact of when disk space was
scarce, were abandoned when they made Java.

> Thirdly, Java allows circular dependencies which can only be
> resolved by compiling the source files at the same time.

Only if the "object files" (.class files) don't exist at compile time.
Again, this is a direct consequence of the C compiler leaving much of
what javac does to the later linking step.

And you forgot to complain about the dynamic dependencies made
possible by Class.forName() and the like.

> Those rules are incompatible with make's DAG.

So make is unsuited for Java. We get that. But why the attack on Ant?

> They have their own compiler from which they extract the necessary
> dependencies.

Yes, they compile everything "at once" and references the compiled
state. Other IDEs do things close to that, e.g. JBuilder.

> In other words, if you are willing to sacrificed correctness of
> builds and efficiency of builds then it has some nice window
> dressing to make expressing those inefficent, incorrect builds.

Ant, just like make, depends on the "makefile" author to express what
sourcefiles they want built. How can a tool be blamed for the errors
of its users?

Do you have a definition of this "correctness of builds" your whole
argument seems to rest on?

> Believe me that is not a fun world to develop in. I get a little
> skeptical of people telling me that build correctness and build
> efficiency are not that important.

I find it very efficient. And correct, in the sense it does what the
developer tells it to do.

> Dependencies are always there in building programs. You can't just
> assert your bias against C/C++ development and assume that it all
> was because of stupid people.

Not stupid people, stupid technology. Objective-C tried to fix the
most glaring problem with header files - multiple inclusion - by
adding #import, but by then the workaround of using
#ifndef __SOMETHING__
#define __SOMETHING__

...

#endif

had been established as a common practice.

> Java didn't get rid of dependencies, it just moved those
> dependencies from being dependent only on source files to being
> dependent on the output of the compilation for other source files.

As is C/C++ when it comes to link time.

> That leads to circular dependencies that can only be solved by the
> fact that Java can sort it out if the files are compiled at the same
> time.

But if c/c++ does not have circular dependencies between files, why
does make have checks against them?

> No make was created to ensure efficent builds that were also
> correct. A correctly written makefile can guarantee that.

It depends on the user just as much as Ant, then.

> - No circular dependencies. Make uses a directed *acyclic* graph.

Make still has code to detect circular dependencies.

> Dependencies in Java are routinely cyclic. Dependencies in C/C++ are
> never cyclic.

Dependencies between make targets can be.

> - Artifacts can be built independent of each other. There are cases
> in Java where you cannot compile A.java and B.java separately.

Because javac does "link-time lookups" when compiling. You avoid this
problem in your praise of make.

> You have to compile them at the same time. In C/C++ you can always
> compile separately.

Only if you compile to (intermediate) object files.

> - One set of commands produces one output. Make has some support for
> this but only in pattern rules. Compiling one Java source file can
> produce many class files.

Yes, this is a consequence of the language. NOT ANT! If I use Ant to
build Python projects, it seems half your arguments go away?

> Make is an expert system. You give it the rules and it applies the
> rules.

Why, it's the same thing as Ant does then. Only it doesn't run
command-line programs like a batch file would - that is make's way.
Dale King - 17 Aug 2005 13:50 GMT
>>The dependencies in C always look like this:
>>
>>   foo.o ----> foo.c ----> header files

Actually that should really be:

   foo.o ---> foo.c + header files

> Yes, prior to linking, they are that simple. Javac, however, resolves
> the "link relationships" at compile time.

And they are that simple after linking. The important point I was making
was that the dependencies were all one direction and acyclic. foo.o is
never dependent on bar.o thus there cannot be circular dependencies.

>>Java is not that simple. First one source file can produce more than
>>one class file.
>
> Yes, but in a deterministic location.

Assuming that your source files are organized according to package. But
the point is in C the compiler will only produce a single object.

>>Secondly, compilation does not depend on text header
>>files, but on other class files.
>
> Correct: The horrid header files, an artifact of when disk space was
> scarce, were abandoned when they made Java.

I think you grossly mischaracterize why header files were used. First
off don't confuse #include with all the other parts of the preprocessor.
Just because many atrocities have been commited with conditional
compilation and macros is not a reason to condemn the use of header files.

There basically are two models of compilation, the C way where
everything is in textual source code or the Java way where the compiler
uses the output of the compilation of other sources rather than the text
itself.

There are a number of issues if C had gone the latter way. We have
talked about the complexity of circular dependencies. They wanted to be
able to link with existig libraries in other languages. To do it
requires an output format that allows you to encode the necessary
format. What was in exiestence was the object file which did not allow
that kind of specification. There's no way they could drive a new
standard to replace object files. They were stuck with them.

Sun could make their own standard because they didn't care about any of
that compatibility.

So it really had little to do with disk space. Given the constraints it
was the only sensible choice.

>>Thirdly, Java allows circular dependencies which can only be
>>resolved by compiling the source files at the same time.
>
> Only if the "object files" (.class files) don't exist at compile time.

Well the class files can only exist by resolving them by compiling at
the same time at least once.

> Again, this is a direct consequence of the C compiler leaving much of
> what javac does to the later linking step.

No, it isn't. Linking has nothing to do with it. It is the difference in
compilation models.

> And you forgot to complain about the dynamic dependencies made
> possible by Class.forName() and the like.

That's really out of the scope of the build tool and in general an
unsolvable problem.

>>Those rules are incompatible with make's DAG.
>
> So make is unsuited for Java. We get that. But why the attack on Ant?

Because Ant improves on some syntax elements but is a major step
backwards in terms of build correctness. Yet people hype Ant like it is
better than make in all ways.

The trouble is there needs to be a real build tool for Java that has the
niceness of expression of Ant, but not losing any of the fundamental
properties of make (and possibly even improve on them).

I for one see what should be done, but don't have the time or the great
need any more to do it. At one time I started a sourceforge project to
work on it, but never took it anywhere.

So while I can't point you to a tool that is better than Ant other than
an IDE like Eclipse, I can definitely show that better tools than Ant
can and should exist. For non-java development, make *IS* better than Ant.

>>They have their own compiler from which they extract the necessary
>>dependencies.
>
> Yes, they compile everything "at once" and references the compiled
> state. Other IDEs do things close to that, e.g. JBuilder.

And that would be the ideal way to a solution, to get dependency
information from the compiler. The dependencies would not be in make
file format, but as long as they can be produced in some readable format
then you can build a tool to guarantee correctness and efficiency for
building Java code.

>>In other words, if you are willing to sacrificed correctness of
>>builds and efficiency of builds then it has some nice window
[quoted text clipped - 3 lines]
> sourcefiles they want built. How can a tool be blamed for the errors
> of its users?

We're not talking about errors in the "makefile".

With Ant it is not possible to write a build script that will give you
the same guarantees of correctness and efficiency that make gives for C
compilation.

Essentially, there is no way to have an "error-free" Ant script.

> Do you have a definition of this "correctness of builds" your whole
> argument seems to rest on?

Actually, there is a very good paper I found a few years ago that echoed
my thoughts and provides a very formal definition of make "safeness" and
what characteristics are necessary to achieve it is:

http://webhotel.ruc.dk/nielsj/research/papers/make.pdf

The short form of the result is:

"Safeness of make-based incremental compilation, the key result of this
paper, can be stated as follows: Suppose we build a program brute-force,
and then edit the source files, and possibly the makefile as well. Then
under certain assumptions about the makefile rules and the kind of
editing performed, the result of make-based incremental recompilation is
equivalent to the result of a (second) brute force build."

>>Believe me that is not a fun world to develop in. I get a little
>>skeptical of people telling me that build correctness and build
>>efficiency are not that important.
>
> I find it very efficient. And correct, in the sense it does what the
> developer tells it to do.

But may result in incorrect builds. It's probably good enough for most
people with the depends task, but I'd guess the majority don't use
depends. Without depends you're really living dangerously.

>>Java didn't get rid of dependencies, it just moved those
>>dependencies from being dependent only on source files to being
>>dependent on the output of the compilation for other source files.
>
> As is C/C++ when it comes to link time.

The key issue is circularity of dependence. It's OK for the linked
executable or library to be dependent ot the output of the compiler. The
situation with Java is that one output of the compiler is dependent on
other outputs of the compiler causing circular dependencies.

So we can have long chains of dependencies, just not circular ones. Make
cannot deal with circular ones.

>>That leads to circular dependencies that can only be solved by the
>>fact that Java can sort it out if the files are compiled at the same
>>time.
>
> But if c/c++ does not have circular dependencies between files, why
> does make have checks against them?

Because humas are expressing the dependencies and make is not just for
C/C++. You can have a makefile like this:

A : B
    cat B > A
B : A
    cat A > B

There is no way to build this. The way make works is that it finds the
order to build things. Without some check for circular dependencies the
above would become an infinite loop of traversing the dependencies and
make would hang. What make actually does is throw away one of the rules
and gives you warning to know that it did.

>>No make was created to ensure efficent builds that were also
>>correct. A correctly written makefile can guarantee that.
>
> It depends on the user just as much as Ant, then.

Sure you have to write it correctly, but the difference is that with
make (and languages with a similar compilation model to C) it is
possible to write it correctly. With Ant and Java there is nothing the
user can do to achieve both correctness and efficiency. You can only get
one at the cost of the other.

>>- No circular dependencies. Make uses a directed *acyclic* graph.
>
> Make still has code to detect circular dependencies.

Only so it doesn't hang when you give it one.

>>Dependencies in Java are routinely cyclic. Dependencies in C/C++ are
>>never cyclic.
>
> Dependencies between make targets can be.

Yes and make cannot deal with them and thus it cannot deal with Java.
Circular dependencies cannot be dealt with in a general way. It requires
 more specific knowledge of how to resolve it.

>>- Artifacts can be built independent of each other. There are cases
>>in Java where you cannot compile A.java and B.java separately.
>
> Because javac does "link-time lookups" when compiling. You avoid this
> problem in your praise of make.

I have no idea what you mean by link-time lookups, but that has nothing
to do with it. The difference is the compilation model. You could
theoretically have Java that used a C compilation model.

Consider if you have A.java and it produces A.class. Now we are going to
compile B.java and it has a reference to what is defined in A.java.
Where does it get the information? There are two choices leading to the
two compilation models:

- It can read A.class. This is what Java actually does. The advantages
are that it leads to faster compilation, consistent results because the
compiler only reads a piece of source once, greater type checking
because you are looking at what the compiler actually produced, and the
ability to compile a library without requiring any source code. The
disadvantage is that it complicates the build process because it causes
circular dependencies and you can no longer compile each source file
indepently of others.
- It can read A.java. This is the C model. The advantages are that it
has simple build procedure with no circular dependencies and allows
separate compilation. It also allows you to use a very simple output
format for the compiler that is compatible with other languages. The
disadvantages are of course the flip side of the advantages of the Java
model.

Neither is the "correct" model. They both have advantages and
disadvantages. If you look at the constraints of C, needing
compatibility with other languages and a relatively dumb object format,
then its choice of model is a no-brainer.

>>You have to compile them at the same time. In C/C++ you can always
>>compile separately.
>
> Only if you compile to (intermediate) object files.

What's that supposed to mean. Of course it compiles to something. The
difference is that output is never also the input of another
compilation, thus no circularity.

>>- One set of commands produces one output. Make has some support for
>>this but only in pattern rules. Compiling one Java source file can
>>produce many class files.
>
> Yes, this is a consequence of the language. NOT ANT! If I use Ant to
> build Python projects, it seems half your arguments go away?

And the point of this section was why make cannot be used Java and why
Java is a more difficult build problem. I wasn't talking about Ant at
all in this portion. What I was addressing was the claim that C had a
dumb compiler. The difference is not smartness and dumbness but choice
of compilation model.

I don't know about Python's compilation model. Is it like C or Java. Of
course there is still the issue of other tasks and their ad-hoc
dependency checking.

>>Make is an expert system. You give it the rules and it applies the
>>rules.
>
> Why, it's the same thing as Ant does then. Only it doesn't run
> command-line programs like a batch file would - that is make's way.

No. Ant is a list of commands to run just like a batch file. Other than
providing names to groups of commands and allowing you to specify a
fixed ordering for the groups of commands The only logic is to execute
the next command in sequence. So the ordering is fixed at the time of
writing the Ant file.

Make is a set of rules telling the system under what circumstances to
run the commands. It dynamically decides what order to do things based
on the current state. It is making decisions about sequence unlike Ant.

Signature

 Dale King

Tor Iver Wilhelmsen - 17 Aug 2005 17:16 GMT
> And they are that simple after linking. The important point I was
> making was that the dependencies were all one direction and acyclic.
> foo.o is never dependent on bar.o thus there cannot be circular
> dependencies.

But that's because if foo.c and bar.c reference each other's fields or
methods, the C compiler will happily delay resolving them.

Java has namespace concerns that C lacks. Everything belongs
somewhere, not in some global scope.

> But the point is in C the compiler will only produce a single
> object.

Per compilation unit. But that's because unlike Java, that object is
not a namespace - except for the case of static variables. And the C
compiler can do it because it does not have a "package" concept.

> There basically are two models of compilation, the C way where
> everything is in textual source code or the Java way where the
> compiler uses the output of the compilation of other sources rather
> than the text itself.

Again you are ignoring the quite important linking step. Everything
_isn't_ in textual source code at that point; everything is in object
files.

> What was in exiestence was the object file which did not allow that
> kind of specification. There's no way they could drive a new
> standard to replace object files. They were stuck with them.

Sort of correct: It would eventually end up as object files, but they
could have another intermediate dependency-aware format before that.
(Digital had a generic three-address code output you could get from
their MIPS Ultrix C compiler for instance.)

Java .class files (or C# executables) are also an "intermediate" step
before Hotspot/JIT turns it into native code at runtime.

> Sun could make their own standard because they didn't care about any
> of that compatibility.

Yes, but that holds for every virtual machine language, from p-code
and WAM via Perl and Python to Java and the .Net CIL.

> So it really had little to do with disk space. Given the constraints
> it was the only sensible choice.

Well, it seems to be more a case of separating "interface" (the
symbols available to the compiler) and "implementation" (the actual
locations available to the linker).

> Well the class files can only exist by resolving them by compiling
> at the same time at least once.

Yes, but you could conceivably have a javac flag that disabled the
resolution; After all, what is put in the class file are just strings
in the constant pool. After all, I can take a .class file out of its
"context" (or one with different classes) and try runnig it: I am then
likely to get various runtime exceptions and errors, including
NoClassDefFoundError and NoSuchMethodError. But the symbols were
available at

The problems arise with wildcard imports and same-package implicit
imports. These need to know what package a given "symbol" (class)
exists in. Not to mention references to superclass methods and fields.

(So C/C++ in may ways uses header files for exactly the same purposes
the Java compiler uses .class files.)

> No, it isn't. Linking has nothing to do with it. It is the
> difference in compilation models.

Again: It has everything to do with it. The difference is that the
"linker" is not involved in
cc -c a.c
but it is involved in
javac a.java

> Because Ant improves on some syntax elements but is a major step
> backwards in terms of build correctness.

I think the issue here is that Ant's Java compilation task is supposed
to "build everything you need". So it may be inefficient but as long
as the build file actually include all source files in its file set,
it should be a