Sunday May 31, 2009

Platform Services Available in V3

Platform Services have just been rolled out for the first 2 platforms:

  • Solaris  Management Facility (SMF)
  • Windows

In the simplest case where you have one default domain and you want to run it as a service you run this command:

asadmin create-service

Here are all of the options:

[--passwordfile password-file] [--name service-name] [--serviceproperties (name=value)+] [--dry-run=false] [--domaindir domain_parent_directory] [domain_name]

 Once you have created the service it can be controlled in various ways by operating system and native tools. 


We use Windows Service Wrapper as the tool for installing the service.  It can be used to start stop and uninstall the service.  It can be found in the bin subdirectory of the domain directory.  In the default case the name of the executable will be domain1Service.exe  The directory also contains the configuration file, domain1Service.xml.  Below are the available commands:

  • domain1Service start
  • domain1Service stop
  • domain1Service uninstall
  • domain1Service install
You can also manage the GlassFish service with Windows tools:  Services snap-in and the net command line program.

Solaris  Management Facility (SMF)

You create the service exactly the same as WIndows.  One big difference for most users is that on Windows most users have administration privileges.  I.e. everyone is super-user.  Not so on Solaris.  In order to create a service you must have SMF privileges.  How to set that up is beyond the scope of this blog, but root definitely has these privileges by default 

 Important: If root creates a service then only root can start that domain from then on.  The best way to set this up is to install and/or create the domain as root and then create the service as root.

Once you have created the service you need to start it yourself.  Here are the most typical Solaris commands of interest:

  • /usr/bin/svcs  -a | grep domain1  // status
  • /usr/sbin/svcadm enable domain1 // start
  • /usr/sbin/svcadm disable domain1 // stop
  • /usr/sbin/svccfg delete domain1 // uninstall

Future Directions

If there is interest, demand and time we will add support for controlling the service from CLI:

  • start
  • stop
  • uninstall
  • restart

Sunday Apr 26, 2009

GlassFish V3 Remote Restart Now Available

GlassFish V3 is now sporting a brand new capability:  Remote Restart.

This feature is particularly handy for environments where the server machine is secured and difficult to get to.  With the right credentials you can now restart the server from anywhere in the world -- as well as from the same machine. 

It is very easy to use.  As of today there are two ways to call the restart-domain command with the third method coming online soon

(1) Use a URL in a browser: 


(2) Use asadmin like so:
   asadmin --host yourhost restart-domain

(3) Coming soon:  Admin Console GUI support for the command

The asadmin command, restart-domain, is what I like to call a "hybrid" command.  It is both a local and a remote command.  The local portion of the command's job is to block until it verifies that the server has completed its restart and is online and ready to go.  The remote portion does the actual restarting.


There are 3 main flavors of starting non-embedded V3.  Restart-domain works with all three:

  • Starting the server with the launcher (i.e. asadmin start-domain).  Restarting will stop the running server and once the JVM process is guaranteed to have exited the server will restart.  There are no special "watchdog" processes involved.  The server itself does the work itself in what I like to call "reincarnation".  This is easy to see by running jps during the restart.  You will see the process id change.  You can also watch the server log as the server restarts.
  • Starting the server with the launcher in verbose mode (i.e. asadmin start-domain --verbose).  The key point here is that we have to preserve the console that asadmin owns here.  So we do the restart a little differently.  Since the asadmin process is also running  on the server machine, we ask the already running asadmin process to restart the server for us.  asadmin does all the heavy lifting here.
  • Starting the server in implanted mode (e.g. java -jar glassfish.jar).  A new jvm will be started with exactly the same commandline arguments.  Note that if the server owns the console -- i.e. is running "in the foreground" and mirroring log messages -- the new server will lose control of the console.  We can not absolutely guarantee a clean shutdown without literally closing down the JVM itself.  Once that is done the console is out of reach.

Give it a try!

Friday Feb 27, 2009

How to Run Asadmin Commands in Embedded GlassFish

You can leverage your experience and knowledge about the GlassFish command line tool,  asadmin, with Embedded GlassFish servers.

Here is a use case:

You want an  Embedded GlassFish server that uses a JavaDB database.  You need to setup a few things in the server configuration.  You can do this configuration in your code every time you start using the CommandExecutor.  Another possibility is to do the following:

  1. start the Embedded GlassFish server -- making sure autodelete is off
  2. Run asadmin commands for configurationmbedded GlassFish server
  3. Stop the Embedded GlassFish server
  4. Always set the install-root to the root of the generated file system from steps 1,2.

Here is how to run asadmin in Embedded GlassFish (embedded.jar is the Embedded GlassFish all-in-one jar file that you have downloaded or built)


java -cp final.jar com.sun.enterprise.admin.cli.AsadminMain %\*


java -cp final.jar com.sun.enterprise.admin.cli.AsadminMain $\*

Monday Feb 02, 2009

Simple Embedded GlassFish App using Maven

Today's blog demonstrates how to create a very simple GFE (GlassFish Embedded) application.  The application requires no manual downloads.  GlassFish need not be installed and no GlassFish files of any kind need to be present.

The application uses a very simple web app named, appropriately, simple.war.  The simple.war file has been checked into Subversion for this project.  This breaks the usual rules of checking in only source code.  But I wanted to make this application as simple as possible for you to use.  You could replace simple.war with your own not-so-simple web app by renaming it to simple.war and overwriting the original.

Here is how to checkout and build the sample project:

  • svn co
  • cd SimpleMaven
  • mvn

You can run the GFE application by executing\*NIX) or r.bat(Windows).  If you are on \*NIX don't forget to make executable (chmod +x

What Does this Sample GFE Do?

  1. Create a GFE server
  2. Create a HTTP listener at port 7777
  3. Start the GFE server
  4. Deploy simple.war to the GFE server
  5. Send a request to simple at port 7777 and print the results
  6. Wait for user to kill the server (\^C) 


  • Maven downloads the GFE jar to your local repository
  • The Maven  Dependency plugin is used to copy the GFE jar from your local repository to the target directory.  Why?  So the run script will work in all scenarios -- since I don't know where your local repository lives.  It isn't strictly necessary,  you could point the classpath to the location of the file in your local repository.
  • The pom.xml for this project is as simple as possible.  The copying over of the GFE jar is the messiest part of the pom.xml.  Take a moment to examine pom.xml
  • There is one java file for this project.  Take a look at it.  Change the port from 7777 to 12345 or your favorite port number.  Have it deploy 2 or 3 more web apps.  Play around with it.

Next Steps

It would be nice if we didn't have to use the run scripts.   It would be nice to have Maven run the app.  In the next installment in this series I will show you just how to do that with the GFE plugin!

Thursday Jun 12, 2008

Tip #-2 Never lock on a Class

I just learned a lesson today the usual way.  I.e. the hard way!  

Conclusion -- never do this:

synchronized(getClass()) { ..... }


The intent is obviously to serialize the block against ALL instances.  About the only requirement is that the object be unique and global.

Oops!  The object is not unique!  What if the method is called from a derived class?  Then the lock object is totally different.  That is what happened to me.

This is a much better way to do such things:

class Foo {

private final static Object myLock = new Object();

public void someMethod() {

    synchronized(myLock) { ....... }

myLock is global, unique and is self-documenting.

Friday Mar 21, 2008

JDK - GetAbsolutePath doesn't

I just finished fixing a bug and I decided to share it so you can avoid the misery of finding it yourself.

JDK's is not that smart about Files vs. String Paths.   You may use getAbsolutePath and getAbsoluteFile because you think it will really give you an absolute path.  Not true at all.  It merely fills in the beginning of the path for you.  It does nothing about trailing dots.

Say your current directory is /foo.  Let's say you have a file named x in the current directory.

String s = new File("x").getAbsolutePath();

this returns "/foo/x".  Perfect!

Now say you do something crazy like

 String s = new File("../foo/./x").getAbsolutePath();

this returns "/foo/./x"  -- doesn't look absolute to me!

What the JDK means by absolute is only that the absolute path will unambiguously point at a file -- without needing the location of the current directory.  Period.   It does most definitely not imply that that you are getting a path with no relative elements in it.

getCanonicalFile and getCanonicalPath are highly under-used methods in my experience.  These methods guarantee to return a 1:1 mapping with the file.  I.e. there is one and only one unique Canonical path for every file on disk.  There are an infinite number of Absolute paths for a given file.

 String s = new File("../foo/./x").getCanonicalPath();

this returns "/foo/x" -- just what you wanted.

Now here is where I got into trouble.  I'm given a ABSOLUTE  path to a jar file.  I need to get the parent directory of the directory that contains the jar file.  So I innocently did the following:

given:  File f  which internally has this path "/foo/lib/./x.jar"

 File grandparent = f.getParentFile().getParentFile();

String s = grandparent.getPath();

I expected the String to be "/foo"

It wasn't though, it was "/foo/lib"!

 JDK says the parent is "/foo/lib/.", and the parent of the parent is "/foo/lib"

JDK is not treating "." specially but, rather, like it's a regular file in this context!

My code was working perfectly until the caller decided to drop a dot in the middle of the path and then suddenly my code broke.


Use CanonicalPath and CanonicalFile.  But wait -- they might throw an IOException.  What a hassle!!

That's no big deal.  I've been using them for years and I have never seen an Exception get thrown.  JDK is paranoid because these methods call into native code to get the right path.  I've written this following snippet of code way, way too many times.  I highly recommend it -- but add it into your utility code, write it once and call it a gazillion times.

public static File sanitize(File f) {
    if(f == null) {
        return null;
    try {
        return f.getCanonicalFile();
    catch(Exception e) {
        return f.getAbsoluteFile();

Here is some sample code you can try, along with the output:
public class Main
    public static void main(String[] args)
        File f = new File(System.getProperty("") + "/foo");
        String foo = f.getPath();
        foo += "/./././././.";
        f = new File(foo);
        // f is now "c:/tmp/foo/./././././."
        while((f = f.getParentFile()) != null) {
            System.out.println("PARENT: " + f);


PARENT: c:\\tmp\\foo\\.\\.\\.\\.\\.
PARENT: c:\\tmp\\foo\\.\\.\\.\\.
PARENT: c:\\tmp\\foo\\.\\.\\.
PARENT: c:\\tmp\\foo\\.\\.
PARENT: c:\\tmp\\foo\\.
PARENT: c:\\tmp\\foo
PARENT: c:\\tmp
PARENT: c:\\


Tuesday Nov 13, 2007

I Want To See My JSP's Generated Servlet Source!!

It is difficult to see the servlets that get generated from  your JSP files.

If you politely ask NetBeans it will tell you something like "You have to run the file first".  And this is after you run the file!

Anyways once you know how -- it is easy.  Read on...


When you deploy a web module (or a Web App that has a web module in it) by default it will not compile the jsp's as part of the deployment process.  Instead, the jsp will be compiled "just in time" by the web container the first time the web module is accessed long after deployment completes.

We need to tell the jsp-compiler to keep the generated files instead of deleting them.  This is the "keepgenerated" option to the jsp-compiler.  You set this option by editing the default-web.xml file in the domain's config directory.  Search for "keepgenerated" and you will see the xml that needs editing just below the enormous comment.  It should look like this when you're done editing


You would think that that is enough to get your generated source, but it is not.  The web-container orchestrated jsp compile is either ignoring the keepgenerated option -- or the generated files are well-hidden.

But it will work if you ask the GF Deployment code to do the compiling for you like so:

asadmin deploy --precompilejsp=true some.war

 ALL of your jsp generated servlet source will be located in:



In summary:

(1) setup the keepgenerated option in default-web.xml and then forget about it

(2) For every deployment use the --precompilejsp=true option

I spent far too much time figuring this out so I am sharing my results here.  

As I was stepping through the deployment source code I thought "Wow, this is pretty nice code".  Then I realized "HEY!  I wrote this code!  It's been about 5 years but there it still is!" 

Tuesday Nov 06, 2007


I use the backspace key on my keyboard about a billion times a day.

I use the shift  key on my keyboard about 10 million times a day.

I use the tab key  on my keyboard about a million times a day.

I use the Caps Lock key about once a month.

Nevertheless I have an enormous Caps Lock key conveniently located right in the traffic lane between the tab and shift keys!



My buddy came up with a solution -- take a screwdriver and pry off the annoying Caps Lock key.  i WILL IMPLEMENT THIS TODAY!!

Thursday Oct 11, 2007

New Backup Restore for V3

We are considering significantly improving the Backup and Restore abilities in GlassFish for V3.  

If you have desires/needs/suggestions on Backup Restore features, now is the time to let us know.  Just leave a comment! 

  • Increase granularity -- i.e. allow selecting one or more of the 4 kinds of deployed "things"
  • backup JavaEE modules
  • backup  JavaEE apps
  • backup lifecycle modules
  • backup mbeans


  • backup configuration
  • backup nodeagents and instances
  • backup EVERYTHING -- the entire GlassFish installation

Customized Rules -

  • Exclude certain files and/or directories from the backup
  • Specify whether or not to backup symbolic link directories recursively
  • Define other things to backup -- e.g. databases

Incremental Backups

  • This is very useful when you have a big GlassFish system that doesn't change too often.  You can have the security of frequent backups without using up huge amounts of disk space. 

Automatic Backups

  • Continuous Configuration Backup - backup domain.xml every time it changes and keep the last, say, 10 versions
  • Automatically backup the previous version of every app and module

Backup GUI

Specifying the above details via, say, an xml file could be rather painful.  We can develop a GUI for doing customized Backup or Restore  immediately.  Even better, the GUI would make it easier to specify everything and then produce an xml file that can be used in an automated manner.

Friday Oct 05, 2007

How to start JavaDB/Derby as a Windows Service

As I've recently started using the built-in Java DB support in GlassFish, I want the Java DB Network Server to start automatically along with GlassFish.

 I discovered that I can use the exact same method and program that's used for GlassFish-as-a-service.

On Windows, I used this script to setup a Windows Service that automatically starts the Java DB Network Server.  You can change the paths, run it once and the DB will start automatically as a service.


@echo off
if "%1A"=="A" goto usage
if "%2A"=="A" goto usage

echo on
sc create %1 binPath= "C:\\as\\lib\\appservService.exe \\"C:\\as\\bin\\asadmin.bat start-database --dbhome %2\\" \\"C:\\as\\bin\\asadmin.bat stop-database\\""  start= auto DisplayName= %1
goto end

echo usage createDBservice  name dbhome



Wednesday Oct 03, 2007

Mort Learns JDBC Realm Authentication for GlassFish

Here is another good blog on this subject.

In my last blog I showed you how to make a jdbc-resource that you can use for accessing a database.

Now I'll explain how to use that jdbc-resource to setup JDBC Realm Authentication and Authorization.

Realm Background

The job of a realm is to maintain a repository of user information.  Each user has one password and 0 or more groups that he belongs to.

At runtime a Realm is initially given a username and password and the realm then figures out if the user is authentic by checking the password.  It checks for authorization by seeing if the user's list of groups is authorized to use a resource (more on this later).

How to Create The Realm for userauth 

Using Admin GUI navigate to Configuration/Security/Realms.  Press the "new" button

Pick the classname that ends in JDBCRealm.  Use the jndi name of your jdbc-resource -- if it isn't userauth.

I'm assuming that you are starting from scratch with no user database.  If you already have such a database, you need to make sure your database table and column names are entered correctly and that your tables correspond to what JDBCRealm needs.  Such details are coming up...

Tip: Use the names in the screen-shot for the 2 table names and 3 column names.  These names are as good as the next.  If you standardize on these names you can use some tools I've developed for help administering and testing the realm.

Database user and password -- I'm not so sure about this.  The connection you get from the jndi name already has the username and password for that database.  I put the username and password from my database here and everything worked fine...

Digest Algorithm

You have to decide whether to save passwords as clear-text or encrypted.  If you want clear-text, leave the edit field blank.  If you want your passwords encrypted set this field to MD5.

My recommendation is to use MD5 for the passwords.  I have some tools with the code you need to convert a plain text password to an encrypted string in the right format for JDBCRealm.

On the other hand you can set it to no encryption -- and it will be much easier to seed the tables with test user info.   You can always change it to MD5 later when you have everything working.

All of the GlassFish administration work is now done.

Now you need to add some tables to your database.  You can run this sql script and it will do all the work for you.  The script also adds one user with username=admin and password=admin. 

The easy way to do this is to run "ij" -- a javaDB  sql console -- there is a copy here: <gf>/javadb/bin

ij> connect 'jdbc:derby://localhost:1527/userauth;user=APP;password=APP;create=true';

ij> run 'createdb.sql';


Now it's time to try out a protected web module.   What we want here is the World's Simplest Web Module.
In NetBeans, create a new web module.  The web module consists of one hello world jsp file.  Perfect.  If you don't use NetBeans then create some sort of ultra simple web module.

We have to add quite a bit of stuff to web.xml.  Netbeans makes fast work of it:


Here are the additions to web.xml (generated by NetBeans)



I have 2 roles named "ADMINISTRATORS" and "USERS".  I use these same names as the groupid values in the database table.  This makes the role-mapping a bit easier because you use the exact same name on both ends.

You must setup the roll-mapping in sun-web.xml  The easiest way to do it so directly edit the file and add these lines:


 Build and deploy this web module and then run it.  It will ask you for authentication info.  If you enter "admin" "admin" you should be allowed in to see the jsp page.

If you enter the name and password for someone that does not belong to the group "ADMINISTRATORS" then you will get an access violation error.

If there is interest, I'll follow up with some tools you can use to add users dynamically and to manage the database itself.



Tuesday Oct 02, 2007

Mort Learns JDBC for Glassfish

 I was intrigued by a problem and I set about solving it.  I finally did solve it.  It was a long difficult trail, but now that I know how to  do it it seems fairly easy.

If you are interested in Glassfish, JDBC, authentication and/or realms then read on.

The Problem: 

I now have 3 home made web modules doing useful things.  They all have authorization and authentication using file-based authentication.  That works fine but what if I want to add a new user?  It means I have to get the information and then create the right command to get the information into the key-file.  Or I figure out how to call Glassfish and have it put the username and password in for me.  Also -- what if I want the user's email address?  I can't put it in the key-file.  What about deleting a user?  Uh-oh.  Sounds complicated.  Plus I'm going to have to have some other data storage for the other user info.  I might as well use a real database -- the database gives me an easy way to add/edit/delete users at runtime (allowing users to create their own account unattended).  The database solves the problem of where to put the extra user info as well.

The Solution: 

Switch to JDBC Realm Authentication

The Trail

Using JDBC and JavaDB in GlassFish is easy.  You can go from no DB at all to a formed DB ready for your first SQL commands in 10 minutes or less.

There are a few traps waiting along for the unwary and I'll reveal them along with some tips.

 JavaDB Essential Information

 JavaDB is based on Derby.  A JavaDB database appears as a directory.  The directory's name is the database name.  When JavaDB opens up a database, that's it -- no other JavaDB runtime is now allowed to connect to that database.  

Tip: If you have connection problems look in the directory where the database is supposed to be.  Is it there?

If you use an embedded JavaDB database then what happens is that GlassFish itself is the JavaDB runtime that has that database locked.  As a result you can NOT look at the database anywhere else like, e.g. a SQL command processor.  If you want to issue SQL commands that way, you have to take down GlassFish to be able to access the database.  That's a disadvantage.  The advantages are

  • it is super-secure since there are no ports open for accessing the database.  GlassFish is in charge of  security for accessing the database
  • It is simpler to setup than the networked client


 The other choice is using the Derby Network Server.  This is just the classic client server database setup.  Derby runs one network server instance which is the "owner" of the databases embedded into it.  You can work on this database via SQL tools while GlassFish is connected to it.  It's not as simple.  You have to separately start and stop the JavaDB server.  GlassFish makes this easy for you with an asadmin command.  asadmin takes care of all the details -- environmental variables, classpath, etc.

I recommend the Network client mode.  It's no big deal, it's just another command that you use before starting GlassFish.  I figured out a way to make it a service in Windows as well (perhaps a future blog?)

Note: You can easily change an embedded client or a network client back and forth.

asadmin start-database -- dbhome <path-to-database-parent-dir>

Here's the first trap.  You don't have to specify the --dbhome option but I highly recommend always using it. 

Short Primer on Where the Heck is My Database on Disk?!?

If you run a stand-alone java program that uses embedded JavaDB, and you tell it to open a database named "foo", it will look for a directory named "foo" in the directory you ran the program from.   If you start a networked server -- it's the same deal, it will look in the directory that you started the server in.  GlassFish determines the all-important location of your databases on disk as follows and in this order

  1. use the --dbhome path as the root of all the databases  Done!
  2. else look in the current directory if there is a file named "derby.log" then make the current directory the root.
  3. else use a standard location:  <gf>/databases

If you don't use the --dbhome option then you need to be aware of whether or not derby.log is in your current directory.

 Let's Get This JDBC Party Started Already

You need to create two items in Glassfish in order to access a database.

The first is a JDBC Connection Pool.

In the Admin GUI navigate to Resources/JDBC/Connection Pool

Set the easy stuff.  Note that "name" is the name of the pool.  This pool is for a network client.  The configuration is a bit different for embedded databases.  I have pictures at the end of this blog for the embedded case.



Here is the first page of mysterious properties.  If you are an experienced DB person you'll know what to do.  If you're like me you'll happily take the defaults.


 This is where all the action is.  You don't want to make any mistakes here.  Here is the default layout:

And here is what it should look like.

Note that DataSource has no value.

Tip: set connectionAttributes to ";create=true".  Now you can make GlassFish create the database for you! 


And here is the new Connection Pool.  Click on it and then press the ping button and the (empty) database will be created.

 The next step is to create a JDBC Resource.  Armed with this jndi name you can get a connection to the database at runtime.

Navigate to Resources/JDBC/JDBC Resources and press the "new" button. 

That's all.  Glassfish is ready to serve up database connections.  From a servlet this code will do the job:

            InitialContext ctx = new InitialContext();
            DataSource ds = (DataSource) ctx.lookup("jdbc/userauth");
            Connection connection = ds.getConnection();

Tuesday Sep 11, 2007

Monitored System.setProperty

[Read More]

Tuesday Jun 12, 2007

Chapter 1 - A Standalone Dean Edell Downloader

This chapter can be downloaded here.

This zip file has the entire Chapter1 NetBeans project in it. I highly recommend using NetBeans 5.51 for this tutorial. And of course you are going to need GlassFish

The first thing that we need to get working is the automatic downloading of the Dean Edell mp3 files. We're going to make a simple stand-alone Java SE application to do the downloading. We will then create a simple script to run the java application. After testing it to make sure all is well we'll get the operating system to call it every Monday through Friday night at 11:30 PM PDT.

The Java Technology Portion

The source consists of two files:
  • HTTPDownloader.javaA simple class that takes a URL string and a filename string. It fetches the file that the URL is pointing to and writes it to the filename. This is where Jaca Technology really pays off. It's ridiculously easy to do.
  • DeanEdellDownloader.javaThis class is also pretty simple. The most difficult part is assembling a distinctive filename based on the date.
DeanEdellDownloader uses HTTPDownloader to fetch the current Dean Edell mp3 file. It refuses to run on weekends. The URL and the location to write the mp3 files is hard-coded here. That's OK in this scenario because we are going to build it once and forget about it.

You will need to change the value of one variable in DeanEdellDownloader. The last line of the file contains the target directory from my GlassFish installation. Replace it with your path:

private final static String DEFAULT_DIR_HTTP = "C:/as/domains/domain1/docroot/DeanEdellFiles";

The Script

NetBeans automatically put a manifest file pointing to the correct main in the jar file. On my Windows system I put a script in DeanEdell.bat in a scripts directory. The command in the script is:

java -jar path-of-jar-file

Run the script. A 10.5 MB mp3 file should appear in [domain]/docroot/DeanEdellFiles (unless it is the weekend!)

Calling the Script Automatically Forever

If you are on UNIX or Linux you are on your own here. You need to create a chron job that runs the script Monday through Friday around 11:30 PM PDT. It's OK to run it on weekends too -- it won't do anything.

On Windows this is super easy to do: Go to Control Panel and then run Scheduled Tasks. It will take you by the hand and guide you in making a chron job. Just have it call the batch file every Monday through Friday around 11:30 PM PDT. Make sure you enter your account password.

And that's all there is to Chapter 1. We now have DeanEdell mp3's appearing automatically in a folder under docroot inour domain.

Next Installment: Chapter 2 - Create a Web Application to serve up the files

Monday Jun 11, 2007

Let's Get This Glassfish Party Going!

This is the first chapter in a n-chapter tutorial on how to exploit Glassfish capabilities. I learned long ago that the only way I can really cement into my head a hunk of technology is to just do it. I came up with a useful application for web technology. In this series we will be building an application that will slowly but surely use these areas of javaee. They are in the approximate order that we will tackle in the project.
  • HTTP File downloading (HyperText Transfer Protocol)
  • Servlets
  • JSPs (Java Server Pages)
  • User Authentication - Basic, then File Realms, then JDBC Realms
  • Derby Database
  • JNI (Java Naming Interface)
  • EJB 3.0 (Enterprise Java Beans)
  • JPA (Java Persistence API)
  • EJB Timer Service
  • Struts
  • JSP Tag Libraries
  • MDB (Message Driven Beans)

Chapter 0: The Application Description

Dr. Dean Edell has an interesting radio talk show on KGO radio in San Francisco. His show is from 1 to 2 PM Monday through Friday. KGO posts an mp3 file for the show once a day. KGO takes it down, forever, after 24 hours. KGO does not maintain an archive of old shows. I like to burn the shows onto CDs and listen to them in my car. What this application will do is:
  • Automatically download the mp3 at 11:38 PM every night, Monday through Friday and save them to a subdirectory of docroot on my Glassfish Application Server.
  • Maintain user accounts for people that wish to download the files. New accounts will be accepted and added to the list on demand.
  • The application will persist which files have been downloaded for each user. When a user is authenticated he will see his own custom list of programs he has yet to download.
  • A list of all available programs will also be available in case of trouble (like the dog eating the Dean Edell CDs)

This sounds like a lot of overkill for such modest sounding requirements. But making it 100% automatic is a bit challenging. Besides, the whole point of this is to create an application - any application -- in order to learn how to do all this stuff. We will start simple but thorough and correct. We will constantly change and modify it to use the cutting edge Java EE technology as the tutorial progresses.

Stay Tuned for the next installment, Chapter 1:

Write a stand alone Java application that will download the mp3 file. The OS will be in charge of running this application via a chron/at job.




« July 2016