cs636 class 3

 CS636 Class 3 Notes

Hw1 due Monday

Resources: Source code for JdbcCheckup.java.
XML and Ant Examples

Running the provided JdbcCheckup Program (source shown from online link)

First compile JdbcCheckup.java. No special classpath needs to be set up for this:

javac JdbcCheckup.java

This command assumes that JdbcCheckup.java is in the current dir.

Now we have JdbcCheckup.class in the current dir.  Use java to run it as follows. We need to add the driver jar file to the classpath to give the program access to the implementation of the JDBC API.

java –classpath driver.jar;. JdbcCheckup     (for Windows)
                                     ^^^^ (change ‘;’ to ‘:’ for UNIX/Linux)

This command assumes that JdbcCheckup.class and driver.jar are in the current dir. Replace driver.jar with the appropriate .jar file from $cs636/jdbc. Also, -classpath can be abbreviated -cp.

1. In the program, we find out what database the user wants to connect to, and their username and password (for Oracle or mysql) and for Oracle, the server host ("dbs3.cs.umb.edu) and port (1521) and sid ("dbs3") compose the "connection string" or "database url":  for Oracle, this is "jdbc:oracle:thin:@dbs3.cs.umb.edu:1521/dbs3".  This step just involves user input and Java strings. It ends up with strings connStr, user, and password.

2. Get a connection from the driver

Connection conn = Driver.Manager.getConnection(connStr, user, password)

                                            "jdbc:oracle:thin:@dbs3.cs.umb.edu:1521/dbs3", “scott”, “tiger1”

for mySql, for user "joe", who has database "joedb": "jdbc:mysql://topcat.cs.umb.edu:3306/joedb", "joe", "joe"

3. Create a statement

Statement stmt = conn.create statement();

4. Do DB action –

Stmt.execute(“drop table welcome”) ;

ResultSet rest = stmt.excuteQuery(“select * from welcome”) ;

5. Close connection (and its associated objects )

conn.close() ← in finally clause ← important to free up TCP/IP connection into the DB

Actually, program exit will close the connection.

See pattern of try within try.  

Java Exceptions: see Java Tutorial on Exceptions. Another tutorial:http://www.tutorialspoint.com/java/java_exceptions.htm

Note: We don't need Java 7 "exception with resources".

Exceptions are widely used in Java code to signal failure of a method to its callers.  What’s special here is that this signaling can jump back to the caller’s caller or even the caller’s caller’s caller, not just to the immediate caller.

Each exception is thrown by a certain method and caught in another method that has prepared to catch it by providing a catch clause in a try/catch.

Ex. A has try/catch, calls B with no try/catch, calls C which throws

Execution ends up in A’s catch clause.  B never sees C return to it, so not all calls return to their caller in Java.

JDBC = Messy Exceptions!

SQLException (base class of all JDBC exceptions) is a checked exception (not a runtime exception)  That means we have to program try/catch to handle it or add throws… to the method signature, i.e., this kind of exception, the checked exception, is tracked aggressively by the compiler to force developer’s attention on doing something about the error conditions.  Another example of a checked exception is IOException.

(vs. a runtime exception, with base class RuntimeException, that does not require “throws...” for methods that generate it. An example is the very common NullPointerException; another is running out of memory.)

Patterns:

Need try/catch at top level, say in main, for getting Connection (which can throw) and closing it whether or not the database access “db-stuff” throws.  This means using a finally clause:

Note that conn.close() can throw, so need to put it in an inner finally to maintain control:

      
      try {
         conn = DriverManager.getConnection(connStr, user, password);
         try {
           do-db-stuff
         }
         finally {
            conn.close();
         }
      } catch (SQLException e) {
         // throw to report problem, or if in main, can exit in error
      }
      

 In JdbcCheckup, we see a variant of this pattern at the end of main.

Suppose we wanted to do significant “db stuff”. Then we would definitely want to put the “db stuff” in its own method, as we see in JdbcCheckup.  There we see another pattern:

Statement stmt = conn.createStatement();

try {
    <Db actions>
} finally {
  stmt.close();  // best to close a Statement, tho not as crucial as closing a Connection
}

Note how there is no catch here. That means the SQLException generated by the DB actions is thrown from the method, so we must say so in the method header:

static void tryWelcomeExperiment(Connection conn) throws SQLException { …}

Don’t “squelch” an exception, that is, have a catch clause which doesn’t do anything.  That’s a “code smell”, sign of a bug. See Wikipedia Code_smell for other examples.

If an exception happens, notify the caller about the problem somehow!

In Java, problems are usually signaled by throwing an exception, but an old-fashioned error return value is still OK.

Rather than catching an exception and re-throwing it, consider just not catching it, as shown in the last snippet above.

Note: no “conn.commit” actions here in JdbcCheckup: the Connection is running in “auto-commit” mode—more on this later.

Next: XML

XML Basics, for ant build.xml

A message in XML: an XML document:

<?xml version=”1.0”?>               Official start of XML doc.
  <message>
    <to> you </you>
    <from> me </from>
    <subject> XML looks like this </subject>
</message>

However, only one message con be in a document, because XML allows only one root element, so for multiple messages, we need a container element:

    <?xml version=”1.0”?>         
    <messages>
       <message>
          <to> you </to>
          <from> me </from>
          <subject>XML looks like this </subject>
       </message>
       <message>
          <to> you </to>
          <from> me </from>
          <subject> XML again </subject>
       </message>
    </messages>

Attributes: name = “value” in start tag. 

We can only have one attribute of a given name in an element

We can have multiple child elements inside an element, like <point> here.

<message to=“you” from=“me”>
     <subject> XML Properties </subject>
     <point> self-describing </point>
     <point> standardized </point>
</message>

Comments, like HTML:

                <!--whatever -->

 Competitor: JSON

{"message": {
    "to": "you",
    "from": me",
    "subject": "JSON Properties",
    "points": [
       "self-describing",
       "standardized",
       "more compact than XML"
     ]
  }
}

 

Look at build.xml in XML and Ant Examples:

root element “project”: only one of these allowed by XML

child elements: name “target”: can have many of these, represent actions we want to do, come back to this in a few minutes

Note className=”oata.HelloWorld”. This long class name means there is a Java package named “oata” in use.

So the HelloWorld.java looks like this:

package oata;

…main(…) {

   System.out.println(“Hello World”);

}

Project Directory setup for projects with packages

And this java file is expected to be located in subdirectory oata of the src directory, itself the root of the “source tree”. The .class file for it is expected to be in the oata subdirectory of the class tree.

In general, we will have a base directory with build.xml, and below this, a source tree rooted at src, and a class tree rooted at build/classes or bin.  In this example build.xml, the class tree is rooted at build/classes.

This system prevents name conflicts between classes that are put together from various places.  Each software system “owns” a directory or a whole tree.  Important package names are based on the domain name system for uniqueness. We could put pizza1 in package edu.cs.umb.cs636.pizza...., but for simplicity, we'll use shorter package names.

This example is using the “oata” package, so there is an oata subdirectory for its source and .class files.

Base directory has subdirs src and build, and contains build.xml

src has subdir oata, containing HelloWorld.java

build has subdir classes

classes has subdir oata, containing HelloWorld.class

Resulting tree of directories:

            BaseDIR   <--build.xml is in here
            /          \
      src            build   
        /                   \
    oata         classes     
                             \
                             oata

Another common way: use “bin” instead of “build/classes”

Specifically, looking from the base directory: relative paths

src/oata/HelloWorld.java:  HelloWorld.java is in oata subdirectory of src

build/classes/oata/HelloWorld.class: HelloWold.class is in oata subdirectory of build/classes

i.e., in short, looking from the base dir:

src: top of sources tree

build/classes: top of .class file tree


Ant example 1: project with sources in oata package, stored under src directory, classes under build/classes. Ant runs executables “from the base directory”, i.e., with the current directory being the base directory, where the build.xml is.

“ant clean”: clean up project

“ant compile”: compile all java files

“ant run”

In each target, an Ant “task”, here delete, mkdir, javac, java

Each of these is a wrapper around a well-known program, or platform-dependent programs:

delete executes rmdir /s on Windows, rm -r on UNIX/Linux: so ant’s delete is platform-independent!

<javac> and <java>: wrappers for javac and java, make them easier to use in multi-package apps

 Using the command line tools in this situation: Not covered in class, but shows what ant tasks actually do under the covers.

Important javac and java command options:

-classpath (or –cp for short): says where to find .class files (for javac and java)

-sourcepath: says where to find .java files, so javac can compile them for dependencies (for javac)

-d: says where to put output .class files (for javac)

General Syntax with these options:

javac –cp <classpath> -sourcepath <sourcepath> -d <top directory for .class files> <filespec of .java file>

java –cp <classpath> <long name of class with main, including package name(s)>

For javac and java, the default classpath (and for javac, the default sourcepath and –d target) is the current directory. We can use this fact as follows to save typing on the command line:

cd src for compile, to set classpath and sourcepath at top of sources, avoid need for -sourcepath in javac command:

javac –d ../build/classes oata/HelloWorld.java   (while cd’d to src directory: compiles helpers too)

We can "cd build/classes" to set classpath at top of .class file tree, and avoid the need for –classpath in the java command

java oata.HelloWorld   (while cd’d to build/classes)


Do everything from the base directory, and set sourcepath and classpath as needed in commands:

javac –sourcepath src –d build/classes src/oata/HelloWorld.java          

java –cp build/classes oata.HelloWorld

Note: Here we are considering the case where no libraries are needed aside from the JDK. We need to use our driver jar files, so we need to work with the classpath too.

End of material not covered in class

Compare the above commands with using build.xml--using build.xml is much easier!