Using Open Source in Java Projects
Using Open Source in Java Projects
Projects
<path id=“second_classpath”>
<fileset dir=“${lib.dir}”>
<include name=“**/*.jar”/>
<exclude name=“junit.jar”/>
</fileset>
</path>
Running ant
Command line:
ant target
Used if your build file is named build.xml
in the current directory
ant –buildfile filename target
Used if your build file isn’t named
build.xml or in a different directory
Run from within a supporting IDE
Example Program Directory
Structure
(root)
javadoc
WEB-INF
lib classes
Example ant script – init
target
<target name="init">
<property file="../build.compile.ant.properties"/>
<property name="webapp" value="ldap"/>
<property name="classes" value="${webapp}/WEB-INF/classes"/>
<property name="lib" value="${webapp}/WEB-INF/lib"/>
<property name="src" value="src"/>
<property name="test" value="test"/>
<property name="testclasses" value="testclasses"/>
<property name="properties" value="properties"/>
<property name="dist" value="dist"/>
…
Example ant script – init
target
…
<!--- Path to compile the application -->
<path id="compile.classpath">
<!-- Include all elements that Tomcat exposes to
applications -->
<pathelement location="${catalina.home}/common/classes"/>
<fileset dir="${catalina.home}/common/lib">
<include name="*.jar"/>
</fileset>
<pathelement location="${testclasses}"/>
<pathelement location="${classes}"/>
</path>
</target>
Example ant script – compile
target
<target name="compile" depends="init" description="Compile">
<mkdir dir="${classes}"/>
<javac debug="true" deprecation="true“
destdir="${classes}" srcdir="${src}">
<classpath refid="compile.classpath"/>
</javac>
</target>
Example ant script -
testcompile
<target name="testcompile" depends="compile“
description="Compile Tests">
<mkdir dir="${testclasses}"/>
<javac debug="true" deprecation="true“
destdir="${testclasses}" srcdir="${test}">
<classpath refid="test.classpath"/>
</javac>
</target>
Example ant script -
javadoc
<target name="javadoc" depends="init" description="Javadoc">
<mkdir dir="apidoc"/>
<javadoc destdir="apidoc" packagenames="edu.*">
<sourcepath>
<pathelement location="${src}"/>
</sourcepath>
<classpath refid="compile.classpath"/>
</javadoc>
</target>
Example ant script - dist
<target name="dist" depends="init,compile“
description="Build Distribution File">
<mkdir dir="${dist}"/>
<jar jarfile="${dist}/ldap.war" basedir="${webapp}">
<exclude name="WEB-INF/lib/junit.jar"/>
</jar>
</target>
Example ant script - all
<target name="all" depends="init,dist" description="Build everything.">
<echo message="Application built"/>
</target>
Example ant script - test
<target name="test" depends="init,compile,testcompile“
description="Junit tests">
<java fork="yes" classname="junit.textui.TestRunner“
taskname="junit" failonerror="true">
<arg value="edu.iu.uis.sit.ldapsearch.test.AllTests"/>
<classpath refid="test.classpath" />
</java>
</target>
Example ant script - clean
<target name="clean" depends="init"
description="Clean all build products">
<delete dir="${classes}"/>
<delete file="${dist}/ldap.war"/>
<delete dir="apidoc"/>
<delete dir="${dist}"/>
<delete dir="${testclasses}"/>
</target>
Ant Summary
Allows developers to build the
application consistently no matter
what environment, operating
system
jRelational Framework (jrf)
Open Source Framework
Object/Database mapping
Framework
Automates most of SQL
programming
Tables look like objects to
programmers
jrf Provides
Object-to-relational mapping for:
Sequenced primary keys
Natural primary keys
Compound primary keys
Insertion of a new object instance into the database.
Updating of existing object instances.
Deleting of existing object instances.
Finding of persistent instances by primary key.
Finding all persistent instances. (Finding all rows in a
table).
Finding of a portion of persistent instances that match
an application-specific criteria.
Augmentation of persistent object instances with
columns from other tables (Joining of tables).
jrf Provides
Aggregation - creation of multiple objects from one
result set.
Flexibility to define custom SQL queries for specialized
searches.
Database independent validation of objects based on
the metadata defined in the AbstractDomain subclass.
(i.e. REQUIRED and UNIQUE field constraints).
Database independent defaulting of attribute values
when updating and selecting from the database.
Optimistic locking of an object/row using a Timestamp
or Integer column. When conflicts occur, an
ObjectHasChanged exception is thrown by the
framework.
Linking of related objects at retrieval time through the
jrf Provides
Plenty of "hooks" by which you can customize
your object before saving, after saving, after
finding, etc...
Compatible with database triggers that change
the tables.
Generation of basic PersistentObject and
AbstractDomain subclasses from an existing
database (using the jrf-extras jar).
Connection pooling (Either via the included
JDBCHelperPool or via your application server
pooling).
Object Mapping
Each RDBMS table is mapped to
two objects
Persistent Object (or Entity Object)
which represents one row
Domain Object which represents the
entire table
Entity Object
Is a JavaBean
Has a property for every column in a
table
The setter method must contain a call
to this.markModifiedPersistentState();
Each property MUST be a Java Object,
not a built in java type
Parent object is
com.is.jrf.PersistentObject
Domain Object
Represents an entire table
Has a method to return lists of all rows
Has a method to return a single row via the
primary key
Has a method to return a list of rows based on
a specified where clause
Has method to add, update or delete single
row
Parent object is com.is.jrf.AbstractDomain
A Domain object can have “hooks” for various
events in the object lifecycle
JDBCHelper
JDBCHelper is the jrf class to wrap
a JDBC driver
You’ll need to work with
JDBCHelper any time you talk to
the database
JDBCHelpers will also let you
manage database transactions
Creating a Domain Object
Create a subclass of
com.is.jrf.AbstractDomain
Implement a protected void
setup() method which should
set the DatabasePolicy
set the table name
Add Column specs for each column
Creating a Domain Object
Override the newPersistentObject
method and return a new instance
of your entity object
Column Specs
Each column in the table needs to
be defined in the setup method of
the Domain object
There are ColumnSpec objects for
many different data types:
StringColumnSpec
IntegerColumnSpec
LongColumnSpec
Column Specs
The constructor for a xColumnSpec
object needs the following
parameters:
column name
getter method name
setter method name
default value
zero or more options
Column Specs – default
value
Default Value constants
DEFAULT_TO_NULL
DEFAULT_TO_EMPTY_STRING
DEFAULT_TO_ZERO (Integer only)
DEFAULT_TO_ONE (Integer only)
DEFAULT_TO_NOW
DEFAULT_TO_TRUE
DEFAULT_TO_FALSE
Column Specs - options
Option constants
SEQUENCED_PRIMARY_KEY
NATURAL_PRIMARY_KEY
OPTIMISTIC_LOCK
REQUIRED
UNIQUE
Max of 3 options
Primary key options shouldn’t be used
with other options (Required & Unique
assumed)
Column Specs
The Domain object has a method
called addColumnSpec that lets
you add each Column Spec object
this.addColumnSpec(new
StringColumnSpec(“user_nm”,
”getUser_nm”,”setUser_nm”,
DEFAULT_TO_EMPTY_STRING,REQUIRED)
Finders
Finders allow you to retrieve lists
of rows that meet certain
requirements
jrf supplies a finder by primary
key, a finder for all rows, and one
for a where clause
You’ll need to write additional ones
Finder methods belong in the
Domain object
Finders
Example Finders
findByUserNm(String user_nm)
findByID(Integer id)
findByAccount(String fin_coa_cd,
String account_nbr)
findNamesStartingWith(String s)
Finders
jrf provides a findWhere method
Example findByUserNm method
Transactions );
balance_amt numeric(8) not null
checkingAccount.setBalance_amt(checkingAccount.getBalance_amt()
try {
Account nAccount1 = aDomain.save(checkingAccount,jdbcHelper);
}…
savingAccount.setBalance_amt(savingAccount.getBalance_amt()+10)
try {
Account nAccount2 = aDomain.save(savingAccount,jdbcHelper);
}…
jdbcHelper.close();
jrf Transactions
Example code WITH transactions:
JDBCHelper jdbcHelper = getJDBCHelper();
jdbcHelper.beginTransaction();
checkingAccount.setBalance_amt(checkingAccount.getBalance_amt(
try {
Account nAccount1 = aDomain.save(checkingAccount,jdbcHelper);
}…
savingAccount.setBalance_amt(savingAccount.getBalance_amt()+10
try {
Account nAccount2 = aDomain.save(savingAccount,jdbcHelper);
}…
jdbcHelper.endTransaction();
jdbcHelper.close();
jrf Transactions
Oracle (and most other RDBMS’s)
by default will “hide” any changes
made within a transaction until the
transaction is finished
Other database connections won’t
see these changes during the
transaction
jRF 2.0 Beta
jRF 2.0 Beta is out
It is not 100% backwards
compatible with 1.7
Check http://jrf.sourceforge.net for
more information
jRF Summary
jRF is a good lightweight
framework for mapping objects to
tables
jUnit
Unit Tests are a series of tests that
verify each component of your
application
jUnit is a framework to help
standardize these tests
jUnit can help automate tests so it
is easy to see if a component
works
jUnit can be integrated into ant
Why Unit Test?
Find bugs soon after code is
written
Save other team members’ time
Prove that finished code works
Make future maintenance easier
Example of how to use code
Unit testing goals
Each class has tests for all public
methods
Tests not only test successes, but also
test failures
Tests are organized so they are easy to
run
Tests are run often
Each test is completely independent of
other tests
Each time a bug is found, write an
additional test to check for that bug,
jUnit Concepts
TestCase – a series of related tests
All the tests for an object
All the tests for a method
TestSuite – a series of related test
cases
All tests for a package
All tests for an application
jUnit Concepts
Fixtures – routines that setup the
environment for each test
Create database connections
Initialize the environment
TestRunner – jUnit code that runs
tests
Command line
Swing
jUnit Addons
Dbunit – code to initialize a database to
a known state before testing
Struts test case – Test Struts specific
code using mock objects
Cactus – Test HTTP applications using
mock objects
HttpUnit – Test HTTP applications based
on an embedded servlet container
Writing jUnit tests
1. Subclass
junit.framework.TestCase
2. Create a constructor with a single
String parameter. Call
super(string) in this constructor
3. Write tests in methods that return
void and start with test as their
name
4. Call fail, assertX in tests as
Test success/failure
assertX methods test for the
correct values. Examples:
assertTrue/assertFalse
assertNull/assertNotNull
assertEquals
Fail method stops the test and
marks it as a failure
Test success/failure
The assertX and fail methods will
take an optional string to describe
the test
I recommend you ALWAYS use this
string to document the tests
Example test
/**
* Test searching for someone that doesn't exist
**/
public void testGetPerson1() {
try {
BusinessLogicInt bli =
BusinessLogicFactory.getInstance(getImplementationClass());
Person p = bli.getPerson("Unknown");
assertNull("Unknown person should be null",p);
} catch (Exception e) {
fail(e.getMessage());
}
}
jUnit Example
Look at example program
jUnit Summary
jUnit helps you create higher
quality software
Time spent by writing tests will be
recovered many times over during
future maintenance
What is Struts?
Open Source Framework
User Interface Framework based on
Model-View-Controller model (MVC or
Model 2)
Part of the Jakarta project sponsored by
the Apache Group
We will talk about Struts 1.0.2. 1.1b2
has been released with many new
features
Why use Struts
Consistency across applications
Split up HTML from Java code
Make Maintenance of applications
easier
Take advantage of code in the
framework
What is Struts?
Struts Components
Struts Servlet
Action Object (Controller)
Form Object (Model)
JSP Page (View)
Tag Libraries
Configuration File
Application Resources
Struts Servlet
“Traffic Cop” for application
Routes requests to appropriate
object
Configuration comes from
configuration file (struts-
config.xml)
Action Object (Controller)
Action objects handle every
request
Each request type should have an
action object
These are NOT Servlets
They are called by the Struts
Servlet
Form Object (Model)
Form objects store state
information
Data can be passed from action
objects (controllers) to JSP’s
(views) and back
Form objects are JavaBeans
JSP Page (View)
JSP Pages contain all the HTML
They use Form objects to display
data
HTML Forms put their data into
Form objects
Tag Libraries contain lots of
functionality you can use
Tag Libraries
Struts comes with many tags
These tags allow you to
manipulate form beans
provide i18n
have conditional parts of page
iterate through lists of data
You can add your own tag libraries also
Look at the JSTL – Java Standard Tag
Library
Configuration File
Allows the developer to define the
flow of an application declaratively
instead of in the code
The flow of an application can be
changed without recompiling code
Application Resources
An application resources file can contain
all of the messages that appear in your
application
This file can be translated into other
languages to provide i18n support
Helps in writing documentation and
making messages consistent
This file goes where your Java source
code goes – it goes in a package
Application Resources
Variable
Sample File:
application.title=My Application
group.error=The group {0} is invalid
error.username.missing=You must type in a username
error.password.missing=You must type in a password
username.message=Username:
password.message=Password:
submit.button.message=Save
Tag Libraries
struts-bean – Define new beans,
render beans/properties
struts-html – Create forms
struts-logic – Conditional page
generation, looping
Using Struts Tag Libraries
Insert these lines at the beginning of each .JSP that
will use these tag libraries
<bean:message key=“application.name”/>
struts-bean <bean:write>
Print out a bean or bean property
<html:errors property=“username”/>
struts-html <html:form>
Start an HTML form where all input
is sent to a Form object
Uses JavaScript to set focus to first
field (optional)
POSTS or GETS to an action in
struts-config.xml
option
options
All of these are just like their HTML counterparts
with a property attribute that work with a FormBean
struts-html <html:link>
Create <a href> and handle url re-
writing
Use to provide links to locations
within your application
<html:link page=“/editVendor.do”>
<bean:message key=“vendor.edit”/>
</html:link>
struts-logic
Contains tags that
Compare values
Iterate
Conditionally include parts of pages
struts-logic - Comparison
equal, notEqual
greaterEqual, lessEqual
greaterThan, lessThan
Compare a value to a cookie,
header, property or name
errors
scope –area to be used for form bean
(“request” or “session”)
validate – true/false – Validate form
bean
Bold - Required
Action Forwards
A forward is a logical definition of a
path
<forward name="success“ path="index.jsp"/>
• name = logical name
• path = path to go to
return (mapping.findForward(“success"));
Action Forwards
Example – Wizard Interface
If user presses Previous button, go to
previous screen
If user presses Next button, go to
next screen
<form-bean name="PersonForm"
type="edu.iu.uis.html1.PersonForm"/>
Global Forwards
Forwards that are used throughout
your application
Example: main menu
<global-forwards>
<forward name="logoff" path="/logoff.do" />
<forward name="logon" path="/logon.jsp" />
<forward name=“menu" path="/mainMenu.jsp" />
</global-forwards>
return (servlet.findForward(“menu"));
Before Calling the Action
Object
The Struts Servlet will:
Check in the user’s session for an
instance of a form bean listed in
struts-config.xml
If it doesn’t exist, create one
Call the setter for each property that
matches a form input field
Pass the form bean to the perform
method
Action Objects
Receives requests from client
Runs appropriate business logic
forwards to view (JSP) for display
Application Architecture
struts-config.xml
BL Controllers
Struts
Browser Action Object
Servlet Entities
JSP
Action
Domain
Form Boundary Controller Entity
JSP
Struts 1.1 beta
New Features
Multiple struts-config.xml files
Dynamic beans
Declarative exception handling
Validation framework
Tiles framework
Struts Summary
Struts will save time as an
application gets complex
Struts will save time in
maintenance
Summary
By 2003, the use of open-source
software will become a standard
part of all organizations utilizing
Java…
- Thomas Murphy
METAgroup.com
Books
Resources
Ant – http://jakarta.apache.org/ant
Jrf – http://jrf.sourceforge.net/
jUnit – http://www.junit.org/
Struts –
http://jakarta.apache.org/struts
Other Resources
Tomcat – http://jakarta.apache.org/tomcat
Hsql – http://sourceforge.net/projects/hsqldb/
Log4j – http://jakarta.apache.org/log4j
NetBeans – http://www.netbeans.org/
Dbunit – http://dbunit.sourceforge.net/
Struts test case –
http://strutstestcase.sourceforge.net/
HTTP Unit – http://httpunit.sourceforge.net/
Cactus – http://jakarta.apache.org/cactus
?
Q&A