Return-Path: Delivered-To: apmail-jakarta-avalon-cvs-archive@apache.org Received: (qmail 36865 invoked from network); 29 Jun 2002 14:47:53 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by 209.66.108.5 with SMTP; 29 Jun 2002 14:47:53 -0000 Received: (qmail 8518 invoked by uid 97); 29 Jun 2002 14:48:03 -0000 Delivered-To: qmlist-jakarta-archive-avalon-cvs@jakarta.apache.org Received: (qmail 8473 invoked by uid 97); 29 Jun 2002 14:48:02 -0000 Mailing-List: contact avalon-cvs-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon CVS List" Reply-To: "Avalon Developers List" Delivered-To: mailing list avalon-cvs@jakarta.apache.org Received: (qmail 8462 invoked by uid 97); 29 Jun 2002 14:48:02 -0000 X-Antivirus: nagoya (v4198 created Apr 24 2002) Date: 29 Jun 2002 14:47:48 -0000 Message-ID: <20020629144748.11696.qmail@icarus.apache.org> From: leosutic@apache.org To: jakarta-avalon-excalibur-cvs@apache.org Subject: cvs commit: jakarta-avalon-excalibur/microcontainer/src/xdocs/stylesheets project.xml X-Spam-Rating: 209.66.108.5 1.6.2 0/1000/N X-Spam-Rating: 209.66.108.5 1.6.2 0/1000/N leosutic 2002/06/29 07:47:48 Modified: microcontainer/src/xdocs index.xml microcontainer/src/xdocs/stylesheets project.xml Added: microcontainer/src/xdocs tutorial.xml ShowDatabases.java Log: Initial check-in of the "Extremely Quick and Easy" tutorial. Revision Changes Path 1.3 +107 -22 jakarta-avalon-excalibur/microcontainer/src/xdocs/index.xml Index: index.xml =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/microcontainer/src/xdocs/index.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- index.xml 27 Jun 2002 14:34:05 -0000 1.2 +++ index.xml 29 Jun 2002 14:47:48 -0000 1.3 @@ -1,30 +1,115 @@ - Excalibur I/O Extensions - Overview - Avalon Documentation Team + Overview + Leo Sutic -
-

Avalon Excalibur's Input/Output utilities are in package - org.apache.avalon.excalibur.io.

- - -

Excalibur's IO package contains a comprehensive set of routines for - copying bytes and chars. Routines exist for copying from: - String, byte[], Reader and - InputStream, to:String, byte[], - Writer and OutputStream. -

-
- - -

- Excalibur includes a number of FileFilters that you can use for your - own purposes. This fills a gap in the Java runtime because the - interface was specified but no implementations were given. -

-
+
+

+ MicroContainer's purpose is to provide a way to use Avalon + components without having to commit to the Avalon architecture. +

+ +

+ It does so by: +

+ +
    +
  • +

    + Using standard Java idioms whenever possible. Use of Avalon components + should be as similar as possible to the use of standard Java classes. +

    +
  • +
  • +

    + Removing the need for XML assembly and/or deployment descriptors. Having + those means that you are forced to include XML parsing ability and need to + integrate the configuration with your own existing architecture. +

    +
  • +
  • +

    + Removing the need to center the application around the component container. + Most Avalon applications are centered around a component container, such as Fortress, + Phoenix or the Excalibur Component Manager (Cocoon). By removing that need, it + is easier to just pick an Avalon component and have it work with your existing + architecture. A MicroContainer will fit anywhere. +

    +
  • +
+
+ +
+

+ Does the above sound like something you'd like to use? Great! +

+ + +
+ +
+

+ MicroContainer has not yet had an official release. What this means for you is: +

+ +
    +
  • +

    + The API may change. While every effort will be made to keep API changes to + a minimum and to always provide backwards binary compatibility, some times + a developer must admit that he was going about it the wrong way and needs + to restructure parts of the project. +

    +
  • +
  • +

    + The documentation isn't quite complete. +

    +
  • +
  • +

    + You should hide your use of MicroContainer behind factory methods. + See the tutorial for an example of how to do + this. If you do so, API changes will impact you minimally should they + happen. +

    +
  • +
+
+ +
+

+ So it stubbornly refuses to work, does it? Defiantly throwing Exceptions all over + your code? MicroContainer, and all other Avalon projects are discussed in the + The Avalon User List. + Subscribe to it and post your question there. +

1.1 jakarta-avalon-excalibur/microcontainer/src/xdocs/tutorial.xml Index: tutorial.xml =================================================================== Extremely Quick and Easy Tutorial Leo Sutic

Welcome to the Extremely Quick and Easy Tutorial. This is what it consists of:

  • First, we'll make sure you have all the required JAR files.

  • Second, we'll set up your CLASSPATH correctly.

  • After that, a short discussion of what makes an Avalon component different from a regular Java class, and what MicroContainer does.

  • Fourth, an example that uses the Excalibur DataSource to list all databases in a MySQL installation.

  • And finally, we'll take a look at the factory that produces a MicroContainer for the DataSource.

You need the following JAR files:

  • excalibur-microcontainer: You can download the latest development JAR from http://gump.covalent.net/jars/latest/jakarta-avalon-excalibur/. Scroll down and you'll see a file named excalibur-microcontainer-YYYYMMDD.jar, with YYYYMMDD being the date the jar was built.

  • avalon-framework: If you do not have it already, you should grab a copy of avalon-framework.jar.

  • excailbur-datasource: Go to: http://gump.covalent.net/jars/latest/jakarta-avalon-excalibur/ and download

    • excalibur-datasource-YYYYMMDD.jar

    • excalibur-pool-YYYYMMDD.jar

    • excalibur-collections-YYYYMMDD.jar

    As with the MicroContainer JAR, the YYYYMMDD will be the date the JAR was built.

  • You also need a JAR with drivers for your database. If you, like me, use MySQL, you can find drivers at http://mmmysql.sourceforge.net/.

    • Click on the download link and select mm.mysql-2.0.9-you-must-unjar-me.jar. Note the version number - the other downloads are source distributions.

    • Unjar the file you just downloaded and find the file mm.mysql-2.0.9-bin.jar. This is the file containing DB drivers for MySQL.

Now that you have all JAR files, create a directory for the tutorial and copy the files into it.

dir Volume in drive C has no label. Volume Serial Number is 6C66-7072 Directory of C:\microcontainertutorial 2002-06-29 16:26 . 2002-06-29 16:26 .. 2002-06-29 16:26 59 369 avalon-framework.jar 2002-06-29 16:26 33 563 excalibur-collections-20020628.jar 2002-06-29 16:26 42 775 excalibur-datasource-20020628.jar 2002-06-29 16:25 29 623 excalibur-microcontainer-20020628.jar 2002-06-29 16:26 44 453 excalibur-pool-20020628.jar 2002-01-19 10:55 121 015 mm.mysql-2.0.9-bin.jar 7 File(s) 330 798 bytes 2 Dir(s) 11 774 013 440 bytes free C:\microcontainertutorial>]]>

You need to include all the above jars in your classpath.

Note that the last SET command includes the current directory in the classpath.

In five words: It expects to be managed.

When you use a regular Java class, you would typically call its constructor and then start using it. Basically, as soon as you have an instance of the class, it is good to go.

Avalon components are different. For example, if the component class implements the org.apache.avalon.framework.activity.Initializable interface, it will have an initialize() method that must be called before the component is ready to be used. Another difference is that all components have a no-argument constructor. Those components that have configuration parameters will implement the org.apache.avalon.framework.configuration.Configurable interface, which defines a single method: configure( Configuration config );. The component then expects to recieve all configuration parameters via that method.

This is why a container is needed. The container is responsible for calling the right methods with the correct parameters, and in general manage the component the way it expects to be managed.

MicroContainer's goal is to provide such a container that can easily be used in any kind of program, and to have minimal impact on your existing code. In particular, MicroContainer is special because it only manages a single component. All the other containers manage several components. MicroContainer manages one. The other containers solve the use case where one component uses another by linking them up inside the container - MicroContainer allows you to link several MicroContainers together for the same purpose.

Now that we have a good idea of what makes Avalon components special, let's get down to practicalities. In particular, how would one use MicroContainer in combination with the Excalibur DataSource to access a MySQL database?

You can download the sample here. Starting with the import declarations, here's the sample code:

For now, we will use the org.apache.excalibur.microcontainer.util.DataSourceFactory to create a MicroContainer for a org.apache.avalon.excalibur.datasource.JdbcDataSource. This is just to quickly get something that can run. As soon as this version runs, we will dig into the DataSourceFactory class and see how to create a MicroContainer.

Proceeding with the sample code, here's the top of the main method:

Some fairly basic initialization followed by a status message. You should edit the parameters to fit your MySQL configuration.

Now we come to the creation of a DataSourceComponent.

A bit of pure magic hidden inside DataSourceFactory.getDataSource() for now. The method takes creation parameters for the DataSource, and returns a MicroContainer that implements the DataSourceComponent. This is important to remember: The object returned by the getDataSource method is a MicroContainer, and not an instance of the Avalon component. Via dynamic proxies, the MicroContainer will implement all interfaces that the component does, thus enabling it to be used just as a component, but keep in mind that it is a proxy.

Finally, the code to get a connection, execute a query, and close everything down.

The above is some fairly straight JDBC access. Do, however, note the MicroContainer.release(ds); at the bottom. As I said above, Avalon components expect to be managed during their initialization phase. They also expect to be managed when shutting down. That's why all MicroContainers must be explicitly released.

At this point, you should compile and test the code with

javac *.java

and

java ShowDatabases

If it works, it should result in output similar to this:

The problem of creating a suitable MicroContainer for a DataSource boils down to this: Since the JdbcDataSource class (which we will use) implements Configurable, it expects configuration parameters in the form of a Configuration object, and we must create a suitable such object for it. All other aspects of management can be handled by the MicroContainer.

Looking at the Javadoc for org.apache.avalon.excalibur.datasource.JdbcDataSource we see that the components expects a configuration like this:

select 1 true com.database.jdbc.JdbcDriver jdbc:driver://host/mydb username password ]]>

One thing that is apparent from the configuration above is that it uses the value part of the configurations to pass parameters and not the attributes. That is, instead of having <user name="username"/>, it has <user>username</user>. So we'll create utility method to create such configuration elements first.

The method will create a DefaultConfiguration, sets its value and return it. For example, to create <user>username</user>, we would call it thus:

Right then, here's the parts that creates the configuration object:

You are probably recoiling in shock and horror at the above. After all, MicroContainer was supposed to reduce complexity, wasn't it? Well, creating a configuration instance programmatically is dirty. There's just not many other ways to do it. Second, the JdbcDataSource class has a fairly massive configuration with lots of parameters.

(If there were any other component with simpler configuration and that yet was as easy to write a sample program for, I would have used it here instead.)

The DataSource component we wanted to use required a configuration. We have one now, and can thus go on to create the actual MicroContainer:

And that was it. Note that the MicroContainer class follows the named parameter idiom.

So it stubbornly refuses to work, does it? Defiantly throwing Exceptions all over your code? MicroContainer, and all other Avalon projects are discussed in the The Avalon User List. Subscribe to it and post your question there.

1.1 jakarta-avalon-excalibur/microcontainer/src/xdocs/ShowDatabases.java Index: ShowDatabases.java =================================================================== import java.sql.Connection; import java.sql.Statement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.StringTokenizer; import org.apache.avalon.excalibur.datasource.DataSourceComponent; import org.apache.avalon.excalibur.datasource.JdbcDataSource; import org.apache.excalibur.microcontainer.MicroContainer; import org.apache.excalibur.microcontainer.util.DataSourceFactory; /** * Sample code to show all databases in a MySQL installation. * * @author Leo Sutic */ public class ShowDatabases { /** * Main method. */ public static void main( String[] args ) throws Exception { String driver = "org.gjt.mm.mysql.Driver"; String dbUrl = "jdbc:mysql://localhost/"; String query = "SHOW DATABASES;"; String userName = "sa"; String password = ""; System.out.println( "Attempting to create a DataSourceComponent with the following parameters:" ); System.out.println( " Driver: " + driver ); System.out.println( " DB URL: " + dbUrl ); System.out.println( "User name: " + userName ); System.out.println( " Password: " + (password != null ? "(hidden)" : "(not specified)") ); DataSourceComponent ds = DataSourceFactory.getDataSource( driver, // JDBC Driver dbUrl, // Database URL userName, // user name password, // user's password null, // Connection keep-alive command (none) 1, // Minimum number of connections in pool. 3, // Maximum number of connections in pool. -1, // Connection timeout (disabled) true, // Auto commit false, // Using oracle (only relevant when supplying a keep-alive command) null); // Override name of connection class (null == use default). Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = ds.getConnection(); stmt = conn.createStatement(); System.out.println( "\nExecuting query: " + query + "\n" ); rs = stmt.executeQuery( query ); System.out.println( "The following databases were found:" ); while (rs.next()) { System.out.println( rs.getObject( 1 ) ); } } finally { if( rs != null ) { rs.close(); } if( stmt != null ) { stmt.close(); } if( conn != null ) { conn.close(); } MicroContainer.release(ds); } } } 1.2 +18 -13 jakarta-avalon-excalibur/microcontainer/src/xdocs/stylesheets/project.xml Index: project.xml =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/microcontainer/src/xdocs/stylesheets/project.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- project.xml 27 Jun 2002 14:35:32 -0000 1.1 +++ project.xml 29 Jun 2002 14:47:48 -0000 1.2 @@ -1,16 +1,21 @@ - - Excalibur MicroContainer - - - - - - - - - - - + + Excalibur MicroContainer + + + + + + + + + + + + + + + + -- To unsubscribe, e-mail: For additional commands, e-mail: