An Overview of the Java Servlet 2.4 and JavaServer Pages 1.3 Specifications
Concurrency Utilities: Present and Future
Conference Miscellany
Using the Java Data Objects Specification with the Enterprise JavaBeans Specification: Persistence Options for the Enterprise
End to End Printing for Enterprise and Desktop Applications
BOF - It's Time for WAR
BOF - A New Solution for Using Threads with the Java Foundation Classes ("JFC/Swing") API: The Synchronous Model
This session is in one of the largest rooms set up for the conference this year. The place
is packed. I remember a Servlets talk at the SD conference three years ago with about 45 people
in attendance. I generally don't like things that are liked by too many other people, so as more
and more people pour in it makes me uncomfortable.
Java Servlets got started in '96 and JSPs in June of '99. The speakers are from Sun and work
on the specifications for Servlets and JSPs. The specifications are pretty much determined by
the Java Community Process. The reference implementation is provided by Tomcat. So my question
is, "What do these people do all day?"
Nine minutes into the presentation and the current speaker is still on a boring introduction
to the Java Community Process. Here are the stages: the expert group discusses issues amongst
themselves, the expert group draft(s) stuff (the stage they're currently at now), then a
community draft, then a public draft, then a proposed final draft, an 18-year-old-and-older
militia draft, and then a final draft where everything and everyone is drafted, gold pens are
exchanged, everyone says their goodbyes and then flies back to Martha's Vineyard for the summer.
The speaker admits the past sixteen minutes of wasted time was a disclaimer.
The Servlet 2.3 spec had large API changes, listeners for spying on global web application
state events, filters, and some deprecation thrown in for good measure. Servlet-based
technologies now include JavaServer Pages, TEA Servlets, JAXM, JAX-RPC, Velocity, Struts,
JavaServer Faces, Turbine, Beautiful Report Language, XMLC framework, Barracuda, Enhydra
Application Framework, Cocoon 2.0, Slide, SIP Servlets and more. There's also a new Portlet
API coming out for building HTTP portals, TS-3458? (my dictation of the number my be wrong).
They are considering moving from DTDs to XML Schema for defining deployment descriptors.
It's an added benefit that XML Schema will likely be supported in JAXP 1.2. This will allow
the deployment descriptor to be modularized, specifically J2EE shared elements. It also
increases the level of validation like enumerated types, uniqueness enforcement, cross
reference checking, and parking stubs. Schemas also would let them create extensibility
points where other applications can inject their extra deployment information.
They're considering completing the listener model started with 2.3. This might include
request/response lifecycle events such as request started, request stopped, request changed,
and filter chain processing events. A "semantic cleanup" for defining the clear relationship
between the session state and the login state, creating a portable(?) logout method, and some
other junk that I didn't get typed up.
Send ideas to
servletapi-feedbak@eng.sun.com.
The session is now taken over by Eduardo and Mark who are the JSP spec-leads. JSPs got
started in June '99 (more repeated information). Custom actions in 1.1 were added in Dec '99.
1.2 shipped in Sept '01 and was meant to add some clean up but then they changed their minds
and added XML syntax to the mix.
The Java Standard Tag Library (JSTL / JR-052) 1.0 will go final before the JSP 1.3 spec.
A new expression language will be in JSTL and JSPs. The expression language is claimed to be
easier for page authors. The syntax is ${expression here} Here's an example:
<foo>${object.method}</foo>
Mark takes the stage and starts talking about actions in JSPs. The <%@ include ...%%gt;
directive doesn't allow for customization. The <jsp:include ...%gt; directive only allows strings to
be passed for customization. Custom actions will allow reusable JSP code to be repeated numerous
times.
Additional features considered for JSP 1.3 include adding debugging support through the
use of JSR-045. It would provide a mapping for page authors and tools between the JSP source
and the generated bytecode. (Sounds nice, but I didn't really understand this.) JSP 1.3 is in
expert draft and a public draft is coming soon. An "exploratory reference application" is being
worked on.
Send feedback to jsp-spec-comments@eng.sun.com.
Every conference has a day of content-free sessions and yesterday was certainly it. The
previous talk was half-decent, and I have high hopes for this one. One of the presenters is
Joshua Bloch, senior staff engineer at Sun and author of Effective Java. The other is a
professor from the State University of New York at Oswego, Doug Lea. Well, a fifty-percent
chance at a good talk is not too bad. The session is completely packed.
Oh no!!! A bait-and-switch! Doug is going to do the talk. He wrote all the slides. He and
Bloch were supposed to get together earlier and split up the talk. That didn't happen.
Doug is going to talk about some concurrency libraries he's written that will be modified
some and incorporated in the future release of Java. He skipped the "mandatory-wasted-time"
outline of the presentation! Cool! JAS-166 will specify the concurrency libraries (aiming for
release 1.5), java.util.concurrent. Doug admits he knows nothing about application development,
which is a great admission for a professor, but he enjoys working on concurrency algorithms.
A package is available now, edu.osego.cs.dl.util.concurrent from
http://gee.cs.oswego.edu. JSR-166 will be a little
different, having learned from 3+ years of API usage experience.
The Java platform provides a simple set of low-level primitives but these can be difficult,
error-prone, or inefficient to use. Three interfaces in the new APIs will support the most
common usages that often escape built-in constructs (another one will be added for 1.5).
Acquire and release synchronization (renamed to locks and conditions in 166), Channels
(renamed to Queue in 166), and an Executor.
interface Sync (Lock)
void acquire();
void release();
boolean attempt(long ms);
interface Channel (Queue)
void put(Object x);
Object take();
void offer(long ms, Object) (I think I mistyped this one.)
Object poll(…);
interface Executor
execute(Runnable runnable)
You need custom locks if you need to:
- Time out of a lock
- Skip an action if lock held by another thread
- Abort lock attempt if thread interrupted
- Lock in one method, unlock in another
- Use non-reentrant locks
- Use semaphore-style locks
These are not possible with synchronized blocks, but are with custom lock classes. If you
want to lock something in one method and unlock it in another method, you can't do it in Java
now.
You get flexibility at the price of more awkward syntax:
sync lock = new LockImplementation();
try
{
lock.acquire();
try
{
action();
}
finally
{
lock.release();
}
}
catch InterruptedException ie)
{
..
}
Mutexes are also included:
private final Mutex mutex = new Mutex();
...
mutex.acquie();
...
mutex.release();
Semaphores can be seen as permit holders. The semaphore just maintains the current
count. You create one with an initial number of permits. An acquire takes a permit. If
none are available then you wait. A release adds a permit back.
For a resource pool class you can declare a semaphore at the top like this:
final Semaphore available = new Semaphore( initialCountHere );
Then in your resource pool's getItem() you would call available.acquire() and in
returnItem() you would call available.release().
Executors allow you to customize how to run asynchronous tasks through pools,
lightweight execution frameworks, and/or special thread parameters or scheduling.
The Executor interface has one method, execute(Runnable runnable). It replaces new
Thread(runnable).start(); Standard implementations include PooledExecutor, ThreadedExecutor,
and QueuedExecutor.
Other classes included:
- ReadWriteLocks - Hold a pair of locks, one for read, one for write. Both have acquire, release, and attempt.
- Barriers - Multi-way synchronization points. A single method called barrier() when issued will cause all threads to sync up to the barrier.
- Rendezvous - Queue-like but with two-way data exchange
- Futures - Runnables returning results; callers wait to use.
- Collection implementations - Hash tables, lists, etc. designed to work well when used by many threads. These should have high-performance in truly parallel program. These are written to incredibly fast and useful. There' not just synchronized for safety.
Planned JSR-166 additions include atomic variables that support compareAndSwap(),
conditions, and enhancements to built-in functionality.
You can send comments to jsr-166-comments@jcp.org.
This was a cool talk and Mr. Professor was funny and interesting after all. For the University
of Arkansas alumni, he was a lot like Joe Wiggins.
JavaOne is well-known for the "JavaOne bag". This year it has been improved upon with the
addition of wheels and a pulley mechanism otherwise referred to as a "handle". It's been great
since instead of lugging around my laptop on my back I have been rolling it around the filthy
streets of San Francisco. It's also very useful for collecting pounds and pounds of propaganda
and freebies on the tradeshow floor and for generally looking like a nerdy dork pulling a Java
backpack around everywhere. It's become very addictive. Every conference from now on that
doesn't include a backpack with wheels on it will be a major disappointment.
The cell-phone pocket on the side of last year's bag has been dropped in favor of a water
bottle slot. Apparently, Nokia didn't put up quite enough money this year. A larger pocket
has been added on the other side, though, which has been performing a great job of holding
my laptop plug-in cord. Now if I could just find a plug-in!!! For attendees who need a lot
of personal assistance, the JavaOne pen doubles as a PDA stylus.
Speaking of PDAs the hottest thing this year has been the Sharp Zaurus PDA. It has a nice
color display, a cute itty-bitty keyboard than can be pulled out, and runs on a Linux kernel.
I heard reports of people waiting in line for 2-3 hours or more on Monday for these things.
They're all over the place. Tuesday they changed the purpose of the line so that those in line
waited to get an appointment to come back and buy it later. Things proceeded faster and Todd
bought one. I've heard reports that Brennan bought two. They sell for $200 and include a
wireless networking card. Sun has servers set up at the conference so you can download Java
and other applications to the PDA and trade applications. There's some sort of contest going
on for writing applications for it. Everywhere you look you see nerds squinting at the tiny
little screen and poking around on it.
Lunches at the conference this year have been rather disappointing but keep making
forward progress. On Monday it was a box-lunch only, quite poorly received by myself
since I expected the hot lunches of last year. I found out later that hot lunches will
be served the rest of the week. (Box lunches to go are always available for those who
would rather get back to their WSDL-CLDC-JAXR session than eat food.) Yesterday was chicken
teriyaki, a nice attempt but it failed. Today's hot lunch was warm fried chicken, cold potato
salad, and cold pasta. Everyone got about two pieces of chicken and I was fortunate enough to
get a piece with meat on it. I believe my second piece was an eyeball but I didn't inspect it
too closely.
The worst part of the lunches by far has been the "entertainment". Either there are no
longer any good cover bands in San Francisco or the conference organizers overlooked weeding
the crop down to those who can sing in tune. Knowing how to play an instrument would also be
nice.
I can't complain about the conference organizers too much though. The show is always quite
impressive. There are numerous banners hanging from the sides of buildings in the South of
Market area, most of them in the 25x40 foot range. There are nerdy advertisements on taxis,
buses, and portable billboards, trucks that do nothing all day but drive around in circles
pulling a billboard on wheels behind them. And many of the men's urinals have rubber Java
logos in the bottom of them. I doubt you'll find Bill Gates putting .Net logos in the bottom
of urinals.
The speaker, Craig Russell, used to be the spec lead for the Java Data Objects technology.
The spec is now spec'd and he's now the standard lead. JDO was released on Monday.
The talk starts with a boring overview of what persistence is and what persistence solutions
address. These include file I/O, serialization, JDBC, EJB container managed persistence (CMP),
and transparent persistence (JDO). I wish he would be more persistent at getting to the point.
He downplays JDB because in his view it's not portable due to SQL variants, it's a manual,
field by field storage of data, the data transformations are frequently hand coded, and there
is little reuse of code.
Twenty minutes into the talk and he finally gets to JDO. JDO is designed to be a simple
API with extended query support, complex domain object models including inheritance and an
optimized database read/update strategy. The JDO interfaces include PersistenceManager,
Query, and Transaction.
Here's a short list of the PersistenceManager Interface:
void makePersistent(Object o)
void deletePersistent(Object o)
Object getObjectById(Object oid)
Transacation currentTransaction()
Query newQuery(Extent extend, String filter)
JDO has object IDs that are durable and "persist throughout time". The PersistenceManager
is a transactional object. You can also run it without transactions if you want.
From within a Servlet, JDO code will look like this:
InitialContext ctx = new InitialContext();
PersistenceManagerFactory pmf = (PersistenceManagerFactory)
ctx.lookup("java:comp/env/jdo/PersonelPMF");
PersistenceManager pm = pmf.getPersistenceManager();
EmployeeKey empKey = new EmployeeKey(empId);
Employee emp = (Employee)pm.getObjectById(empKey);
String name = emp.getName();
Different objects and methods that ask for a PersistenceManagerFactory will get the same
instance if they are part of the same transaction context. JDO will create a dummy object and
hand it back to you. It will only retrieve the real object from the database when it's asked
for, in other words lazy loading.
I don't really see the point of JDO and doubt that it will ever take off to any considerable
degree. JDBC is plenty abstract for most people and writing DAOs by hand or generating them for
large applications is no big deal. It's true that if you really believe you're application may
need to write to a text file or a database or somewhere else, then yet another layer of
abstraction would be useful, but I don't see many people in that camp. Denny's pattern of
using reflection on the fly is the best database access mechanism I've seen so far.
For more propaganda you can go to http://JDOcentral.com.
This timeslot is great for those interested in Java Security. There are three different
talks on the subject. The downside is that all three of them are in the same timeslot.
Instead, I opted for a non-stop hour of excitement on Java printing. After all, the real
purpose of 80% of all software ever developed is to ultimately print little pieces of paper
to be thrown away latter.
J2SE 1.4 adds printer discovery and capabilities APIs, nice to know in case you lose your
printer. JDK 1.2 introduced java.awt.print.PrinterJob. It prints stuff as graphics and is a
low-level API. An application has to implement the print(…) callback method of the Printable
interface. You have to be able to turn any kind of print data into calls to the Java 2D
graphics API. Thus, printing anything other than little circles, squares, and lines using
the sample code provided gets rather involved and becomes an all-around pain in the ass.
The javax.print packages are new in 1.4. The PrintService interface is "the printer".
(Not to be confused with "that other printer over there".) Instances map to underlying
printers. (Overlyin printers are not supported.) You can ask it nicely for its DocFlavor.
DocFlavor is a mime-type plus a representation class name. The result generally depends on
the age and color of the paper in the printer. The next key interface is "Doc", not to be
confused with Doc Johnson, my high-school shop teacher. An application supplies print data
to a job as a Doc object. There are also a lot of printing attribute classes like DocAttribute
in case you're picky about the physical attributes of your documents and printers.
When you want to print something in Java, bring up an IDE and type in this code:
DocFlavor textFlavor = DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST;
PrintService[] services =
PrintServiceLookup.lookupPrintServices(textFlavor,null);
DocPrintJob job = services[0].createPrintJob();
Doc doc = new SimpleDoc(myText, textFlavor, null);
... (followed by more lines that look very similar to the above)
In the real world everything is eventually put into a JTable. How do you print a JTable
(correctly)? If you guessed "very carefully" you're correct. You start by creating your
own PrintTable class that implements Printable. You will have to calculate page breaks and
other fun stuff. A JTable's header is a distinct JComponent so that's an additional problem.
The speaker followed by going into the boring coding details of printing a JTable. This
is probably the most useful slideware presented at the conference so far. It's also about
to make me go to sleep, so I'm not going to attempt to type it in.
After you have the boring JTable code you can shove it into a TablePrinter class to create
a PrintService directly. The class can take a JTable as an argument.
I didn't think Java printing would be more boring that Java security. I was wrong.
1.4 added several enhancements which benefit server printing. You no longer need end-user
manipulation of printer dialogs to find printers and set settings. The output of printing can
be re-directed to a file, a URL, etc. It prints to a URI (pronounced "you or I").
If you're trying to print from a Java applet, you can install a custom print service directly
into the client VM (you may need permissions) and print directly to the user's local printer.
1.4.1 will include a few high priority bug fixes for printing. 1.5 will include more bug
fixes. And a small number of APIs will be added so that they don't run out of bugs to fix
in the next maintenance release.
JFC/Swing RFE 4627240 is for adding print support to JTable.
The Java Print Service API Guide: http://java.sun.com/j2se/1.4/docs/guide/jps
WAR files (Web Application Archives) were specified in the Java Servlet API 2.2 specification.
They're the packaging and deployment mechanism for web applications. WAR files are JAR files. JAR
files are ZIP files. A WAR file has a web root where some JSPs and HTML files can live. Under
that is a "Content" directory and a "WEB-INF" directory. Web.xml is required to be in WEB-INF.
Under "Content" are "classes", "lib", and "tlds" directories.
The web.xml file is the web application descriptor. The root element for web.xml is .
Then blocks appear within that. The and params are
required and is often useful. The param is used for servlet
mapping. Supply GPS coordinates for where you're Servlets are located.
The speaker continued with a monotone walkthrough of creating and using WAR files using
JBuilder. Then he covered creating WAR files from ANT using this built-in ANT task:
(other stuff within this tag that I missed)
His ANT script includes an action to deploy as a WAR as well as an option to deploy in
exploded format so you can deploy and look at things.
During a Q&A "battle" the speaker mentioned having a separate WAR file for different devl,
test, and uate type of environments, each specifying different database connection information,
etc. This didn't go over too well (because it's a stupid solution). One of the audience members
mentioned a good solution of using the ANT script to insert the appropriate information into the
WAR file as it's being deployed. This can be done using some type of replacement parameters.
Common problems with WAR files:
- Inappropriate capitalization on WEB-INF. It must be ALL CAPITALS.
- Loading an absolute file location from a .war file.
JSR-88 is not final but it is a proposal for J2EE Application Deployment.
The speaker started covering objectives for the Sun Web Certified Developer exam
(exam name may not be exactly correct). Here are some sample questions:
For a Web application, what is the proper file name of the web Application deployment
descriptor?
Ans. web.xml (from a multiple-choice list)
Given the exhibit choices, select the appropriate entry that specifies the name of the
class deployment descriptor tag for a Servlet with class name HarryPotter as it would appear
in the file web.xml.
Ans. <servlet-class>HarryPotter</servlet-class> (from a multiple-choice list)
Given the answer choices in the exhibit, which is a valid child element of the <web-app>
element within the Web application deployment descriptor?
Ans. <error-page>
Truly new solutions for anything in this business are extraordinarily rare. So anyone
putting "new solution" in the title of a JavaOne talk deserves a shot at being listened
to (at least the first time).
The AWT event model is based on the AWT Event Queue and the AWT Event Thread. The job
of the AWT Event Thread is to dequeue one event from the AWT Event Queue and process the
event. This means that until the processing of an event finishes, no other events may be
dequeued from the AWT Event Queue. Another event posted from an event listener is not
dequeued and is not dispatched until the listener itself returns.
The Swing threading model was by design single threaded and by design NOT thread safe
in order to be fast. Most applications need to be simple and fast.
Here is some sample Swing code for a form with only one button on it:
Inside of the button press listener:
button.setText("Sleeping…");
heavyOperatoin();
button.setText("Awake again…");
After you hit the button, you don't see the caption changed until heavyOperation()
completes. If you drag another window over your form while heavyOperation() is executing,
your form will not repaint.
Asynchronous solutions are based on a worker thread that executes heavyOperatoin(). You
can do this with SwingUtilities.invokeLater(). This is simple but you have uncontrolled
thread creation and difficult exception handling.
There are subtleties with invokeLater though. Be careful with concurrent access to Swing
models. A solution pattern for this is to collect new data in a new data holder inside
heavyOperatioin() and replace the old data with the new data from inside a
SwingUtilities.invokeLater().
The speaker then covered some other very interesting examples of problems with
invokeLater() solutions but they were too long and complex for me dictate here.
A SwingWorker was created to solve the problems discussed; but instead, it still has
many of the same problems. I think the implementation of SwingWorker is on Sun's site.
A common problem is a user action, followed by some initialization that requires a heavy
operation, followed by user input needed after initialization, and then another heavy
operation is performed. Imagine if the user action is a menu selection is to bring up a
dialog. After the dialog goes away and the second heavy operation is performed, the app
will freeze up for a few seconds and not repaint. SwingWorker can be used to fix this problem.
Now towards a new solution. His framework is called Foxtrot. The Foxtrot API is quite
simple but the usage examples are too complex to dictate here. It solves pretty much all
of the problems introduced with the other solutions.
The API is free. Check it out at
http://foxtrot.sourceforge.net
A cool appendix example to his talk shows his Task interface and Worker class can be
implemented using generics with JSR-014.
This was the most useful presentation I've been to so far. I didn't get all the material
covered very well here because it involves some fairly complex multi-threading examples, but
I encourage everyone interested in Swing to check out the Foxtrot API.
[ Previous ]
[ Index ]
[ Next ]