cs636 class 4

CS636 Class 4 Notes

Handout : Pizza1 Project

Easier once set up: use <javac> and <java> Ant tasks, in build.xml

They wrap javac and java in programmer-friendly ways

<javac>  srcdir and destdir attributes: just specify the tops of the src and .class file trees, and the whole tree of .java files gets compiled

<java> classpath and classname, similar to command. Also put fork=”true” to get a brand-new JVM for your program rather than executing in the used one of Ant itself, which sometimes can cause weird problems. 

<javac> is using sourcepath for us, and also finding all the source files in the src tree for us: javac itself can handle oata/*.java on its command line, but not */*.java, etc.

<javac> compiles all java files in the file tree, that is, all files below the top dir that you specify by srcdir  and puts class file in the file tree specified by dstdir.

Note that <javac> is “smart”: it only compiles sources that are newer than their class files, and things it sees as dependent on those.

--It can be fooled if you move things around on the filesystem, so if worried, do “ant clean” and then “ant compile” or “ant build” to do a “full rebuild”. 

--In eclipse, use Project>Clean to do this important action.

Dependencies in build.xml: look at second example on handout

Need to compile before run

compile → run

ant looks at  <target> element for “run”, sees depends = compile

so does “ant compile” for us, when we do “ant run”. 

Properties: just name-value associations, i.e., in effect string variables to allow us to avoid stupid repetition inside build.xml.

Evaluation of property foo: ${foo}

Can build up strings from pieces, see classes.dir property.

Can evaluate a property even inside an attribute value: the double-quotes (or single quotes) used in attribute value syntax don’t stop this evaluation.

Ex: srcdir = “${src.dir}”.  Ant evaluates ${...} first, then uses resulting XML.

<path> element: a way to define a path (usually a classpath) once for the project, and then use it over and over in various targets.  It has an id attribute, for pointing to by an IDREF attribute elsewhere.

Ant tasks

<javac> 
task from example 1 of handout last time
         <javac srcdir="${src.dir}" destdir="${classes.dir}"/>   
Note that
 <foo/> 
is equivalent to
<foo></foo>
, an element without content, i.e. child elements or text data Same without use of properties:
         <javac srcdir="src" destdir="build/classes"/>  
<javac> 
task from example 2:
         <javac srcdir="${src.dir}" destdir="${classes.dir}">
           <classpath refid="project.classpath"/>
         </javac>
 
Note here how we remove the / from the start tag for
<javac>
to allow it to have a child element.
We need a child element to be the basis of a ref to the "path" element describing the classpath,
because the ID-IDREF mechanism goes from element to element. java task with classpath
<javac> classname="${main-class}" fork="true">
  <classpath  refid="project.classpath"> 
</javac>
</classpath>
How can you find out all the possible attributes and child elements of an ant task?
Docs linked from class web page at apache.org, or Google “ant task javac”.

What about using jar files?

A jar file represnts a tree of files. To see the tree:

   jar tf foo.jar             --shows classes in jar

   java –classpath ojdbc6.jar:. JdbcCheckup

                            ojdbc6.jar:   holds whole tree of directories, contains driver class

Not covered in class:

How java locates x.y.Foo ‘s class:

It takes each entry in the classpath (here odbj6.jar and .) as the top of a real or virtual tree of class files and looks in the tree at the x/y/Foo.class position in the tree, and if there is a class there it uses it.  JdbcCheckup.class is found relative to “.”.  The oracle driver class is located in the jar file.

In other cases, where your program directly uses the classes in a jar file, you need the jar file in the classpath for the javac command, too. JDBC’s top-level methods are in the JDK, so we don’t need to use the driver jar during compiles, only at runtime.

How does that work? JDBC has a standard that specifies the required classes and methods in the drivers. For example, the line from JdbcCheckup.java:

…DriverManager.getConnection(…)

can compile because the class DriverManager, with static method getConnection, is in the JDK.  The code that executes at runtime for this call largely comes from the driver in the jar file.

 End of material not covered in class

Adding jar files to the classpath in build.xml

We need to add jar files to the classpath, but for that, we need to put them somewhere in the project that we can refer to from build.xml.

Usual solution for java projects: add a lib directory to the base directory, and put the jar files there.

Of course, to save on disk space, you can alternatively put jar files in some globally-known directory, but we will do the simplest thing, resulting in a self-contained project.

Adding lib to the project’s file tree:  

            Basedir
          /     /        \
      src    build     lib
              /                 \
        classes       Put jar files we need in here, like ojdbc6.jar

Now we need to fix up the classpath definition.

Same with added pathelement for jar in lib:

    <path  id="project.classpath">

	<pathelement  location="${classes.dir}"/>   
        <pathelement  location="lib/ojdbc6.jar"/>   
   </path>

We see that a jar file adds a whole file tree to the classpath, just like a directory at the top of a real file tree does. We can similarly add jar files for the other driver we need for MySQL and HSQLDB.

Advanced Tip: There is a wildcard way to add all jars in the lib directory to the classpath.

The Pizza Project

We’ll start with a client-server implementation, then later, turn it into a web app.

The first step is studying the supplied Pizza1 project, the example to guide our own development project

See the handout for this class, linked to the class web page. Also the pizza project “Project Description”, linked to the class web page

We use the layered architecture discussed in the first class. We see packages for presentation, service, and dao, corresponding to the layers.


What about package “domain”? It has classes PizzaOrder, PizzaTopping, and PizzaSize. These represent the needed domain objects, the subjects of the application. so the domain package does not have its own layer, though is associated closely with the service layer.

The domain objects are acted on by the code in the service layer, the heart of the application. They also are used in the DAO layer, in a more technical way, to allow the data to be persisted in the database

We can show this on the layer diagram as follows: add notation to the following diagram showing that the domain objects flow to and fro between the service layer and the DAO layer.


layers diagram
Some development groups allow the domain objects to flow also up into the presentation layer, but this can lead to problems, especially if the objects are mutable, so we will stick to the more conservative approach of keeping them inside the main part of the application. We can return to this consideration.

Note that the layers are “call-down” layers: the presentation layer code calls the service API and thus into the service layer. The service layer code calls the DAO API, and the DAO code calls JDBC for pizza1. The presentation layer code never calls the DAO directly.

And nothing ever calls methods of a higher layer. So this is strict layering.

Why would you want to call upwards?

For notifications. Consider when the pizza is ready: the admin action “this pizza is ready” calls down and changes the database. If this change triggered a notification to the student user, that would need an upcall to the presentation layer.

Such notifications can be done in say a Swing application (GUI program running on the user’s machine), because the Swing app owns the screen. It can pop up a little note on the screen.

But we are designing for an (eventual) web app, where the service layer runs in the server and doesn’t own the clients’ screens. The clients use HTTP to ask questions and make commands.

So the client has to explicitly ask “is the pizza done?” and this request is handled in a call-down manner.

That’s the simple web app way. We could explore ways to notify, but it is quite difficult, and we need to keep things simple to get where we want to go in one term.

Consider that from the server’s standpoint, the clients are often hidden behind firewalls—how can you send them information at some arbitrary moment?

They don’t have well-known network addresses! The chance to send them information is when they send a request in to you (the server) and you get to reply to it.

Therefore, we will stick to the simple call-down layers.

Note: Presentation code is not allowed to use domain objects, but it can use information from them.

Example: The presentation code gets topping names (simple Strings) by calling getToppingNames, size names by calling getSizeNames, then displays them as options to the user, and uses the chosen objects in the call to makeOrder.

The domain objects carry info, often “scratch copies” of DB data, or data bound for DB