Moving up to Java 1.5 and Tomcat 5.5

Download Report

Transcript Moving up to Java 1.5 and Tomcat 5.5

Moving up to Java 1.5 and
Tomcat 5.5
Java Hour – Sept 23, 2005
Infrastructure

<TOMCAT_HOME>/common/lib





ojdbc14.jar
commons-dbcp-1.2.1.jar
commons-pool-1.2.jar
commons-collections-3.1.jar
May want to copy your old cacerts file into
<JAVA_HOME>/jre/lib/security if you have
added any hosts to cacerts in the past
Add a new JRE in Eclipse
1.
2.
3.
4.
5.
6.
Window->Preferences...
Expand “Java”
Click “Installed JREs”
Click the Add button
Name it whatever you like, click the
Browse button and point it at your
<JAVA_HOME>
Click the OK button
Modify Tomcat 5 in Eclipse
1.
2.
3.
4.
5.
6.
7.
8.
Window->Preferences...
Expand “MyEclipse”
Expand “Application Servers”
Expand “Tomcat 5”
Enable it if not already enabled
Click the Browse button for “Tomcat Home
Directory” and select your <TOMCAT_HOME>
Click on “JDK” in the tree to the left under
Tomcat 5
Select your JRE for Java 1.5 that you created on
the previous slide
Application Changes

Recompile your code. It is possible that
you have used a keyword that is new to
Java 1.5

context.xml – the tomcat
developers/designers decided to change
from xml tags or elements to attributes
Old context.xml
<!DOCTYPE doc
[
<!ENTITY MYDB SYSTEM "file:/opt/sa_forms/java/dev/edu/iu/uis/security/my/MYDB.xml">
]
>
<Context path="/my-dev" reloadable="true" docBase="c:\java\projects\my\my">
<Resource name="jdbc/dev/my/MYDB" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/dev/my/MYDB">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>5</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.driver.OracleDriver</value>
</parameter>
&MYDB;
<parameter>
<name>validationQuery</name>
<value>select 1 from dual</value>
</parameter>
</ResourceParams>
</Context>
New context.xml
<!DOCTYPE doc
[
<!ENTITY MYDB SYSTEM
“file:/opt/sa_forms/java/dev/edu/iu/uis/security/my/MYDB.xml”>
]
>
<Context path=“/my-dev”
reloadable=“true”
docBase=“c:\java\projects\my\my”
>
&MYDB;
</Context>
Guts of the Include File (MYDB.xml)
<Resource name="jdbc/dev/my/MYDB"
auth="Container"
type="javax.sql.DataSource"
username=“xx"
password=“xxxxx"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin..."
maxActive="100"
maxIdle="5"
maxWait="10000"
validationQuery="select 1 from dual"/>
Timeline?

Discussion… questions?
Some Neat Things in Java
1.5
Quick Overview
Generics
 Enhanced for loop
 Autoboxing and auto-unboxing
 Typesafe enumerated types
 Variable arguments
 Static imports
 Metadata or annotations

Other noteworthy changes…


apt – annotation processing tool
Enhancements to core libraries







Networking (connect timeouts, ipv6, proxy server, etc)
Security (more standards, SASL, crypto, etc)
Formatter (printf, layout and alignment, support for
common types)
Scanner (parse input: scanner.nextInt(), can use regex)
Concurrency (powerful thread package – low level)
Monitoring and management (can monitor jvm and the
os from within your application)
More support for profiling – extended the API
Generics
Generics provides compile-time type
checking and eliminates the need for
casts. This serves to optimize collections
of older Java versions.
 No need to cast anymore… you know for
sure what is in the collection and the
compiler will help you – no runtime errors!
 Cleaner code!

Enhanced for loops

Enhanced for-loops make it easy to traverse
through collections while avoiding error-prone
iterators.
for ( Type x: collection ) {
x.doSomething();
}


No more Iterator!
Less code, more reliable, better performance
because the compiler knows best.
Example: Where’s the bug?
01:
02:
03:
04:
05:
06:
07:
08:
09:
List<Suit> suits = ...;
List<Rank> ranks = ...;
List<Card> sortedDeck = new ArrayList<Card>();
for (Iterator<Suit> s = suits.iterator(); s.hasNext();) {
for (Iterator<Rank> r = ranks.iterator(); r.hasNext(); ) {
sortedDeck.add(new Card(r.next(), s.next()));
}
}
Fixed the bug with new for loops
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
List<Suit> suits = ...;
List<Rank> ranks = ...;
List<Card> sortedDeck = new ArrayList<Card>();
// Fixed and pretty
for (Suit suit : suits) {
for (Rank rank : ranks) {
sortedDeck.add(new Card(rank, suit));
}
}
Final thoughts on the new loop

Can not be used when:



you want to remove an element from a
collection.
you want to modify an element while iterating.
you want to iterate multiple collections at the
same time.
Any other time, go for it!
 Note: can be used with arrays too.
 Example1.java – take a look in Eclipse

Autoboxing and Auto-unboxing
Autoboxing and Auto-unboxing reduce the
efforts previously required to cast
primitive types back and forth. The
compiler now does this for you.
 Before Java 1.5

Integer grade = new Integer(10);
int g = grade.intValue();

In Java 1.5
Integer grade = 10;
int g = grade;
Another example

Autoboxing
list.add(23); // list is List<Integer>

Auto-unboxing
int value = list.get(0);
Caveats
The wrappers are created behind the
scenes, so performance degradation is
possible.
 Use them to make your code more
readable: IMO, I would sacrifice a bit of
performance for maintainability.
 Don’t use them when:



you are inside of an large inner loop
items in a collection might be null
Typesafe enums
Typesafe enums provide a way to define
enumerated types that can be checked by
the compiler for type safety.
 Better than the C/C++ counterpart: they
are a class, not a glorified integer.
 Example:

enum Suit { CLUB, DIAMOND, HEART, SPADE };
01: public class ChessPiece {
02:
03:
public static final int TYPE_KING = 0;
04:
public static final int TYPE_QUEEN = 1;
05:
public static final int TYPE_ROOK = 2;
06:
public static final int TYPE_KNIGHT = 3;
07:
public static final int TYPE_BISHOP = 4;
08:
public static final int TYPE_PAWN = 5;
09:
10:
public static final int COLOR_WHITE = 0;
11:
public static final int COLOR_BLACK = 1;
12:
13:
private final int type;
14:
private final int color;
15:
16:
public ChessPiece(int type, int color) {
17:
this.type = type;
18:
this.color = color;
19:
}
20:
21:
public int getType() {
22:
return this.type;
23:
}
24:
public int getColor() {
25:
return this.color;
26:
}
27:
28:
public String toString() {
29:
String out = this.color == COLOR_WHITE? “white“:“black“;
30:
switch (this.type) {
31:
case TYPE_KING: return out + “ king”;
32:
case TYPE_QUEEN: return out + “ queen”;
33:
case TYPE_ROOK: return out + “ rook”;
34:
case TYPE_KNIGHT: return out + “ knight”;
35:
case TYPE_BISHOP: return out + “ bishop”;
36:
case TYPE_PAWN: return out + “ pawn”;
37:
default: return “invalid chess piece”;
37:
}
38:
}
39: }
Typical “enumerated
types” before Java 1.5
- used a bunch of ints
Can you think of any
problems with this
solution?
Problems
Not type safe: constructor takes ints…
nothing is enforcing a type and color.
 Can do things like:

int x = ChessPiece.COLOR_BLACK + ChessPiece.TYPE_QUEEN;
Printed values are uninformative: just ints.
 No easy way to enumerate/iterate. No
bounds.

A fix with typesafe enums
01: public class ChessPiece {
02:
03:
public static enum Type {KING,QUEEN,ROOK,KNIGHT,BISHOP,PAWN};
04:
05:
public static enum Color { WHITE, BLACK };
06:
07:
private final Type type;
08:
private final Color color;
09:
10:
public ChessPiece(Type type, Color color) {
11:
this.type = type;
12:
this.color = color;
13:
}
14:
15:
public Type getType() {
16:
return this.type;
17:
}
18:
19:
public Color getColor() {
20:
return this.color;
21:
}
22:
23:
public String toString() {
24:
return System.out.printf("%s %s\n", this.color, this.type);
25:
}
26: }
Benefits










Compile time safety
Loaded at run time – don’t have to recompile
client code.
Allows arbitrary fields and methods.
Can implement interfaces.
Can be iterated/used in collections.
Inherit from java.lang.Object
Implement Comparable and Serializable
Nice printed values
Performance is similar to using ints – no worries.
Can be used in switch statements, unlike other
objects.
01: public enum Planet {
02:
// Constants
03:
MERCURY (3.303e+23, 2.4397e6),
04:
VENUS (4.869e+24, 6.0518e6),
05:
EARTH (5.976e+24, 6.37814e6),
06:
MARS (6.421e+23, 3.3972e6),
07:
JUPITER (1.9e+27, 7.1492e7),
08:
SATURN (5.688e+26, 6.0268e7),
09:
URANUS (8.686e+25, 2.5559e7),
10:
NEPTUNE (1.024e+26, 2.4746e7),
11:
PLUTO (1.27e+22, 1.137e6);
12:
13:
// Fields
14:
private final double mass;
// in kilograms
15:
private final double radius; // in meters
16:
17:
// Constructor
Enums can be
18:
Planet(double mass, double radius) {
by giving them
19:
this.mass = mass;
20:
this.radius = radius;
methods!
21:
}
22:
23:
// Methods
24:
public double getMass() { return mass; }
25:
public double getRadius() { return radius; }
26:
public static final double G = 6.67300E-11;
27:
28:
public double getSurfaceGravity() {
29:
return G * mass / (radius * radius);
30:
}
31:
public double getSurfaceWeight(double otherMass) {
32:
return otherMass * getSurfaceGravity();
33:
}
34: }
more powerfull
their own
Using the Planet enum
01: public class Test {
02:
03:
public static void main(String[] args) {
04:
double earthWeight = Double.parseDouble(args[0]);
05:
double mass = earthWeight / EARTH.getSurfaceGravity();
06:
for (Planet p : Planet.values()) {
07:
System.out.printf("Your weight on %s is %f\n",
08:
p, p.getSurfaceWeight(mass));
09:
}
10:
}
11:
12: }
$ java Test
Your weight
Your weight
Your weight
Your weight
Your weight
Your weight
Your weight
Your weight
Your weight
175
on MERCURY is 66.107583
on VENUS is 158.374842
on EARTH is 175.000000
on MARS is 66.279007
on JUPITER is 442.847567
on SATURN is 186.552719
on URANUS is 158.397260
on NEPTUNE is 199.207413
on PLUTO is 11.703031
Variable arguments




Varargs allow a variable number of arguments to
be passed to a method, yet another borrowed
idea from C/C++.
A good example is the new printf method.
Can only be used as the last variable to a
method.
Basically, and array is created behind the scenes

Can even call .length to find how many arguments were
passed to the method call
Old School (the max method)

Here is a basic max method
int max(int a, int b) {
return a > b ? a : b;
}

For multiple arguments you would call it
as follows:
// works, but very hard to read
int m = max(a, max(b, max(c, d)));

Another solution: write overloaded
methods: ex: int max(int a, int b, int
c)
Using varargs
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
// return the int with the maximum value
int max(int... values) {
int max = Integer.MIN_VALUE;
for (int i : values) {
if (i > max) {
max = i;
}
}
return max;
}
int m2 = max(a, b);
int m3 = max(a, b, c);
int m4 = max(a, b, c, d);
// what if the values already come in an array?
int[] values = {1, 2, 3, 2, 3, 1};
int m = max(values);
Static imports


Static imports simplify the task of importing
constants and other static members in your code
like when you are importing packages.
Instead of:
double r = Math.cos(Math.PI * theta);

Import it and use it to make your code more
readable
import java.lang.Math.cos;
import java.lang.Math.PI;
// ...
double r = cos(PI * theta);
A common Anti-pattern
Some ways to get at constants have been
to stick them in Interfaces and implement
the interface, or just use that interface to
get to global constants.
 Interfaces are public APIs, and logic
(constants) really should not be in a public
API.
 Just not very clean, and now there is a
solution built into the language.

When vs. When Not?

It’s best not to overuse this neat new
feature. It can make your code harder to
read if you statically import too much.

Use it when you are accessing a contant a
lot, or when you feel the desire to write
one of those anit-patterns
Metadata or Annotations
Metadata or annotations provide a
standard way to annotate your code.
 Javadoc and xdoclet are examples
 Examples: @Override and EJB
 http://www.devx.com/Java/Article/27235

Questions?

Lots of information out
there on the web… just ask
Google.
Code used in demo…
package examples;
import java.util.ArrayList;
import java.util.List;
public class Example1 {
public static void main(String [] args) {
test1();
test2();
}
private static void test1() {
List<String> names = new ArrayList<String>();
names.add("Joe");
names.add("Beth");
names.add("Randy");
for (String name: names) {
System.out.printf("test1: My name is %s\n", name);
}
}
private static void test2() {
List names = new ArrayList();
names.add("Joe");
names.add("Beth");
names.add("Randy");
for (Object name: names) {
System.out.printf("test2: My name is %s\n", (String)name);
}
}
}