Did you know? DZone has great portals for Python, Cloud, NoSQL, and HTML5!

Java

  • submit to reddit

Getting Started with Oracle Berkeley DB

By Masoud Kalali

8,501 Downloads · Refcard 68 of 151 (see them all)

Download
FREE PDF


The Essential Berkeley DB Cheat Sheet

The Oracle Berkeley DB (BDB) family consists of three open source data persistence products that provide developers with fast, reliable, high performance, enterprise ready local databases implemented in the ANSI C and Java programming languages. This DZone Refcard provides a brief introduction to the Oracle Berkeley DB family. The author, Masoud Kalali, then moves on to discuss in depth the Oracle Berkeley DB Java Edition, including the following topics: Transaction Support, Performance Tuning, Backup, and Recovery. This DZone Refcard is perfect for anyone interested in learning more about the Oracle Berkeley DB family and its capabilities.
HTML Preview
Getting Started with Oracle Berkeley DB

Getting Started with Oracle Berkeley DB

By Masoud Kalali

About Oracle Berkeley DB

The Oracle Berkeley DB (BDB) family consists of three open source data persistence products which provide developers with fast, reliable, high performance, enterprise ready local databases implemented in the ANSI C and Java programming languages. The BDB family typically stores key-value pairs but is also flexible enough to store complex data models. BDB and BDB Java Edition share the same base API, making it possible to easily switch between the two.

We will review the most important aspects of Oracle BDB family briefly. Then we will dig deep into Oracle BDB Java Edition and see what its exclusive features are. We discuss Based API and Data Persistence Layer API. We will see how we can manage transactions DPL and Base API in addition to persisting complex objects graph using DPL will form the overall development subjects. Backup recovery, tuning, and data migration utilities to migrate data between different editions and installations forms the administrations issues which we will discuss in this Refcard.

The BDB Family

Oracle BDB Core Edition

Berkeley DB is written in ANSI C and can be used as a library to access the persisted information from within the parent application address space. Oracle BDB provides multiple interfaces for different programming languages including ANSI C, the Java API through JNI in addition to Perl, PHP, and Python.

Oracle BDB XML Edition

Built on top of the BDB, the BDB XML edition allows us to easily store and retrieve indexed XML documents and to use XQuery to access stored XML documents. It also supports accessing data through the same channels that BDB supports.

BDB Java Edition

BDB Java Edition is a pure Java, high performance, and flexible embeddable database for storing data in a key-value format. It supports transactions, direct persistence of Java objects using EJB 3.0-style annotations, and provides a low level key-value retrieval API as well as an “access as collection” API.

Key Features

Each of the BDB family members supports different feature sets. BDB XML edition enjoys a similar set of base features as the Core BDB. BDB Java edition on the other hand is implemented in a completely different environment with an entirely different set of features and characteristics (See Table 4). The base feature sets are shown in Table 1.

Table 1: Family Feature Sets
Feature Set Description
Data Store (DS) Single writer, multiple reader
Concurrent Data Store (CDS) Multiple writers, multiple snapshot readers
Transactional Data Store (TDS) Full ACID support on top of CDS
High Availability (HA) Replication for fault tolerance. Fail over recovery support

Table 2 shows how these features are distributed between the different BDB family members.

Table 2: Different Editions’ Feature Sets DS CDS TS HA
BDB/BDB XML Edition

model_binder

model_binder

model_binder

model_binder

BDB Java Edition

model_binder

model_binder

Additional Features

The BDB family of products has several special features and offers a range of unique benefits which are listed in Table 3.

Table 3: Family Features and Benefits
Feature Benefit
Locking High concurrency
Data stored in application-native format Performance, no translation required
Programmatic API, no SQL Performance, flexibility/control
In process, not client-server Performance, no IPC required
Zero administration Low cost of ownership
ACID transactions and recovery Reliability, data integrity
Dual License Open/Closed source distributions
In memory or on disk operation Transacted caching/ persisted data store
Similar data access API Easy switch between JE and BDB
Just a set of library Easy to deploy and use
Very large databases Virtually no limit on database size

Features unique to BDB Java Edition are listed in Table 4.

Table 4: BDB Java Edition Exclusive Features
Feature Benefit
Fast, indexed, BTree Ultra fast data retrieval
Java EE JTA and JCA support Integration with Java EE application servers
Efficient Direct Persistence Layer EJB 3.0 like annotation to store Java Objects graph
Easy Java Collections API Transactional manipulation of Base API through enhanced Java Collections
Low Level Base API Work with dynamic data schema
JMX Support Monitor able from within parent application

These features, along with a common set of features, make the Java edition a potential candidate for use cases that require caching, application data repositories, POJO persistence, queuing/buffering, Web services, SOA, and Integration.

Introducin g Berkeley DB java Edition

Installation

You can download BDB JE from http//bit.ly/APfJ5. After extracting the archive you’ll see several directories with selfdescribing names. The only file which is required to be in the class path to compile and run the included code snippet is je- 3.3.75.jar (the exact file name may vary) which is placed inside the lib directory. Notice that BDB JE requires J2SE JDK version 1.5.0_10 or later.

Hot Tip

All editions of Berkeley DB are freely available for download and can be used in open source products which are not distributed to third parties. A commercial license is necessary for using any of the BDB editions in a closed source and packaged product. For more information about licensing visit: http://bit.ly/17pMwZ

Access APIs

BDB JE provides three APIs for accessing persisted data. The Base API provides a simple key-value model for storing and retrieving data. The Direct Persistence Layer (DPL) API lets you persist any Java class with a default constructor into the database and retrieve it using a rich set of data retrieval APIs. And finally the Collections API which extends the well known Java Collections API with data persistence and transaction support over data access.

Base API sample

The Base API is the simplest way to access data. It stores a key and a value which can be any serializable Java object.


EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
Environment dbEnv = new Environment(new File(“/home/masoud/dben”),
envConfig);
DatabaseConfig dbconf = new DatabaseConfig();
dbconf.setAllowCreate(true);
dbconf.setSortedDuplicates(false);//allow update
Database db = dbEnv.openDatabase(null, “SampleDB “, dbconf);
DatabaseEntry searchEntry = new DatabaseEntry();
DatabaseEntry dataValue = new DatabaseEntry(“ data content”.
getBytes(“UTF-8”));
DatabaseEntry keyValue = new DatabaseEntry(“key content”.
getBytes(“UTF-8”));
db.put(null, keyValue, dataValue);//inserting an entry


db.get(null, keyValue, searchEntry, LockMode.DEFAULT);//retrieving
record
String foundData = new String(searchEntry.getData(), “UTF-8”);
dataValue = new DatabaseEntry(“updated data content”.
getBytes(“UTF-8”));
db.put(null, keyValue, dataValue);//updating an entry
db.delete(null, keyValue);//delete operation
db.close();
dbEnv.close();

There are multiple overrides for the Database.put method to prevent duplicate records from being inserted and to prevent record overwrites.

DPL Sample

DPL sample consists of two parts, the entity class and the entity management class which handle CRUD over the entity class.

Entity Class


@Entity
public class Employee {
  @PrimaryKey
  public String empID;
  public String lastname;
  @SecondaryKey(relate = Relationship.MANY_TO_MANY,
  relatedEntity = Project.class,onRelatedEntityDelete =
DeleteAction.NULLIFY)
  public Set<Long> projects;
  public Employee() { }
  public Employee(String empID, String lastname, Set<Long> projects)
{
   this.empID = empID;
   this.lastname = lastname;
   this.projects = projects;
    }
  }}

This is a simple POJO with few annotations to mark it as an entity with a String primary key. For now ignore the @Secondarykey annotation, we will discuss it later.

The data management Class


EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
Environment dbEnv = new Environment(new File(“/home/masoud/dbendpl”),
envConfig);
StoreConfig stConf = new StoreConfig();
stConf.setAllowCreate(true);
EntityStore store = new EntityStore(dbEnv, “DPLSample”, stConf);
PrimaryIndex userIndex;
userIndex = store.getPrimaryIndex(String.class, Employee.class);
userIndex.putNoReturn(new Employee(“u180”, “Doe”, null));//insert
Employee user = userIndex.get(“u180”);//retrieve
userIndex.putNoReturn(new Employee(“u180”, “Locke”, null));//
Update
userIndex.delete(“u180”);//delete
store.close();
dbEnv.close();

These two code snippets show the simplest from of performing CRUD operation without using transaction or complex object relationships.

Sample code description

An Environment provides a unit of encapsulation for one or more databases. Environments correspond to a directory on disk. The Environment is also used to manage and configure resources such as transactions. EnvironmentConfig is used to configure the Environment, with options such as transaction configuration, locking, caching, getting different types of statistics including database, locks and transaction statistics, etc.

One level closer to our application is DatabaseConfig and Database object when we use Base API. When we use DPL these objects are replaced by StoreConfig and EntityStore.

In Base API DatabaseConfig and Database objects provide access to the database and how the database can be accessed.

Configurations like read-only access, record duplication handling, creating in-memory databases, transaction support, etc. are provided through DatabaseConfig.

In DPL StoreConfig and EntityStore objects provide access to object storage and how the object storage can be accessed. Configurations such as read only access, data model mutation, creating in-memory databases, transaction support, etc. are provided through StoreConfig.

The PrimaryIndex class provides the primary storage and access methods for the instances of a particular entity class. There are multiple overrides for the PrimaryIndex.put method to prevent duplicate entity insertion and provide entity overwrite prevention.

Hot Tip

When closing an Environment or Database or when we commit a Transaction in a multi thread application we should ensure that no thread still has in-progress tasks.

BDB Java edition environment anatomy

A BDB JE database consists of one or more log files which are placed inside the environment directory.

The log files are named NNNNNNNN.jdb where NNNNNNNN is an 8-digit hexadecimal number that increases by 1 (starting from 00000000) for each log file written to disk. BDB JE rolls to next file when the current file size reaches the predefined configurable size. The predefined size is 10MB.

A BDB database can be considered like a relational table in an RDBMS. In Base API we directly use the database we need to access, while in DPL we use an EntityStore which may interact with multiple databases under the hood.

Each BDB environment can contain tens of databases and all of these databases will be stored in a single row of log files. (No separate log files per-database). Figure 1 shows the concept visually.

Hot Tip

To create in-memory database we can use DatabaseConfig. setTemporary(true) and StoreConfig.setTemporary(true) to get an in-memory instance with no data persisted beyond the current session.

Figure1

Figure 1: BDB JE environment and log files.

Hot Tip

The environment path should point to an already existing directory, otherwise the application will face and exception. When we create an environmnt object for the first time, necessary files are created inside that direcory.

BDB Java edition environment anatomy

Table 5 shows Base API characteristics and benefits. The keyvalue access model provides the most flexibility.

Table 5: Base API Features
Key value store retrieval, value can be anything
Cursor API to traverse in a dataset forward and backward
JCA (Java Connectivity Architecture) support
JMX (Java Management eXtension) support
Table 6: DPL API Features
Type Safe access to persisted objects
Updating classes with adding new fields is supported
Persistent class fields can be private, package-private, protected or public
Automatic and extendable data binding between Objects and underlying storage
Index fields can be accessed using a standard java.util collection.
Java annotations are used to define metadata like relations between objects
Field refactoring is supported without changing the stored date.(Called mutation)

Table 6 and Table 7 list the features that mostly determine when we should use which API. Table 7 lists possible use cases for each API.

Table 7: Which API is suitable for your case
Use case characteristics Suitable API
Data model is highly dynamic and changing Base API
Data model has complex object model and relationships DPL
Need application portability between Java Edition and Core Edition DPL, Base API

Transaction Support

Transaction Support is an inseparable part of enterprise software development. BDB JE supports transaction and provides concurrency and record level locking. To add transaction support to DPL in our DPL sample code we can introduce the following changes:


...
envConfig.setTransactional(true);
stConf.setTransactional(true);
TransactionConfig txConf = new TransactionConfig();
stConf.setTransactional(true);
txConf.setReadCommitted(true);
Transaction tx= dbEnv.getThreadTransaction();
dbEnv.beginTransaction(tx, txConf);
...
userIndex.putNoReturn(tx, new Employee(“u180”, “Doe”, null));//
insert
...
tx.commit();
...

The simplicity of BDB JE Transaction Support makes it very suitable for transactional cache systems. The isolation level, deferrable and manual synchronization of transactional data with hard disk (Durability), replication policy, and transaction lock request and transaction lifetime timeout can be configured using the Transaction and TransactionConfig objects.

Hot Tip

Environment, Database, and EntityStore are thread safe meaning that we can use them in multiple threads without manual synchronization

Transaction support in Base API is a bit different, as in Base API we directly deal with databases while in DPL we deal with environment and EntityStore objects. The following changes will allow transaction support in Base API.


...
envConfig.setTransactional(true);
dbconf.setTransactional(true);
TransactionConfig txConf = new TransactionConfig();
txConf.setSerializableIsolation(true);
txConf.setNoSync(true);
Transaction tx = dbEnv.getThreadTransaction();
tx.setLockTimeout(1000);
tx.setTxnTimeout(5000);
Database db = dbEnv.openDatabase(tx, «SmpleDB», dbconf);
dbEnv.beginTransaction(tx, txConf);
...
db.put(tx, keyValue, dataValue);//inserting an entry
...
tx.commit();

More transaction related supported features are demonstrated in this snippet. Environment, Database, EntityStore, etc. configuration is omitted from these snippet for sake of simplicity.

Hot Tip

Once a transaction is committed, the transaction handle is no longer valid and a new transaction object is required for further transactional activities.

Persisting Complex Object Graph using DPL

For this section we leave Base API alone and focus on using DPL for complex object graphs. We continue with introducing secondary index and many-to-many mapping.

Let’s look at some important annotations that we have for defining the object model.

Table 8: BDB JE annotations
Annotation Description
@Entity Declares an entity class; that is, a class with a primary index and optionally one or more indices.
@PrimaryKey Defines the class primary key and must be used one and only one time for every entity class.
@SecondaryKey Declares a specific data member in an entity class to be a secondary key for that object. This annotation is optional, and can be used multiple times for an entity class.
@Persistent Declares a persistent class which lives in relation to an entity class.
@NotTransient Defines a field as being persistent even when it is declared with the transient keyword.
@NotPersistent Defines a field as being non-persistent even when it is not declared with the transient keyword.
@KeyField Indicates the sorting position of a key field in a composite key class when the Comparable interface is not implemented. The KeyField integer element specifies the sort order of this field within the set of fields in the composite key.

We used two of these annotations in practice and you saw @SecondaryKey in the Employee class. Now we are going to see how the @SecondaryKey annotation can be used. Let’s create the Project entity which the Employee class has a many-to-many relation with.


@Entity
public class Project {
	public String projName;
	@PrimaryKey(sequence = «ID»)
	public long projID;
	public Project() {
	}
	public Project(String projName) {
	this.projName = projName;
	}
}

The @PrimaryKey annotation has a string element to define the name of a sequence from which we can assign primary key values automatically. The primary key field type must be numerical and a named sequence can be used for multiple entities.

Now let’s see how we can store and retrieve an employee with its related project objects.


...
PrimaryIndex<String, Employee> empByID;
PrimaryIndex<Long, Project> projByID;
empByID = store.getPrimaryIndex(String.class, Employee.class);
projByID = store.getPrimaryIndex(Long.class, Project.class);
SecondaryIndex<Long, String, Employee> empsByProject;
empsByProject = store.getSecondaryIndex(empByID, Long.class,
“projects”);
Set<Long> projects = new HashSet<Long>();
Project proj = null;
proj = new Project(“Develop FX”);
projByID.putNoReturn(proj);
projects.add(proj.projID);
proj = new Project(“Develop WS”);
projByID.putNoReturn(proj);
projects.add(proj.projID);
empByID.putNoReturn(new Employee(“u146”, “Shephard”, projects));//
insert
empByID.putNoReturn(new Employee(“u144”, “Locke”, projects));//
insert
EntityIndex projs = empsByProject.subIndex(proj.
projID);
EntityCursor<Employee> pcur = projs.entities();
for (Employee entity : pcur) {
   //process the employees
}
EntityCursor<Employee> emplRange = empByID.entities(“e146”, true,
“u148”, true);
for (Employee entity : emplRange) {
   //process the employees
}
emplRange.close();
pcur.close();
store.close();
dbEnv.close();

The Environment and EntityStore definitions are omitted. The SecondaryIndex provides primary methods for retrieving objects related to the Secondary Key of a particular object. The SecondaryIndex can be used to retrieve the related objects through a traversable cursor. We can also use SecondaryIndex to query for a specific range of objects in a given range for its primary key.

Table 9: Supported Object Relation
Relation Description
ONE_TO_ONE A single entity is related to a single secondary key value.
ONE_TO_MANY A single entity is related to one or more secondary key values.
MANY_TO_ONE One or more entities are related to a single secondary key value.
MANY_TO_MANYOne or more entities are related to one or more secondary key values.

A SecondaryIndex can be used to traverse over the collection of secondary key’s values to retrieve the secondary objects.

Hot Tip

Multiple processes can open a database as long as only one process opens it in read-write mode and other processes open the database in read-only mode. The readonly processes get an open-time snapshot of the database and won’t see any changes coming from other process.

BDB JE Collections API

The only different between using BDB JE collections API and classic collections is the fact that when we use BDB JE Collections API we are accessing persisted objects instead of in-memory objects which we usually access in classic collection APIs.

The Collections API Characteristics
An implementation Map, SortedMap, Set, SortedSet, and Iterator.
To stay compatible with Java Collections, Transaction is supported using TransactionWorker and TransactionRunner which the former one is the interface which we can implement to execute our code in a transaction and later one process the transaction.
Keys and values are represented as Java objects. Custom binding can be defined to bind the stored bytes to any type or format like XML, for example.
Data binding should be defined to instruct the Collections API about how keys and values are represented as stored data and how stored data is converted to and from Java objects. We can use one of the two (SerialBinding, TupleBinding) default data bindings or a custom data binding.
Environment, EnvironmentConfig, Database and DatabaseConfig stay the same as it was for Base API.
Collections API extends Java serialization to store class description separately to make data records much more compact.

To get a real sense about BDB JE Collections API think of it as we can persist and retrieve objects using a collection class like SortedMap’s methods like tailMap, subMap or put, putall, get, and so on.

But before we use the SortedMap object to access the stored data, we need to initialize the base objects like Database and Environment; we should create the ClassCatalog object, and finally we should define bindings for our key and value types.

Collections API sample

Now let’s see how we can store and retrieve our our objects using Collections API. In this sample we are persisting a pair of Integer key and String value using SortedMap.

First lets analyze the TransactionWorker implementation.


public class TransWorker implements TransactionWorker {
	private ClassCatalog catalog;
	private Database db;
	private SortedMap map;
	public TransWorker(Environment env) throws Exception {
	   DatabaseConfig dbConfig = new DatabaseConfig();
	   dbConfig.setTransactional(true);
	   dbConfig.setAllowCreate(true);
   Database catalogDb = env.openDatabase(null, “catalog”, dbConfig);
	   catalog = new StoredClassCatalog(catalogDb);
	   // use Integer tuple binding for key entries
	   TupleBinding keyBinding =
              TupleBinding.getPrimitiveBinding(Integer.class);
	   // use String serial binding for data entries
	 SerialBinding dataBinding = new SerialBinding(catalog,
String.class);
	 db = env.openDatabase(null, “dben-col”, dbConfig);
	 map = new StoredSortedMap(db, keyBinding, dataBinding,
true);
    }
    /** Performs work within a transaction. */
    public void doWork() throws Exception {
	   // check for existing data and writing
	   Integer key = new Integer(0);
	   String val = (String) map.get(key);
	   if (val == null) {
           map.put(new Integer(10), “Second”);
     }
     //Reading Data
    Iterator iter = map.entrySet().iterator();
       while (iter.hasNext()) {
          Map.Entry entry = (Map.Entry) iter.next();
          //Process the entry
    }
  }
}

TransWorker implements TransactionWorker which makes it necessary to implement the doWork method. This method is called by TransactionRunner when we pass an object of TransWorker to its run method. The TransWorker constructor simply receive an Environment object and construct other required objects . Then it opens the database in Collection mode, creates the required binding for the key and values we want to store in the database and finally it creates the SortedMap object which we can use to put and retrieve objects using it. Now let’s see the driver code which put this class in action.


public class CollectionSample {
   public static void main(String[] argv)
		throws Exception {
		// Creating the environment
		EnvironmentConfig envConfig = new EnvironmentConfig();
		envConfig.setTransactional(true);
		envConfig.setAllowCreate(true);
		Environment dbEnv = new Environment(new File(“/home/
masoud/dben-col”), envConfig);
		// creating an instance of our TransactionWorker
		TransWorker worker = new TransWorker(dbEnv);
		TransactionRunner runner = new TransactionRunner(dbEnv);
           runner.run(worker);
	}
}

The steps demonstrated in the CollectionSample are self describing. The only new object in this snippet is the TransactionRunner object which we used to run the TransWorker object. I omit many of the safe programming portions to keep the code simple and conscious. we need exception handling and properly closure of all BDB JE objects to ensure data integrity

BDB JE Backup/Recovery and Tuning

Backup and Recovery

We can simply backup the BDB databases by creating an operating system level copy of all jdb files. When required we can put the archived files back into the environment directory to get a database back to the state it was at. The best option is to make sure all transactions and the write process are finished to have a consistent backup of the database.

The BDB JE provides a helper class located at com.sleepycat. je.util.DbBackup to perform the backup process from within a Java application. This utility class can create an incremental backup of a database and later on can restore from that backup. The helper class ideally freezes the BDB JE activities during the backup to ensure that the created backup exactly represents the database state when the backup process started.

Tuning

Berkeley DB JE has 3 daemon threads and configuring these threads affects the overall application performance and behavior. These 3 threads are as follow:

Cleaner Thread Responsible for cleaning and deleting unused log files. This thread is run only if the environment is opened for write access.
Checkpointer Thread Basically keeps the BTree shape consistent. Checkpointer thread is triggered when environment opens, environment closes, and database log file grows by some certain amount.
Compressor Thread For cleaning the BTree structure from unused nodes.

These threads can be configured through a properties file named je.properties or by using the EnvironmentConfig and EnvironmentMutableConfig objects. The je.properties file, which is a simple key-value file, should be placed inside the environment directory and override any further configuration which we may make using the EnvironmentConfig and EnvironmentMutableConfig in the Java code.

The other performance effective factor is cache size. For ondisk instances cache size determines how often the application needs to refer to permanent storage in order to retrieve some data bucket. When we use in-memory instances cache size determines whether our database information will be paged into swap space or it will stay in the main memory.

je.cleaner.minUtilization Ensures that a minimum amount of space is occupied by live records by removing obsolete records. Default occupied percentage is 50%.
je.cleaner.expunge Determines the cleaner behavior in the event that it is able to remove an entire log file. If “true” the log file will be deleted, otherwise it will be renamed to nnnnnnnn.del
je.checkpointer.bytesInterval Determines how often the Checkpointer should check the BTree structure. If it performs the checks little by little it will ensure a faster application startup but will consume more resources specially IO.
je.maxMemory Percent Determines what percentage of JVM maximum memory size can be used for BDB JE cache. To determine the ideal cache size we should put the application in the production environment and monitor its behavior.

A complete list of all configurable properties, with explanations, is available in EnvironmentConfig Javadoc. The list is comprehensive and allows us to configure the BDB JE at granular level.

All of these parameters can be set from Java code using the EnvironmentConfig object. The properties file overrides the values set by using EnvironmentConfig object.

Helper Utilities

Three command line utilities are provided to facilitate dumping the databases from one environment, verifying the database structure, and loading the dump into another environment.

DbDump Dumps a database to a user-readable format.
DbLoad Loads a database from the DbDump output.
DbVerify Verifies the structure of a database.

To run each of these utilities, switch to BDB JE directory, switch to lib directory and execute as shown in the following command:


java -cp je-3.3.75.jar com.sleepycat.je.util.DbVerify

The JAR file name may differ depending on your version of BDB JE. These commands can also be used to port a BDB JE database to BDB Core Edition.

Hot Tip

A very good set of tutorials for different set of BDB JE APIs are available inside the docs folder of BDB JE package. Several examples for different set of functionalities are provided inside the examples directory of the BDB JE package.

About The Author

Photo of Masoud Kalali

Masoud Kalali

Masoud Kalali holds a software engineering degree and has been working on software development projects since 1998. He has experience with a variety of technologies (.Net, J2EE, CORBA, and COM+) on diverse platforms (Solaris, Linux, and Windows). His experience is in software architecture, design and server side development. Masoud has several articles in Java.net. He is one of founder members of NetBeans Dream Team. Masoud’s main area of research and interest includes Web Services and Service Oriented Architecture along with large scale and high throughput systems' development and deployment.

Blog: http://weblogs.java.net/blog/kalali/

Contact: Kalali@gmail.com

Recommended Book

Oracle Berkeley DB

The Berkeley DB Book is a practical guide to the intricacies of the Berkeley DB. This book covers in-depth the complex design issues that are mostly only touched on in terse footnotes within the dense Berkeley DB reference manual. It explains the technology at a higher level and also covers the internals, providing generous code and design examples.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Application Performance Testing: From Conception to Gravestone

0 replies - 1285 views - 12/05/11 by Brandon Nokes in Whitepapers

Why Load Testing From The Cloud Doesn't Work

0 replies - 1241 views - 12/05/11 by Brandon Nokes in Whitepapers

Web Load Testing is Good Business

0 replies - 1291 views - 12/05/11 by Brandon Nokes in Whitepapers

Big Data Analytics: Better, Faster, Smarter... (Europe)

Data is exploding in this age of machine-generated data. IT and business users alike are finding that traditional database can't cope with the volume - causing slow reports or the need to analyze less data at any one time.. Join Jeff Kibler, Community...

0 replies - 1047 views - 11/04/11 by Brandon Nokes in Uncategorized

Big Data Analytics: Better, Faster, Smarter... (US/Canada)

Data is exploding in this age of machine-generated data. IT and business users alike are finding that traditional database can't cope with the volume - causing slow reports or the need to analyze less data at any one time.. Join Jeff Kibler, Community...

0 replies - 953 views - 11/04/11 by Brandon Nokes in Uncategorized

Getting Started with Apache Wicket

By Andrew Lombardi

13,855 Downloads · Refcard 63 of 151 (see them all)

Download
FREE PDF


The Essential Apache Wicket Cheat Sheet

Apache Wicket is a Java-based web application framework that has rapidly grown to be a favorite among many developers. Among the dizzying number of Web frameworks available today, Wicket’s simple and intuitive approach to Web development has led it to become a favorite among many Java developers. This DZone Refcard brings you quickly up to speed on some of the key features of Apache Wicket 1.3, showing you how to configure the framework, define your domain model, create standard Wicket components and add internationalization options.
HTML Preview
Getting Started with Apache Wicket

Getting Started with Apache Wicket

By Andrew Lombardi

About Apache Wicket

Apache Wicket is a Java-based web application framework that has rapidly grown to be a favorite among many developers. It features a POJO data model, no XML, and a proper mark-up / logic separation not seen in most frameworks. Apache Wicket gives you a simple framework for creating powerful, reusable components and offers an object oriented methodology to web development while requiring only Java and HTML. This Refcard covers Apache Wicket 1.3 and describes common configuration, models, the standard components, implementation of a form, the markup and internationalization options available.

Project Layout

The project layout most typical of Apache Wicket applications is based on the default Maven directories. Any Wicket component that requires view markup in the form of HTML needs to be side-by-side with the Java file. Using Maven however, we can separate the source directories into java/ and resources/ to give some distinction. To get started, download either the wicket-quickstart project and modify it to your needs, or use the maven archetype here:


mvn archetype:create \
-DarchetypeGroupId=org.apache.wicket \
-DarchetypeArtifactId=wicket-archetype-quickstart \
-DarchetypeVersion=1.3.5 \
-DgroupId=com.mysticcoders.refcardmaker \
-DartifactId=refcardmaker

Either way, if using Maven, you’ll need the wicket jar, and the latest slf4j jar.


<dependency>
  <groupId>org.apache.wicket</groupId>
  <artifactId>wicket</artifactId>
  <version>1.3.6</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.4.2</version>
</dependency>

Configuring the web application

I mentioned that Wicket has no XML, and that’s mostly true, but J2EE requires a web.xml file to do anything. We set up the WicketFilter and point it to our implementation of WebApplication along with the URL mapping.


<web-app>
  <filter>
    <filter-name>wicketFilter</filter-name>
    <filter-class>org.apache.wicket.protocol.http.
WicketFilter</filter-class>


<init-param>
      <param-name>applicationClassName</param-name>
      <param-value>com.mysticcoders.refcardmaker.
RefcardApplication</param-value>
    </init-param>
    <init-param>
      <param-name>filterPath</param-name>
      <param-value>/*</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>wicketFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

Apache Wicket offers a development and deployment mode that can be configured in the web.xml file:


<context-param>
	<param-name>configuration</param-name>
	<param-value>development</param-value>
</context-param>

Hot Tip

Depending on your configuration needs, you can set this parameter in the web.xml as either:
  • a context-param or init-param to the filter
  • a command line parameter wicket.configuration
  • by overriding Application.getConfigurationType()

Models

Apache Wicket uses models to separate the domain layer from the view layer in your application and to bind them together. Components can retrieve data from their model, and convert and store data in the model upon receiving an event. There are a variety of implementations of Model, and they all extend from the interface IModel.

IModel

There are only two methods that a class would have to implement to be a Model, and that is getObject and setObject. getObject returns the value from the model, and setObject sets the value of the model. Your particular implementation of IModel can get data from wherever you’d like; the Component in the end only requires the ability to get and set the value. Every component in Wicket has a Model: some use it, some don’t, but it’s always there.

PropertyModel

A model contains a domain object, and it’s common practice to follow JavaBean conventions. The PropertyModel allows you to use a property expression to access a property in your domain object. For instance if you had a model containing Person and it had a getter/setter for firstName to access this property, you would pass the String “firstName” to that Model.

CompoundPropertyModel

An even fancier way of using models is the CompoundPropertyModel. Since most of the time, the property identifier you would give Wicket mimics that of the JavaBean property, this Model takes that implied association and makes it work for you.


...
setModel(new CompoundPropertyModel(person));
add(new Label(“firstName”));
add(new Label(“lastName”));
add(new Label(“address.address1”));
...

We can see from the example above, that if we set the model with the person object using a CompoundPropertyModel, the corresponding components added to this parent Component will use the component identifiers as the property expression.

IDetachable

In order to keep domain objects around, you’re either going to need a lot of memory / disk space, or devise a method to minimize what gets serialized in session. The detachable design helps you do this with minimal effort. Simply store as little as needed to reconstruct the domain object, and within the detach method that your Model overrides, null out the rest.

LoadableDetachableModel

In order to make things easier, LoadableDetachableModel implements a very common use case for detachable models. It gives you the ability to override a few constructors and a load method, and provides automatic reattach and detach within Wicket’s lifecycle. Let’s look at an example:


public class LoadableRefcardModel extends LoadableDetachableModel
{
	private Long id;
	public LoadableRefcardModel(Refcard refcard) {
	  super(refcard);
	  id = refcard.getId();
	}
	public LoadableRefcardModel(Long id) {
	  super();
      this.id = id;
	}
	protected Object load() {
      if(id == null) return new Refcard();
      RefcardDao dao = ...
      return dao.get(id);
    }
}

Here we have two constructors, each grabbing the identifier and storing it with the Model. We also override the load method so that we can either return a newly created Object, or use an access object to return the Object associated with the Model’s stored identifier. LoadableDetachableModel handles the process of attaching and detaching the Object properly giving us as little overhead as possible.

Components

In Wicket, Components display data and can react to events from the end user. In terms of the Model-View-Controller pattern, a Component is the View and the Controller. The following three distinct items make up every Wicket Component in some way:

  • Java Class implementation – defines the behavior and responsibilities
  • HTML Markup – defines the Components using their identifiers within view markup to determine where it shows to the end user
  • The Model – provides data to the Component

Now that we have an idea about what makes up a Component, let’s look at a few of the building blocks that make up the majority of our Pages. Forms and their Components are so important they have their own section.

Label

When developing your application, if you’d like to show text on the frontend chances are pretty good that you’ll be using the Label Component. A Label contains a Model object which it will convert to a String for display on the frontend.


<span wicket:id=”message”>[message]</span>
...
add(new Label(“message”, “Hello, World!”));

The first portion is an HTML template, which gives a component identifier of “message” which must be matched in the Java code. The Java code passes the component identifier as the first parameter.

Link

Below is a list of the different types of links, bookmarkable and non-bookmarkable, and how they are used to navigate from page-to-page.

Name Description
Link

If linking to another Page, it is best to use a Link in most instances:
add(new Link(“myLink”) {
    public void onClick() {
      setResponsePage(MyNewPage.class);
  }
}

BookmarkablePageLink A Bookmarkable page gives you a human readable URL that can be linked to directly from outside of the application. The default look of this URL can be overridden as we’ll see in the next section. add(new BookmarkablePageLink(“myLink”, MyNewPage.class);
ExternalLink If linking to an external website that is not within your application, here’s the Link component you’ll need and an example: add(new ExternalLink(“myLink”, http://www. mysticcoders.com, “Mystic”);

Repeaters

Due to the lack of any executable code inside of Wicket’s HTML templates, the method of showing lists may seem a little counterintuitive at first. One of the simplest methods for showing a list of data is the RepeatingView. Here’s an example of how to use it:


<ul>
    <li wicket:id=”list”></li>
</ul>
...
RepeatingView list = new RepeatingView(“list”);
add(list);
for(int i = 1; i <= 10; i++) {
    list.add(new Label(list.newChildId(), “Item “ + i));
}

This will simply print out a list from 1 to 10 into HTML. RepeatingView provides a method .newChildId() which should be used to ensure the Component identifier is unique. As your needs get more complex, this method quickly turns stale as there is a lot of setup that has to be done. Using a ListView is a great approach for managing possibly complex markup and business logic, and is more akin to other ways we’re asked to interact with Apache Wicket:


<ul>
   <li wicket:id=”list”><span wicket:id=”description”>[descripti
on]</li>
</ul>
...
ListView list = new ListView(“list”, Arrays.asList(“1”, “2”, “3”,
“4”, “5”, “6”, “7”, “8”, “9”, “10”) {
   @Override
   protected void populateItem(ListItem item) {
      String text = (String)item.getModelObject();
      item.add(new Label(“description”, text));
   }
};
add(list);

This method, while it looks more complex, allows us a lot more flexibility in building our lists to show to the user. The two list approaches described above each suffer from some drawbacks, one of which is that the entirety of the list must be held in memory. This doesn’t work well for large data sets, so if you need finer grain control on how much data is kept in memory, paging, etc., DataTable or DataView is something to look into.

Custom

The beauty of Wicket is that reuse is as simple as putting together a Panel of Components and adding it to any number of pages – this could be a login module, a cart, or whatever you think needs to be reused. For more great examples of reusable components check out the wicket-extensions (http://cwiki.apache.org/Wicket/wicket-extensions.html) and wicket-stuff (http:..wicketstuff.org) projects.

Hot Tip

Since Wicket always needs a tag to bind to, even for a label, a tag is sometimes easier to place into your markup; however, this can throw your CSS design off. .setRenderBodyOnly(true) can be used so the span never shows on the frontend but be careful using this with any AJAX enabled components, since it requires the tag to stick around.

Page and navigation

A Wicket Page is a component that allows you to group components together that make up your view. All Components will be related in a tree hierarchy to your page, and if the page is bookmarkable you can navigate directly to it. Tocreate a new page, simply extend WebPage and start adding components.

Most webapps will share common areas that you don’t want to duplicate on every page -- this is where markup inheritance comes into play. Because every page is just a component, you can extend from a base page and inherit things like header, navigation, footer, whatever fits your requirements. Here’s an example:


public class BasePage extends WebPage {
   ... header, footer, navigation, etc ...
}
public class HomePage extends BasePage {
... everything else, the content of your pages...
}

Everything is done similarly to how you would do it in Java, without the need for messy configuration files. If we need to offer up pages that can be referenced and copied, we’re going to need to utilize bookmarkable pages. The default Wicket implementation of a BookmarkablePage is not exactly easy to memorize, so in your custom Application class you can define several mount points for your pages:


// when a user goes to /about they will get directly to this page
mountBookmarkablePage(“/about”, AboutPage.class);
// this mount makes page available at /blog/param0/param1/param2 and fills PageParameters with 0-indexed numbers as the key mount(new IndexedParamUrlCodingStrategy(“/blog”, BlogPage.class);
// this mount makes page available at /blog?paramKey=paramValue&pa ramKey2=paramValue2 mount(new QueryStringUrlCodingStrategy(“/blog”, BlogPage.class);

In your code, you’ll need several ways of navigating to pages, including within Link implementations, in Form onSubmits, and for an innumerable number of reasons. Here are a few of the more useful:


// Redirect to MyPage.class
setResponsePage(MyPage.class);
// Useful to immediately interrupt request processing to perform a redirect throw new RestartResponseException(MyPage.class);
// Redirect to an interim page such as a login page, keep the URL in memory so page can call continueToOriginalDestination() redirectToInterceptPage(LoginPage.class);
// Useful to immediately interrupt request processing to perform a redirectToInterceptPage call throw new RestartResponseAtInterceptPageException(MyPage.class);

Markup

Apache Wicket does require adding some attributes and tags to otherwise pristine X/HTML pages to achieve binding with Component code. The following table illustrates the attributes available to use in your X/HTML templates, the most important and often used being wicket:id.

Attribute Name Description
wicket:id Used on any X/HTML element you want to bind a compoent to
wicket:message Used on any tag we want to fill an attribute with a resource bundle value. To use, prefix with te [attributename]:[resource name]

The following table lists out all of the most commonly used tags in X/HTML templates with Wicket.

Tag Name Description
wicket:panel

This tag is used in your template to define the area associatedf with
the component. Anything outside of this tag’s hierarchy will be
ignored. It is sometimes useful to wrap each of your templates with
html and body tags like so:
<html xmlns:wicket=”http://wicket.apache.org”>
<body>
<wicket:panel> ... </wicket:panel>
</body>
</html>
In this example, you can avoid errors showing in your IDE, and it
won’t affect the resulting HTML.

wicket:child Used in conjunction with markup inheritance. The subclassing Page will replace the tag with the output of its component
wicket:extend Defining a page that inherits from a parent Page requires a mirroring of the relationship in your X/HTML template. As with wicket:panel, everything outside of the tag’s hierarchy will be ignored, and the component’s result will end up in the wrapping template
wicket:link

Using this tag enables autolinking to another page without having
to add BookmarkablePageLink’s to the component hierarchy as this
is done automatically for you. To link to the homepage from one of
its subpages:
<wicket:link><a href=”Homepage.html”>Homepage</
a></wicket:link></td>

wicket:head Adding this to the root-level hierarchy of the template will give you access to inject code into the X/HTML <head></head> section.
wicket:message This tag will look for the given key in the resource bundle component hierarchy and replace the tag with the String retrieved from that bundle property. To pull the resource property page.label: <wicket:message key=”page.label”>[page label]</ wicket:message>
wicket:remove The entire contents of this tag will be removed upon running this code in the container. Its use is to ensure that the template can show design intentions such as repeated content without interfering with the resulting markup.
wicket:fragment A fragment is an inline Panel. Using a Panel requires a separate markup file, and with a fragment this block can be contained within the parent component.
wicket:enclosure A convenience tag added in 1.3 that defines a block of code surrounding your component which derives its entire visibility from the enclosing component. This is useful in situations when showing multiple fields some of which may be empty or null where you don’t want to add WebMarkupContainers to every field just to mimic this behavior. For example if we were printing out phone and fax: <wicket:enclosure> <tr><td class=”label”>Fax:</td><td><span wicket:id=”fax”>[fax number]</span></td></tr> </wicket:enclosure> ... add(new Label(“fax”) { public boolean isVisible() { return getModelObjectAsString()!=null; } } );
wicket:container

This tag is useful when you don’t want to render any tags into the
markup because it may cause invalid markup. Consider the following:
<table>
  <wicket:container wicket:id=”repeater”>
    <tr><td>1</td></tr>
    <tr><td>2</td></tr>
  </wicket:container>
</table>
In this instance, if we were to add any code in between the table and
tr tags, it would be invalid. Wicket:container fixes that

.

Form

A Form in Wicket is a component that takes user input and processes it upon submission. This component is a logical holder of one or more input fields that get processed together. The Form component, like all others, must be bound to an HTML equivalent, in this case the <form> tag.


<form wicket:id=”form”>
	Name: <input type=”text” wicket:id=”name” />
	<input type=”submit” value=”Send” />
</form>
...
Form form = new Form(“form”) {
   @Override
     protected void onSubmit() {


  System.out.println(“form submit”);
   }
};
add(form);
form.add(new TextField(“name”, new Model(“”));

Form input controls can each have their own Models attached to them, or can inherit from their parent, the Form. This is usually a good place to use CompoundPropertyModel as it gets rid of a lot of duplicate code. As you can see, each input component should be added to the Form element.

Wicket uses a POST to submit your form, which can be changed by overriding the Form’s getMethod and returning Form.METHOD_GET. Wicket also uses a redirect to buffer implementation details of form posts which gets around the form repost popup. The following behavior settings can be changed:

Name Setting Description
No redirect IRequestCycleSettings.ONE_PASS_RENDER Renders the response directly
Redirect to buffer IRequestCycleSettings.REDIRECT_BUFFER Renders the response directly to a buffer, redirects the browser and prevents reposting the form
Redirect to render IRequestCycleSettings. REDIRECT_TO_RENDER Redirects the browser directly; renders in a separate request

Components of a Form

The following table lists all the different form components available, and how to use them with Models.

Name Example
TextField

<input type=”text” wicket:id=”firstName” />
...
add(new TextField(“firstName”, new
PropertyModel(person, “firstName”));

TextArea

<textarea wicket:id=”comment”></textarea>
...
add(new TextArea(“comment”, new
PropertyModel(feedback, “comment”));

Button

<form wicket:id=”form”>
   <input type=”submit” value=”Submit”
wicket:id=”submit” />
</form>
...
Form form = new Form(“form”) {
   @Override
   protected void onSubmit() {
      System.out.println(“onSubmit called”);
   }
};
add(form);
form.add(new Button(“submit”));

CheckBoxMultipleChoice

<span wicket:id=”operatingSystems”>
   <input type=”checkbox” /> Windows
<input type=”checkbox” /> OS/2 Warp
</span> ... add(new CheckBoxMultipleChoice(“operat ingSystems”, new PropertyModel(system, “operatingSystems”), Arrays.asList(“Windows”, “OS X”, “Linux”, “Solaris”, “HP/UX”, “DOS”)));
DropDownChoice

<select wicket:id=”states”>
   <option>[state]</option>
</select>
...
add(new DropDownChoice(“states”, new
PropertyModel(address, “state”),
listOfStates));

PasswordTextField

<input type=”password” wicket:id=”password”
/>
...
add(new PasswordTextField(“password”, new
PropertyModel(user, “password”));

RadioChoice

<span wicket:id=”gender”>
	<input type=”radio” /> Male<br />
	<input type=”radio” /> Female</br />
</span>
...
add(new RadioChoice(“sex”, new
PropertyModel(person, “gender”), Arrays.
asList(“Male”, “Female”));

SubmitLink

<form wicket:id=”form”>
   <a href=”#”
wicket:id=”submitLink”>Submit</a>
</form>
...
form.add(new SubmitLink(“submitLink”) {
	@Override
	public void onSubmit() {
System.out.println(“submitLink
called”);
	}
});</td>
	</tr>

Validation

When dealing with user input, we need to validate it against what we’re expecting, and guide the user in the right direction if they stray. Any user input is processed through this flow:

  • Check that the required input is supplied
  • Convert input values from String to the expected type
  • Validate input using registered validators
  • Push converted and validated input to models
  • Call onSubmit or onError depending on the result

Wicket provides the following set of validators:

Resource Key Example
Required textField.setRequired(true)
RangeValidator.range numField.add(RangeValidator.range(0,10))
MinimumValidator.minimum numField.add(MinimumValidator.minimum(0))
MaximumValidator.maximum numField.add(MaximumValidator.maximum(0))
StringValidator.exact textField.add(StringValidator.exact(8))
StringValidator.range textField.add(StringValidator.range(6,18))
StringValidator.maximum textField.add(StringValidator.maximum(8))
StringValidator.minimum textField.add(StringValidator.minimum(2))
DateValidator.range dateField.add(DateValidator.range(startDate, endDate))
DateValidator.minimum dateField.add(DateValidator.minimum(minDate))
DateValidator.maximum dateField.add(DateValidator.maximum(maxDate))
CreditCardValidator ccField.add(new CreditCardValidator())
PatternValidator textFIeld.add(new PatternValidator(“\d+”)
EmailAddressValidator emailField.add(EmailAddressValidator.getInstance())
UrlValidator urlField.add(new UrlValidator())
EqualInputValidator add(new EqualInputValidator(formComp1,formComp2))
EqualPasswordInputValidator Add(new EqualPasswordInputValidator(passFld1, passFld2))

More than one validator can be added to a component if needed. For instance, if you have a password that needs to be within the range of 6 – 20 characters, must be alphanumeric and is required, simply chain the needed validators above to your component. If the validators listed above don’t fit your needs, Wicket lets you create your own and apply them to your components.


public class PostalCodeValidator extends AbstractValidator {
	public PostalCodeValidator() {
	}
	@Override
	protected void onValidate(IValidatable validatable) {
	  String value = (String)validatable.getValue();
	  if(!postalCodeService.isValid(value)) {
	    error(validatable);
	  }
	}
	@Override
	protected String resourceKey() {
	  return “PostalCodeValidator”;
	}
	@Override
	protected Map variablesMap(IValidatable validatable) {
	  Map map = super.variablesMap(validatable);
	  map.put(“postalCode”, n);
	  return map;
	}
}

When Wicket has completed processing all input it will either pass control to the Form’s onSubmit, or the Form’s onError..If you don’t choose to override onError, you’ll need a way to customize the error messages that show up.

Feedback Messages

Apache Wicket offers a facility to send back messages for failed validations or flash messages to provide notification of status after submitting a form or performing some action. Wicket’s validators come with a default set of feedback messages in a variety of languages, which you can override in your own properties files. Here’s the order Wicket uses to grab messages out of resource bundles:

Location Order Description Example
Page class 1 Messages Specific to a page Index.properties Index_es.properties
Component class 2 Messages specific to a component AddressPanel_es.properties CheckOutForm.properties
Custom Application class 3 Default application-wide message bundle

RefcardApplication_es_
MX.properties
RefcardApplication_
es.properties
RefcardApplication.
properties

During a Form submission, if you’d like to pass back messages to the end user, Wicket has a message queue that you can access with any component:


info(“Info message”);
warn(“Warn message”);
error(“Error message”);

With that added to the queue, the most basic method of showing these to users is to use the FeedbackPanel component which you can add to your Page as follows:


<div wicket:id=”feedback”></div>
…
add(new FeedbackPanel(“feedback”));

When you’d like to get them back out again, it will give you an Iterator to cycle through on the subsequent page:


getSession().getFeedbackMessages().iterator();

Internationalization

Earlier sections touched on the order of resource bundles importance from the Page down to Wicket’s default application. Apache Wicket uses the same resource bundles standard in the Java platform, including the naming convention, properties file or XML file.

Using ResourceBundles, you can pull out messages in your markup using , or use a ResourceModel with the component to pull out the localized text.

Another available option is to directly localize the filename of the markup files, i.e. HomePage_es_MX.html, HomePage.html. Your default locale will be used for HomePage.html, and if you were from Mexico, Wicket would dutifully grab HomePage_es_ MX.html.

Hot Tip

Wicket’s Label component overrides the getModelObjectAsString of Component to offer you Localaware String’s output to the client, so you don’t have to create your own custom converter.
Resources
Wicket 1.3 Homepage http://wicket.apache.org/
Component Reference http://wicketstuff.org/wicket13/compref/
Wicket Wiki http://cwiki.apache.org/WICKET/
Wicket by Example http://wicketbyexample.com/

About The Author

Photo of Andrew Lombardi

Andrew Lombardi

is one of a new breed of businessmen: the enlightened entrepreneur. He has been writing code since he was a 5-year old, sitting at his dad’s knee at their Apple II computer. Having such a deep affinity for the computer model, it is no surprise that at the age of 17 he began to delve deeply into the inner workings of the human mind. He became a student of Neuro Linguistic Programming and other mind technologies, and then went on to study metaphysics. He is certified as an NLP Trainer, Master Hypnotherapist and Time Line Therapy practitioner.

Using all of his accumulated skills, at the age of 24, Andrew began his consulting business, Mystic Coders, LLC. Since the inception of Mystic in 2000, Andrew has been building the business and studying finance and economics as he stays on the cutting edge of computer technology.

Recommended Book

Wicket in action

Wicket in Action is an authoritative, comprehensive guide for Java developers building Wicketbased Web applications. This book starts with an introduction to Wicket’s structure and components, and moves quickly into examples of Wicket at work. Written by two of the project’s earliest and most authoritative experts, this book shows you both the “how-to” and the “why” of Wicket. As you move through the book, you’ll learn to use and customize Wicket components, how to interact with other technologies like Spring and Hibernate, and how to build rich, Ajax-driven features into your applications.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Vaadin

A Familiar Way to Build Web Apps with Java

By Marko Grönroos

12,598 Downloads · Refcard 85 of 151 (see them all)

Download
FREE PDF


The Essential Vaadin Cheat Sheet

Vaadin is a server-side Ajax web application development framework that allows you to build web applications just as you would with traditional desktop frameworks, such as AWT or Swing. An application is built from user interface components contained hierarchically in layout components. In the server-driven model, the application code runs on a server, which the actual user interaction is handled by a client-side engine running in the browser. This DZone Refcard will cover how to create an application, components, themes, data binding, and more.
HTML Preview
Getting Started with Vaadin

Vaadin: A Familiar Way to Build Web Apps with Java

By Marko Grnroos

ABOUT VAADIN

Vaadin is a server-side Ajax web application development framework that allows you to build web applications just like with traditional desktop frameworks, such as AWT or Swing. An application is built from user interface components contained hierarchically in layout components.

In the server-driven model, the application code runs on a server, while the actual user interaction is handled by a client-side engine running in the browser. The client-server communications and any client-side technologies, such as HTML and JavaScript, are invisible to the developer. As the client-side engine runs as JavaScript in the browser, there is no need to install plug-ins. Vaadin is released under the Apache License 2.0.

Client-Server Architecture

Figure 1: Vaadin Client-Server Architecture

If the built-in selection of components is not enough, you can develop new components with the Google Web Toolkit (GWT) in Java.

CREATING AN APPLICATION

An application that uses the Vaadin framework needs to inherit the com.vaadin.Application class and implement the init() method.


import com.vaadin.ui.*;

public class HelloWorld extends com.vaadin.Application {
	public void init() {
		Window main = new Window(“Hello window”);
		setMainWindow(main);
		main.addComponent(new Label(“Hello World!”));
	}
}

The basic tasks in writing an application class and the initialization method are:

  • inherit the Application class
  • create and set a main window
  • populate the window with initial components
  • define event listeners to implement the UI logic

Optionally, you can also:

  • set a custom theme for the window
  • bind components to data
  • bind components to resources

The application can change the components and the layout dynamically according to the user input.

Architecture for Vaadin Applications

Figure 2: Architecture for Vaadin Applications


You can get a reference to the application object from any component attached to the application with getApplication()

Event Listeners

In the event-driven model, user interaction with user interface components triggers server-side events, which you can handle with event listeners.

In the example below, we handle click events for a button with an anonymous class:


Button button = new Button(“Click Me!”);
button.addListener(new Button.ClickListener() {
	public void buttonClick(ClickEvent event) {
		getWindow().showNotification(“Thank You!”);
	}
});

Download Vaadin

Below is a list of the most important event interfaces; their corresponding listener interfaces are named -Listener.

Event Interface Description
Property.ValueChangeEvent Field components except Button
Button.ClickEvent Button click
Window.CloseEvent A sub-window or an application-level window has been closed

Unless the immediate property (see below) is set, value change events are not communicated immediately to the server-side when the user changes the values, but are delayed until the first immediate interaction. Certain events, such as button clicks, are immediate by default.

Deployment

To deploy an application as a servlet, you must define a WEB-INF/web.xml deployment descriptor. The application class must be defined in the application parameter.


<web-app>
	<display-name>myproject
	
	<servlet>
		<servlet-name>Myproject Application
		<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet
		</servlet-class>
		<init-param>
			<description>Vaadin application class to start
			<param-name>application
			<param-value>com.example.myproject.HelloWorld
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>Myproject Application
		<url-pattern>/*
	</servlet-mapping>
</web-app>

COMPONENTS

Vaadin components include field, layout, and other components. The component classes and their inheritance hierarchy are illustrated in Figure 4 (page 3).

Component Properties

Common component properties are defined in the Component interface and the AbstractComponent base class for all components.

Property Description
caption A label that identifies the component for the user, usually shown above, left of, or inside a component, depending on the component and the containing layout.
description A longer description usually displayed as a tooltip when mouse hovers over the component.
enabled If false, the user can not interact with the component. The component is shown as grayed. (Default: true)
icon An icon for the component, usually shown left of the caption.
immediate If true, value changes are communicated immediately to the server-side, usually when the selection changes or (a text field) loses input focus. The default is false for most components, but true for Button.
locale The current country and/or language for the component. Meaning and use are application-specific for most components. (Default: application locale)
readOnly If true, the user can not change the value. (Default: false)
visible Whether the component is actually visible or not. (Default: true)

Field Properties

Field properties are defined in the Field interface and the AbstractField base class for fields.

Property Description
required Boolean value stating whether a value for the field is required. (Default: false)
requiredError Error message to be displayed if the field is required but empty. Setting the error message is highly recommended for providing user feedback about a failure.

Sizing

The size of components is defined in the Sizeable interface.

Method Description
setWidth()
setHeight()
Set the component size in either fixed units (px, pt, pc, cm, mm, in, or em) or as a relative percentage (%) of the containing layout. The value "-1" means undefined size (see below).
setSizeFull() Sets both dimensions to 100% relative size of the space given by the containing layout.
setSizeUndefined() Sets both dimensions as undefined, causing the component to shrink to fit the content.

Notice that a layout with an undefined size must not contain a component with a relative (percentual) size.

Validation

All components implementing the Validatable interface, such as all fields, can be validated with validate() or isValid(). You need to implement a Validator and its validate() and isValid() methods, and add the validator to the field with addValidator().

Built-in validators are defined in the com.vaadin.data.validator package and include:

Validator Description
DoubleValidator A floating-point value
EmailValidator An email address
IntegerValidator An integer value
RegexpValidator String that matches a regular expression
StringLengthValidator Length of string is within a range

Resources

Icons, embedded images, hyperlinks, and downloadable files are referenced as resources.


Button button = new Button("Button with an icon");
button.setIcon(new ThemeResource("img/myimage.png"));

The external and theme resources are usually static resources. Application resources are served by the Vaadin application servlet, or by the user application itself.

Resource classes and interfaces

Figure 3: Resource classes and interfaces

Class Name Description
ExternalResource Any URL
ThemeResource A static resource served by the application server from the current theme. The path is relative to the theme folder.
FileResource Loaded from the file system
ClassResource Loaded from the class path
StreamResource Provided dynamically by the application

User Component Classes Class Diagram

Figure 4: The Class Diagram presents all user interface component classes and the most important interfaces, relationships, and methods.

LAYOUT COMPONENTS

The layout of an application is built hierarchically from layout components, or more generally component containers, with the actual interaction components as the leaf nodes of the component tree.

You start by creating a root layout for the main window and set it with setContent(), unless you use the default, and then add the other layout components hierarchically with addComponent().

Margins

The margin of layout components is controlled with the margin property, which you can set with setMargin(). Once enabled, the HTML element of the layout will contain an inner element with <layoutclass>-margin style, for example, v-verticallayoutmargin for a VerticalLayout. You can use the padding property in CSS in a custom theme to set the width of the margin:


.v-verticallayout-margin {
	padding-right: 20px;
	padding-top: 30px;
	padding-bottom: 40px;
}

Spacing

Some layout components allow spacing between the elements. You first need to enable spacing with setSpacing(true), which enables the <layoutclass>-spacing-on style for the layout, for example, v-gridlayout-spacing-on for GridLayout. You can then set the amount of spacing in CSS in a custom theme with the padding-top property for vertical and padding-left for horizontal spacing, for example as follows:


.v-gridlayout-spacing-on {
	padding-left: 50px; /* Horizontal spacing */
	padding-top: 100px; /* Vertical spacing */
}

Alignment

When a layout cell is larger than a contained component, the component can be aligned within the cell with the setComponentAlignment() method as in the example below:


VerticalLayout layout = new VerticalLayout();
Button button = new Button("My Button");
layout.addComponent(button);
layout.setComponentAlignment(button, Alignment.MIDDLE_CENTER);

Custom Layout

The CustomLayout component allows the use of a HTML template that contains location tags for components, such as <div location="hello">. The components are inserted in the location elements with the addComponent() method as shown below:


CustomLayout layout = new CustomLayout("mylayout");
layout.addComponent(new Button("Hello"), "hello");

The layout name in the constructor refers to a corresponding .html file in the layouts subfolder in the theme folder, in the above example layouts/mylayout.html. See Figure 5 for the location of the layout template.

THEMES

Vaadin allows customization of appearance of the user interface with themes. Themes can include CSS style sheets, custom layout HTML templates, and any graphics.

Custom themes are placed under the WebContent/VAADIN/ themes/ folder of the web application. This location is fixed the VAADIN folder specifies that these are static resources specific to Vaadin.

The name of a theme folder defines the name of the theme, to be used for the setTheme() method:


public void init() {
	setTheme("mytheme");
	...

The theme folder must contain the styles.css style sheet and custom layouts must be placed in the layouts sub-folder, but other contents may be named freely.

Custom themes need to inherit a base theme in the beginning of the styles.css file. The default theme for Vaadin 6 is reindeer


@import url(../reindeer/styles.css);

Theme contents

Figure 5: Theme contents

Hot Tip

During development, you can let the built-in themes and the default widget set be loaded dynamically from the Vaadin JAR. For production, it is more efficient to let them be served statically by the web server. You just need to extract the VAADIN folder from the JAR.

DATA BINDING

Vaadin allows binding components directly to data. The data model, illustrated in Figure 4, is based on interfaces on three levels of containment: properties, items, and containers.

Properties

The Property interface provides access to a value of a specific class with the setValue() and getValue() methods.

All field components provide access to their value through the Property interface, and the ability to listen for value changes with a Property.ValueChangeListener. The field components hold their value in an internal data source by default, but you can bind them to any data source with setPropertyDataSource().

For selection components, the property value points to the item identifier of the current selection, or a collection of item identifiers in the multiSelect mode.

The ObjectProperty is a wrapper that allows binding any object to a component as a property.

Items

An item is an ordered collection of properties. The Item interface also associates a name with each property. Common uses of items include Form data and Table rows. You can set the data source of a Form with setItemDataSource().

The BeanItem is a special adapter that allows accessing any Java bean (or POJO with proper setters and getters) through the Item interface. This is especially useful for binding a Form or a Table to beans.

Containers

A container is a collection of items. It allows accessing the items with an item identifier associated with each item.

Common uses of containers include selection components, as defined in the AbstractSelect class, especially the Table and Tree components. (The current selection is indicated by the property of the field, which points to the item identifier of the selected item.) You can set the container data source of a field with setContainerDataSource().

Vaadin includes the following built-in container implementations:

Container Class Description
IndexedContainer Container with integer index keys
BeanItemContainer Container for BeanItems
HierarchicalContainer Tree-like container, used especially by the Tree component
FilesystemContainer Direct access to the file system

Buffering

All field components implement the Buffered interface that allows buffering user input before it is written to the data source. Buffering is enabled by default.

Method Description
commit() Writes the buffered data to the data source
discard() Discards the buffered data and re-reads the data from the data source
set-/getWriteThrough() When the writeThrough property is true, write buffering is disabled
set-/getReadThrough() When the readThrough property is true, read buffering is disabled

CREATING NEW COMPONENTS

Creating a Client-Side Widget

The basic tasks of a client-side component are:

  • Implement the Paintable interface
  • Maintain a reference to the ApplicationConnection object
  • Implement updateFromUIDL() to deserialize state changes from server-side
  • Serialize state changes to server-side with calls to updateVariable()

Creating a Server-Side Component

The basic tasks of a server-side component are:

  • Use @ClientWidget annotation for the server-side component class to bind the component to the client-side counterpart
  • Implement paintContent() to serialize state changes to client-side with addVariable() and addAttribute() calls
  • Implement changeVariables() to deserialize state changes from client-side

TWidget integration

Figure 6: Widget integration within the Vaadin client-server communication architecture

Defining a Widget Set

A widget set is a collection of widgets that, together with the communication framework, form the Client-Side Engine of Vaadin, when compiled with the GWT Compiler into JavaScript.

A widget set is defined in a .gwt.xml GWT Module Descriptor. You need to specify at least one inherited base widget set, typically the DefaultWidgetSet or a custom set.


<module>
	<inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />
</module>

The client-side source files must be located in the client subpackage under the package of the descriptor.

You can associate a stylesheet with a widget set with the <stylesheet> element in the .gwt.xml descriptor:


<stylesheet src="/sites/all/modules/dzone/assets/refcardz/085/colorpicker/styles.css"/>

Widget Project Structure

Widget set source structure

Figure 7: Widget set source structure.

Figure 7 illustrates the source code structure of a widget project (for the Color Picker example).

Using Widget Sets

You can generate the descriptor of a combining widget set automatically with the com.vaadin.terminal.gwt.widgetsetutils. WidgetSetBuilder application. It searches the class path to find all widget sets, including ones packaged in JARs, and generates the required <inherit> elements.

  • Give the full name (including the package name) of the widget set as a parameter. This is the name of the .gwt.xml file without the extension.
  • Give path to the top-level source directory as the first element of the class path

For more information on Vaadin, visit the Vaadin Blog at http://vaadin.com/blog or the Forum at http://vaadin.com/forum

About The Author

Photo of Marko Grnroos

Marko Grnroos

CMarko Grnroos is a professional writer and software developer working at IT Mill Ltd, the company behind Vaadin. He has been involved in web application development since 1994 and has worked on several application development frameworks in C, C++, and Java. He has been active in many open source software projects and holds an M.Sc. degree in Computer Science from the University of Turku. He lives in Turku, Finland.

Website: http://iki.fi/magi

Blog: http://markogronroos.blogspot.com/

Recommended Book

Book of Vaadin

Book of Vaadin is a comprehensive documentation of Vaadin. It shows how to get started, gives a good overview of the features, and tutors you through advanced aspects of the framework.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Getting Started with JBoss Enterprise Application Platform 5

By Scott Marlow, Jaikiran Pai, Shelly McGowan, Brian Stansberry and Len DiMaggio

15,337 Downloads · Refcard 97 of 151 (see them all)

Download
FREE PDF


The Essential JBoss EAP 5 Cheat Sheet

JBoss Enterprise Application Platform 5 is an open source implementation of the Java EE suite of services. This DZone Refcard provides an in-depth introduction to JBoss Enterprise Application Platform 5. It comprises a set of offerings for enterprise customers who are looking for preconfigured profiles of JBoss Enterprise Middleware components that have been tested and certified together to provide an integrated experience. We take you all the way from installation to the deployment of your application. This Refcard is a must have for both users starting out with Java EE as well as senior architects.
HTML Preview
Getting Started With JBoss Enterprise Application Platform 5

Getting Started with JBoss Enterprise Application Platform 5

By Scott Marlow, Jaikiran Pai, Shelly McGowan, Brian Stansberry, and Len DiMaggio

WHAT IS JBOSS EAP 5?

JBoss Enterprise Application Platform is an open source implementation of the Java EE suite of services. It comprises a set of offerings for enterprise customers who are looking for preconfigured profiles of JBoss Enterprise Middleware components that have been tested and certified together to provide an integrated experience. Its easy-to-use server architecture and high flexibility makes JBoss the ideal choice for users just starting out with Java EE, as well as senior architects looking for a customizable middleware platform.

Because it is Java-based, JBoss Enterprise Application Platform is cross platform, easy to install and use on any operating system that supports Java. The readily available source code is a powerful learning tool to debug the server and understand it. It also gives you the flexibility to create customized versions for your personal or business use.

Visit the http://www.jboss.com/products/community-enterprise/ website to download JBoss Enterprise Application Platform 5.

INSTALLING JBOSS EAP 5

1. Installation using the Graphical Installer

The graphical installer will guide you through the installation steps. Invoke the installer using the command:


java -jar enterprise-installer-5.0.1.GA.jar

2. Installation using the Zip Distribution

Use the unzip command:


unzip jboss-eap-5.0.1.GA.zip

Use the same steps to install optional native package:


unzip jboss-eap-native-5.0.1.GA-<operating-system>-<arch>.zip

DIRECTORY STRUCTURE

Contents of jboss-as:

Directory Description
bin Contains startup, shutdown and other system-specific scripts. All entry point JAR files and start scripts are here.
client JAR files used by external Java client applications. Choose JAR files as required or use jbossall-client.jar
common/lib Shared JAR files common to profiles are here.
docs XML DTD and schemas for reference. Also example configuration files for setting up datasources (e.g. MySQL, Oracle, PostgreSQL).
lib Contains server startup JARs and not intended to hold application JAR files.
server Contains the JBoss server profile sets.

DIRECTORY STRUCTURE

JBoss EAP 5 configuration profiles are located within the jboss-as/server directory (specified with "run -c PROFILE" ):

default JavaEE 5 server profile. Has most frequently used EE services. Default does not include JAXR, IIOP, clustering services.
all Bundles all services (including clustering and RMI/IIOP).
production based on "all" profile, tuned for production; with log verbosity reduced, deployment scanning every 60 seconds, and memory usage tuned to accommodate production deployment requirements, configured to require authorization checks.
standard based on 'all' profile and is a fully certified Java EE 5 configuration.
web lightweight configuration created around JBoss Web and provides services required for web application deployment and a subset of Java EE technologies. Does not include JBoss Transaction JTS or XTS, Enterprise Java Bean 1.x or 2.x capabilities, JBoss Messaging, JCA, or JBoss IIOP
minimal Bare minimum required to start. Includes logging, JNDI and URL deployment scanner. Use JMX/JBoss to start your own services. No web container, EJB or JMS support is included.

ADMINISTRATION

To start the JBoss EAP server, simply change to the EAP_DIST/ jboss-as/bin directory. Set the environment variable JAVA_ HOME. Execute the run.bat (for Windows) or run.sh (for Linux, Unix, Mac OSX) script, as appropriate for your operating system.

Administering your JBoss EAP 5 server instance is easy with the administration consoles provided in this distribution. Once the server is started, simply point your browser to:


http://localhost:8080

This brings you to the consoles to manage your instance as well as links to on-line resource references.

Use the Administration Console for managing and monitoring a server instance. Deploy, undeploy, and update enterprise applications, persist configuration changes for Datasources, JMS topics and queues, Connection Factories, and Service Binding Manager, monitor standard JVM metrics, and view statistics and invoke operations on many other components.

The JMX Console provides a server view. It lists all registered services (MBeans). Administration Console shares the same username/password as JMX console.

Command-line scripts are available in the jboss-as/bin directory. In addition to scripts for starting and stopping the server, JBoss provides a command line tool that allows for interaction with a remote server instance. This tool is called twiddle (for twiddling bits via JMX) and is located in the bin directory. Twiddle is a command execution tool, not a general command shell. Run using the twiddle.sh/twiddle.bat scripts, and passing in a -h(-- help) argument provides the basic syntax, and --help-commands shows commands. Twiddle defaults to the localhost at port 1099 to lookup the default jmx/rmi/RMIAdaptor binding of the RMIAdaptor service as the connector for communicating with the JMX server. To connect to a different server/port combination, can use the -s (--server) option:


$ ./twiddle.sh -s servername serverinfo -d jboss
$ ./twiddle.sh -s servername:1099 serverinfo -d jboss

MANAGEMENT

The JBoss Operations Network (JON) management platform delivers centralized systems management that allows you to:

  • Coordinate stages of application’s life-cycle datasources and messaging services
  • Expose cohesive view of middleware components through complex environments
  • Improve operational efficiency/reliability through visibility into production availability and performance
  • Configure and roll out applications across complex environments through a single tool

APPLICATION DEPLOYMENT

There are multiple ways to deploy applications to JBoss:

Simplest way

  • Choose the server profile to which you want to deploy the application (let's consider the "default" server profile in this example)
  • Copy your application (for example: .war or .ear or a .jar file) to JBOSS_HOME/server/<profilename>/deploy folder.
  • Start the server:

./run.sh

  • JBoss will deploy your application when it boots up.
  • That's it!

Hot Tip

This approach does not require the server to be started when you are deploying your application. If you want to undeploy the application then just move (or delete) the application from the deploy folder. You can develop simple scripts (like an Ant script) to deploy the application to JBoss. All it takes is a file copy command.

Using the admin console

  • Start the server

./run.sh

  • On the left hand side of the admin console page, under JBoss AS -> Applications, select the type of application you want to deploy. Let's consider a web application (.war) in this example
  • Click the "Web Application (WAR)" link
  • In the right side section, under the "Summary" tab, click on "Add a new resource" button

  • "Browse" to the .war file to deploy (e.g. /home/me/myapp.war)
  • If you want to deploy the application in exploded format (instead of an archive) then select "Yes" radio button for "Deploy Exploded" option Click on the "Continue" button
  • On successful deployment, you will see your application listed in the Summary tab
  • To undeploy the application, click on the "Delete" button next to the application you want to undeploy, in the "Summary" tab

Hot deployment

JBoss has a built-in hot deployer which can:

  • Detect new applications in the deploy folder and trigger an application deployment
  • Detect an application which was removed from the deploy folder and trigger an application undeployment
  • Detect that the deployment descriptor of an application (for example, the web.xml of .war or application.xml of .ear) has changed and trigger an application redeployment

Hot Tip

The hot deployer is configured to run every X milliseconds. This value can be changed by changing the "scanPeriod" attribute in JBOSS_HOME/server/lt;profilename>/deploy/ hdscanner-jboss-beans.xml:

<!-- Hotdeployment of applications -->
<bean name="DScanner" class="org.jboss.system.server.profileservice
.hotdeploy.HDScanner">
<property name="deployer"><inject bean="ProfileServiceDeployer"/></property>
<property name="profileService"><inject bean="ProfileService"/></property>
<property name="scanPeriod">5000</property>
<property name="scanThreadName">HDScanner</property>
</bean>

To disable hot deployment, remove the hdscanner-jboss-beans. xml from the deploy folder or rename it to hdscanner-jbossbeans. xml.bak (.bak files are ignored).

Clustering

Getting started with JBoss clustering is very simple. If two JBoss server instances using the all configuration are started on the same network, those servers will detect each other and automatically form a cluster.

Initial Preparation

Preparing a set of servers to act as a JBoss cluster involves a few simple steps:

  • Install JBoss on all your servers.
  • For each node, determine the address to bind sockets to.
  • Ensure multicast is working. Make sure each server's networking configuration supports multicast and that multicast support is enabled for any switches or routers between your servers. JBoss clustering also offers nondefault configuration options that do not use multicast.
  • Determine a unique integer "ServerPeerID" for each node. JBoss Messaging requires that each node in a cluster has a unique integer id, known as a "ServerPeerID", that should remain consistent across server restarts. A simple 1, 2, 3, ..., x naming scheme is fine.

Launching Your Cluster

We'll look at two scenarios for doing this. In each scenario we'll be creating a two node cluster, where the ServerPeerID for the first node is 1 and for the second node is 2.

Scenario 1: Nodes on Separate Machines

On node1, to launch JBoss:


$ ./run.sh -c all -b 192.168.0.101 -Djboss.messaging.ServerPeerID=1

On node2, it's the same except for a different -b value and ServerPeerID:


$ ./run.sh -c all -b 192.168.0.102 -Djboss.messaging.ServerPeerID=2

The -c switch says to use the all config, which includes clustering support. The -b switch sets the address on which sockets will be bound. The -D switch sets the system property from which JBoss Messaging gets its unique id.

Scenario 2: Two Nodes on a Single, Non-Multihomed, Machine

Running multiple nodes on a single machine that only has a single IP address is a common scenario in a development environment. You need to be sure each server instance has its own work area. One way to do this is to simply make copies of the all configuration. For example, assuming the root of the JBoss distribution was unzipped to /var/jboss, you could:


$ cd /var/jboss/server
$ cp -r all node1
$ cp -r all node2

Two processes can't bind sockets to the same address and port, so we'll have to tell JBoss to use different ports for the two instances. This can be done by setting the jboss.service. binding.set system property.

To launch the first instance, open a console window and:


$ ./run.sh -c node1 -b 192.168.0.101 -Djboss.messaging.ServerPeerID=1 \
-Djboss.service.binding.set=ports-default

For the second instance, in a second console window:


$ ./run.sh -c node2 -b 192.168.0.101 -Djboss.messaging.ServerPeerID=2 \
-Djboss.service.binding.set=ports-01

This tells the ServiceBindingManager on the first node to use the standard set of ports (e.g. JNDI on 1099). The second node uses the “ports-01" binding set, with which by default each port has an offset of 100 from the standard port number (e.g. JNDI on 1199).

Web Application Clustering Quick Start

Web application clustering involves two aspects: setting up an HTTP load balancer and telling JBoss to make the application’s user sessions HA. How to do the former depends on what load balancer you choose (mod_cluster is a good choice); the latter couldn't be simpler – just add the <distributable/> to your application’s web.xml.

EJB3 Session Bean Clustering Quick Start

To add load balancing and failover capabilities to your EJB3 session beans, simply add the org.jboss.ejb3.annotation. Clustered annotation to the bean class for your stateful or stateless bean:


@javax.ejb.Stateful
@org.jboss.ejb3.annotation.Clustered
public class MyBean implements MySessionInt {
	public void test() {
		// Do something cool
	}
}

PERFORMANCE AND TUNING

Identify peak application workload and difference from normal workload. In understanding peak workloads, don’t go by averages as the peaks may be much more than the averages calculated over a period. Start testing with a low load and increase until expected peak load. Tune until target performance is achieved. There are a number of possible performance optimizations. Always load test before and after making changes to verify the intended effect. Make one change at a time so it's clear what change has what effect.

Use OS monitoring tools to identify system performance bottlenecks. In a multiple machine installation, find the machine(s) that are the bottleneck.

Instrument the application for performance measurement (make optional for production ). Also, turn on container call statistics and Hibernate statistics.

Taking successive thread dumps indicates what is going on. Do this prior/after hitting a performance wall. Generate a thread dump once a minute over a five minute performance problem and compare your findings. Use "jps -l" command to get the Java process ids and then run the “jstack ProcessID" command (generates the thread dump.)

The HotSpot Java Virtual Machine contains other information gathering tools which can help tune applications. More information is in http://java.sun.com/javase/technologies/hotspot/.

jmap generates a memory heap dump file that can easily be read by the Eclipse Memory Analyzer tool (http://www.eclipse.org/mat/). jstat shows details of the memory space.

Clustering Tuning

Ensuring Adequate Network Buffers

Inadequately sized network buffers can cause lost packets. Steps to increase max buffer sizes are OS specific. For Linux change /etc/sysctl.conf file:


# Allow a 25MB UDP receive buffer for JGroups
net.core.rmem_max = 26214400
# Allow a 1MB UDP send buffer for JGroups
net.core.wmem_max = 1048576

Isolating Intra-Cluster Traffic

isolate intra-cluster traffic from external request traffic. This requires multiple NICs on your server machines, with request traffic coming in on one NIC and intra-cluster traffic using another.


./run.sh -c all -b 10.0.0.104 -Djgroups.bind_addr=192.168.100.104

JGroups Message Bundling

Message bundling queues small messages until a configurable number of bytes have accumulated, then sent as a large message. Use of bundling can have significant performance benefits for high-volume asynchronous session replication. However, it is not enabled by default, as bundling can add significant latency to other types of intra-cluster traffic, particularly clustered Hibernate/JPA Second Level Cache traffic.

To use a JGroups channel with message bundling enabled, edit the <JBoss_Home>/server/<profilename>/deploy/cluster/ jboss-cache-manager.sar/META-INF/jboss-cache-jboss-beans. xml file. For example, for the cache used by default for web sessions:


. . .
<!-- Standard cache used for web sessions -->
<entry><key>standard-session-cache</key>
<value>
	<bean name="StandardSessionCacheConfig" class="org.jboss.cache.config.
	Configuration">
. . .
<!-- Replace standard 'udp' JGroups stack with one that uses message
bundling -->
	<property name="multiplexerStack">udp-async</property>
. . .

For FIELD granularity web sessions, in the same file the same change can be made to the cache configuration with the fieldgranularity- session-cache key. For EJB3 stateful session beans, in the same file the same change can be made to the cache configuration with the sfsb-cache key.

Enabling Buddy Replication for Session Caches

In a cluster of more than two nodes, you can improve performance by enabling "buddy replication" in the web session and stateful session bean caches. With buddy replication, instead of replicating a copy of sessions to all nodes in the cluster, a copy is only replicated to a configurable number of "buddy" nodes.

Buddy replication is enabled by editing the <JBoss_Home>/ server/<profilename>/deploy/cluster/jboss-cache-manager. sar/META-INF/jboss-cache-jboss-beans.xml file. For example, for the cache used by default for web sessions:


. . .
<!-- Standard cache used for web sessions -->
<entry><key>standard-session-cache</key>
<value>
	<bean name="StandardSessionCacheConfig" class="org.jboss.cache.config.
	Configuration">
. . .
<property name="buddyReplicationConfig">
	<bean class="org.jboss.cache.config.BuddyReplicationConfig">
<!-- Just set to true to turn on buddy replication -->
	<property name="enabled">true</property>
. . .

For FIELD granularity web sessions, in the same file the same change can be made to the cache configuration with the fieldgranularity- session-cache key. For EJB3 stateful session beans, in the same file the same change can be made to the cache configuration with the sfsb-cache key.

Reducing the Volume of Web Session Replication

Reducing the amount data being replicated can obviously improve performance. This can be accomplished both by avoiding replication when a request hasn't actually updated the session and by limiting replication to only the session data that has actually changed. See the discussion of replicationtrigger and replication-granularity in "http://www.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/5.0.0/html/Administration_And_Configuration_Guide/clustering-http-state.html" for how to configure your application to limit the amount of data replicated.

Monitoring JGroups via JMX

When clustering services create a JGroups Channel to use for intra-cluster communication, the JMX console will include the following:

jboss.jgroups:cluster=<cluster_name>,protocol=UDP,type=protocol Statistics on two thread pools used to carry incoming messages up the channel’s protocol stack.

jboss.jgroups:cluster=<cluster_name>,protocol=UNICAST,type=protocol Information on lossless, ordered delivery of unicast (i.e. point-to-point) messages.

jboss.jgroups:cluster=<cluster_name>,protocol=NAKACK,type=protocol Information on lossless, ordered delivery of multicast (i.e. point-to-multipoint) messages.

jboss.jgroups:cluster=<cluster_name>,protocol=FC,type=protocol Information on ensuring fast message senders do not overwhelm slow receivers.

Web deployer

Other key configurations required for performance tuning of your Enterprise Application Platform include the <JBoss_ Home>/server/<your_configuration>/deployers/jbossweb. deployer/server.xml file that sets your HTTP requests pool.

Thread pool

JBoss Enterprise Application Platform 5 has a robust thread pooling, that should be sized appropriately. The server has a jboss-service.xml file in the <JBoss_Home>/server/<your_ configuration>/conf directory that defines the system thread pool. There is a setting that defines the behavior if there isn't a thread available in the pool for execution. The default is to allow the calling thread to execute the task. You can monitor the queue depth of the system thread pool through the JMX Console, and determine from that if you need to make the pool larger.

TROUBLESHOOTING

Startup problems

If you are having trouble starting JBoss, the first thing to check is the JAVA_HOME environment variable. This should point to the home of your JDK (or JRE installation). For example, if your JDK is installed at /opt/Java/jdk1.5.0 then JAVA_HOME should be set as follows:


JAVA_HOME=/opt/Java/jdk1.5.0

On Windows OS, if your JDK installation is at C:/Java/jdk1.5.0, you can set it as follows:


set JAVA_HOME=C:/Java/jdkl.5.0

Hot Tip

It's highly recommended not to install JBoss or Java in a folder containing a space in its path. For example, do not install Java at C:/Program Files/Java/jdk1.5.0 on Windows OS.

Logs

JBoss by default is configured to log messages to the JBOSS_HOME/server/<servername>/log server.log file. This file can be checked for any exceptions or other informational logging. Logging levels can be controlled in JBOSS_HOME/ server/<servername>/conf/jboss-log4j.xml

Thread dumps

Sometimes, if you notice that the application is not responding, you can generate thread dumps to check what each thread is currently doing. Thread dumps can be generated in multiple ways - 2 of which are explained below:

From jmx-console

  • Access jmx-console (http://localhost:8080/jmx-console)
  • Look for the jboss.system:type=ServerInfo MBean and click on the link
  • On the page that comes up, look for the listThreadDump operation and click on the Invoke button

Using Twiddle:

  • From the command prompt, cd to JBOSS_HOME/bin folder
  • Run the following command:
    • ./twiddle.sh invoke "jboss.system:type=ServerInfo" listThreadDump > threads.html
    • Note: Use twiddle.bat for Windows OS

This command will generate the thread dump and redirect the output to threads.html (you can redirect it to any file of your choice)

It's best to generate multiple thread dumps between a span of few seconds and compare those thread dumps to find any blocked threads.

Reporting problems

Also, search the community forums to see if someone else is experiencing the same problem. The forums are at link http://community.jboss.org/. You can also obtain a support contract via http://www.jboss.com/services/subscriptions/ and then access https://www.redhat.com/wapps/sso/jboss/login.html?redirect=http%3A%2F%2Fsupport.redhat.com%2Fjbossnetwork

Search for existing issues that also report the same problem. Access the JIRA issue search via link https://jira.jboss.org/jira/secure/IssueNavigator.jspa

When filling in the JIRA, be as precise as possible when reporting the bug. Include as much information as possible. Include the steps needed to reproduce the problem.

If possible, create a standalone test case that reproduces the bug that can be attached to a JIRA issue. The JIRA issue is more likely to be fixed if a unit test is attached (or at least a test case). Even better is if a solution, in the form of a patch (output of doing "svn diff > fix.patch"), is attached.

JBOSS EAP 5 VS AS 5

The focus of the JBoss AS project is continuous innovation - fueled by Open Source community collaboration - on the bleeding edge of Java Middleware. Quickly bringing emerging standards and technology into the mainstream through it's large user base and active community. This focus implies continuous change and a rapid release cycle with minor releases every one or two months and major releases every six months. Red Hat does not provide support for JBoss community projects.

Red Hat does provide world-class support, consulting and training for the JBoss Enterprise Platforms. JBoss Enterprise Platforms balance innovation with enterprise class stability by integrating the best of Open Source projects like JBoss AS. The JBoss Enterprise Platforms are certified against a broad range of Operating Systems, Databases and other 3rd party applications and tools; meet very strict industry security standards; are pre-tuned and secured by default so are ready to support your business critical applications and services.

Red Hat recommends JBoss projects as a place to get involved in shaping the Open Source middleware landscape and as a way to understand how the technology landscape is evolving. Red Hat recommends JBoss Enterprise Platforms for demanding business critical production workloads where security, performance, reliability and long-term, world-class support are imperative.

See this link for information on training http://www.jboss.com/services/training/

About The Authors

Scott Marlow

Core Engineer on the JBoss AS team. Over 20 years experience building enterprise development software, from database server to developer tools (such as PowerBuilder and four different application servers). Five years experience contributing to JBoss OSS projects { Application Server, Clustering, JGroups, JBoss Cache, Hibernate }. Scott enjoys coaching and playing soccer in his spare time.

Jaikiran Pai

Employed at RedHat and is part of the JBoss EJB3 development team. Jaikiran completed his graduation in 2004 and started working in a software company in Pune, India. In his role as a software developer, he was part of projects which involved Java and JavaEE. During this period, he developed interest in JBoss Application Server and started spending his spare time in JBoss community forums. In 2009, Jaikiran was offered a job at RedHat to be part of his favourite project - JBoss Application Server.

Jaikiran can often be found either at the JBoss forums or at his other favourite place http://www.javaranch.com/. Occasionally, Jaikiran blogs at http://www.jaitechwriteups.blogspot.com/

Shelly McGowan

Member of the JBoss Application Server development team. She has several years of software development experience most recently on Java Enterprise Edition technologies such as EJB and EJB 3 persistence.

Brian Stansberry

My background is in International Business and East Asian Studies, with a B.A. from Michigan State and an M.A. from Stanford. Before getting bitten by the software bug, I had a successful career in corporate finance in the semiconductor industry. Part of that oddly enough involved web application and other types of software development. But since I realized in the late 1990s that my true interest was in software, not finance, I've focused on server-side development and Java. I started working on JBoss in 2003 and joined the company in 2005. My other main interests are China (I speak Mandarin Chinese and visit China regularly) and hanging out with my family. I live in St. Louis, MO.

Expertise: JBoss AS Clustering JBoss AS in general JBoss Cache PojoCache JGroups mod_cluster

Occupation: Lead, JBoss AS Clustering

Len DiMaggio

JBoss middleware QE engineer and team lead. Len is a frequent contributor to JBoss blogs and DZone (http://soa.dzone.com/users/ldimaggi).

Recommended Book

JBoss AS5 Development

This book will kick-start your productivity and help you to master JBoss AS development. The author's experience with JBoss enables him to share insights on JBoss AS development, in a clear and friendly way. By the end of the book, you will have the confidence to apply all the newest programming techniques to your JBoss applications.



JBoss in Action

JBoss in Action is the first book to focus on teaching readers in detail how to use the JBoss application server. Unlike other titles about JBoss, the authors of JBoss in Action go deeper into the advanced features and configuration of the server. In particular, it focuses on enterprise-class topics, such as high availability, security, and performance.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Core Java

By Cay S. Horstmann

48,439 Downloads · Refcard 24 of 151 (see them all)

Download
FREE PDF


The Essential Java Cheat Sheet

The Core Java Technology is the foundation of Java Platform of JSE. It is utilized in all classes of Java programming, from desktop to Java Enterprise Edition. This DZone Refcard gives you an overview of key aspects of the Java language and cheat sheets on the core library (formatted output, collections, regular expressions, logging, properties) as well as the most commonly used tools (javac, java, jar). In addition, this Refcard reviews Java Keywords, Standard Java Packages, Character Escape Sequences, Collections and Common Algorithms, Regular Expressions, JAR Files and more.
HTML Preview
Core Java

Core Java

By Cay S. Horstmann

About CORE JAVA

This refcard gives you an overview of key aspects of the Java language and cheat sheets on the core library (formatted output, collections, regular expressions, logging, properties) as well as the most commonly used tools (javac, java, jar).

Java Keywords

Keyword Description Example
abstract an abstract class or method abstract class Writable { public abstract void write(Writer out); public void save(String filename) { ... } }
assert with assertions enabled, throws an error if condition not fulfilled assert param != null; Note: Run with -ea to enable assertions
boolean the Boolean type with values true and false boolean more = false;
break breaks out of a switch or loop while ((ch = in.next()) != -1) { if (ch == '\n') break; process(ch); } Note: Also see switch
byte the 8-bit integer type byte b = -1; // Not the same as 0xFF Note: Be careful with bytes < 0
case a case of a switch see switch
catch the clause of a try block catching an exception see try
char the Unicode character type char input = 'Q';
class defines a class type class Person { private String name; public Person(String aName) { name = aName; } public void print() { System.out.println(name); } }
const not used
continue continues at the end of a loop while ((ch = in.next()) != -1) { if (ch == ' ') continue; process(ch); }
default the default clause of a switch see switch
do the top of a do/while loop do { ch = in.next(); } while (ch == ' ');
double the double-precision floating-number type double oneHalf = 0.5;
else the else clause of an if statement see if
enum an enumerated type enum Mood { SAD, HAPPY };
extends defines the parent class of a class class Student extends Person { private int id; public Student(String name, int anId) { ... } public void print() { ... } }
final a constant, or a class or method that cannot be overridden public static final int DEFAULT_ID = 0;
finally the part of a try block that is always executed see try
float the single-precision floating-point type float oneHalf = 0.5F;
for a loop type for (int i = 10; i >= 0; i--) System.out.println(i); for (String s : line.split("\\s+")) System.out.println(s); Note: In the "generalized" for loop, the expression after the : must be an array or an Iterable
goto not used
if a conditional statement if (input == 'Q') System.exit(0); else more = true;
implements defines the interface(s) that a class implements class Student implements Printable { ... }
import imports a package import java.util.ArrayList; import com.dzone.refcardz.*;
instanceof tests if an object is an instance of a class if (fred instanceof Student) value = ((Student) fred).getId(); Note: null instanceof T is always false
int the 32-bit integer type int value = 0;
interface an abstract type with methods that a class can implement interface Printable { void print(); }
long the 64-bit long integer type long worldPopulation = 6710044745L;
native a method implemented by the host system
new allocates a new object or array Person fred = new Person("Fred");
null a null reference Person optional = null;
package a package of classes package com.dzone.refcardz;
private a feature that is accessible only by methods of this class see class
protected a feature that is accessible only by methods of this class, its children, and other classes in the same package class Student { protected int id; ... }
public a feature that is accessible by methods of all classes see class
return returns from a method int getId() { return id; }
short the 16-bit integer type short skirtLength = 24;
static a feature that is unique to its class, not to objects of its class public class WriteUtil { public static void write(Writable[] ws, String filename); public static final String DEFAULT_EXT = ".dat"; }
strictfp Use strict rules for floating-point computations
super invoke a superclass constructor or method public Student(String name, int anId) { super(name); id = anId; } public void print() { super.print(); System.out.println(id); }
switch a selection statement switch (ch) { case 'Q': case 'q': more = false; break; case ' '; break; default: process(ch); break; } Note: If you omit a break, processing continues with the next case.
synchronized a method or code block that is atomic to a thread public synchronized void addGrade(String gr) { grades.add(gr); }
this the implicit argument of a method, or a constructor of this class public Student(String id) {this.id = id;} public Student() { this(""); }
throw throws an exception if (param == null) throw new IllegalArgumentException();
throws the exceptions that a method can throw public void print() throws PrinterException, IOException
transient marks data that should not be persistent class Student { private transient Data cachedData; ... }
try a block of code that traps exceptions try { try { fred.print(out); } catch (PrinterException ex) { ex.printStackTrace(); } } finally { out.close(); }
void denotes a method that returns no value public void print() { ... }
volatile ensures that a field is coherently accessed by multiple threads class Student { private volatile int nextId; ... }
while a loop while (in.hasNext()) process(in.next());

Standard Java Packages

java.applet Applets (Java programs that run inside a web page)
java.awt Graphics and graphical user interfaces
java.beans Support for JavaBeans components (classes with properties and event listeners)
java.io Input and output
java.lang Language support
java.math Arbitrary-precision numbers
java.net Networking
java.nio "New" (memory-mapped) I/O
java.rmi Remote method invocations
java.security Security support
java.sql Database support
java.text Internationalized formatting of text and numbers
java.util Utilities (including data structures, concurrency, regular expressions, and logging)

Operator Precedence

Operators with the same precedence Notes
[] . () (method call) Left to right
! ~ ++ -- + (unary) - (unary) () (cast) new Right to left ~ flips each bit of a number
* / % Left to right Be careful when using % with negative numbers. -a % b == -(a % b), but a % -b == a % b. For example, -7 % 4 == -3, 7 % -4 == 3.
+ - Left to right
<< >> >>> Left to right >> is arithmetic shift (n >> 1 == n / 2 for positive and negative numbers), >>> is logical shift (adding 0 to the highest bits). The right hand side is reduced modulo 32 if the left hand side is an int or modulo 64 if the left hand side is a long. For example, 1 << 35 == 1 << 3.
< <= > >= instanceof Left to right null instanceof T is always false
== != Left to right Checks for identity. Use equals to check for structural equality.
& Left to right Bitwise AND; no lazy evaluation with bool arguments
^ Left to right Bitwise XOR
| Left to right Bitwise OR; no lazy evaluation with bool arguments
&& Left to right
|| Left to right
?: Right to left
= += -= *= /= %= &= |= ^= <<= >>= >>>= Right to left

Primitive Types

Type Size Range Notes
int 4 bytes -2,147,483,648 to 2,147,483, 647 (just over 2 billion) The wrapper type is Integer. Use BigInteger for arbitrary precision integers.
short 2 bytes -32,768 to 32,767
long 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Literals end with L (e.g. 1L).
byte 1 byte -128 to 127 Note that the range is not 0 ... 255.
float 4 bytes approximately -3.40282347E+38F (6-7 significant decimal digits) Literals end with F (e.g. 0.5F)
double 8 bytes approximately -1.79769313486231570E+308 (15 significant decimal digits) Use BigDecimal for arbitrary precision floating-point numbers.
char 2 bytes \u0000 to \uFFFF The wrapper type is Character. Unicode characters > U+FFFF require two char values.
boolean true or false

Legal conversions between primitive types

Dotted arrows denote conversions that may lose precision.

Legal Conversions Between Primitive Types

Collections and Common Algorithms

ArrayList An indexed sequence that grows and shrinks dynamically
LinkedList An ordered sequence that allows efficient insertions and removal at any location
ArrayDeque A double-ended queue that is implemented as a circular array
HashSet An unordered collection that rejects duplicates
TreeSet A sorted set
EnumSet A set of enumerated type values
LinkedHashSet A set that remembers the order in which elements were inserted
PriorityQueue A collection that allows efficient removal of the smallest element
HashMap A data structure that stores key/value associations
TreeMap A map in which the keys are sorted
EnumMap A map in which the keys belong to an enumerated type
LinkedHashMap A map that remembers the order in which entries were added
WeakHashMap A map with values that can be reclaimed by the garbage collector if they are not used elsewhere
IdentityHashMap A map with keys that are compared by ==, not equals

Common Tasks

List<String> strs = new ArrayList<String>(); Collect strings
strs.add("Hello"); strs.add("World!"); Add strings
for (String str : strs) System.out.println(str); Do something with all elements in the collection
Iterator<String> iter = strs.iterator(); while (iter.hasNext()) { String str = iter.next(); if (someCondition(str)) iter.remove(); } Remove elements that match a condition. The remove method removes the element returned by the preceding call to next.
strs.addAll(strColl); Add all strings from another collection of strings
strs.addAll(Arrays.asList(args)) Add all strings from an array of strings. Arrays.asList makes a List wrapper for an array
strs.removeAll(coll); Remove all elements of another collection. Uses equals for comparison
if (0 <= i && i < strs.size()) { str = strs.get(i); strs.set(i, "Hello"); } Get or set an element at a specified index
strs.insert(i, "Hello"); str = strs.remove(i); Insert or remove an element at a specified index, shifting the elements with higher index values
String[] arr = new String[strs.size()]; strs.toArray(arr); Convert from collection to array
String[] arr = ...; List<String> lst = Arrays.asList(arr); lst = Arrays.asList("foo", "bar", "baz"); Convert from array to list. Use the varargs form to make a small collection.
List<String> lst = ...; lst.sort(); lst.sort(new Comparator<String>() { public int compare(String a, String b) { return a.length() - b.length(); } } Sort a list by the natural order of the elements, or with a custom comparator.
Map<String, Person> map = new LinkedHashMap<String, Person>(); Make a map that is traversed in insertion order (requires hashCode for key type). Use a TreeMap to traverse in sort order (requires that key type is comparable).
for (Map.Entry<String, Person> entry : map.entrySet()) { String key = entry.getKey(); Person value = entry.getValue(); ... } Iterate through all entries of the map
Person key = map.get(str); // null if not found map.put(key, value); Get or set a value for a given key

Character Escape Sequences

\b backspace \u0008
\t tab \u0009
\n newline \u000A
\f form feed \u000C
\r carriage return \u000D
\" double quote
\' single quote
\\ backslash
\uhhhh (hhhh is a hex number between 0000 and FFFF) The UTF-16 code point with value hhhh
\ooo (ooo is an octal number between 0 and 377) The character with octal value ooo
Note: Unlike in C/C++, \xhh is not allowed

Formatted output with printf

Typical usage

System.out.printf("%4d %8.2f", quantity, price);
String str = String.format("%4d %8.2f", quantity, price);

Each format specifier has the following form. See the tables for flags and conversion characters.

Typical usage

Flags

Flag Description Example
+ Prints sign for positive and negative numbers +3333.33
space Adds a space before positive numbers | 3333.33|
0 Adds leading zeroes 003333.33
- Left-justifies field |3333.33 |
( Encloses negative number in parentheses (3333.33)
, Adds group separators 3,333.33
# (for f format) Always includes a decimal point 3,333.
# (for x or o format) Adds 0x or 0 prefix 0xcafe
$ Specifies the index of the argument to be formatted; for example, %1$d %1$x prints the first argument in decimal and hexadecimal 159 9F
< Formats the same value as the previous specification; for example, %d %<x prints the same number in decimal and hexadecimal 159 9F

Conversion characters

Conversion Character Description Example
d Decimal integer 159
x Hexadecimal integer 9f
o Octal integer 237
f Fixed-point floating-point 15.9
e Exponential floating-point 1.59e+01
g General floating-point (the shorter of e and f)
a Hexadecimal floating-point 0x1.fccdp3
s String Hello
c Character H
b boolean true
h Hash code 42628b2
tx Date and time See the next table
% The percent symbol %
n The platform-dependent line separator

Formatted output with MessageFormat

Typical usage:

String msg = MessageFormat.format("On {1, date,
long}, a {0} caused {2,number,currency} of damage.",
"hurricane", new GregorianCalendar(2009, 0, 15).
getTime(), 1.0E8);

Yields "On January 1, 1999, a hurricane caused $100,000,000 of damage"

  • The nth item is denoted by {n,format,subformat} with optional formats and subformats shown below
  • {0} is the first item
  • The following table shows the available formats
  • Use single quotes for quoting, for example '{' for a literal left curly brace
  • Use '' for a literal single quote
Format Subformat Example
number none 1,234.567
integer 1,235
currency $1,234.57
percent 123,457%
date none or medium Jan 15, 2009
short 1/15/09
long January 15, 2009
full Thursday, January 15, 2009
time none or medium 3:45:00 PM
short 3:45 PM
long 3:45:00 PM PST
full 3:45:00 PM PST
choice List of choices, separated by |. Each choice has
  • a lower bound (use -\u221E for -)
  • a relational operator: < for "less than", # or \u2264 for .
  • a message format string
For example, {1,choice,0#no houses|1#one house|2#{1} houses}
no house
one house
5 houses

Regular Expressions

Common Tasks

String[] words = str.split("\\s+"); Split a string along white space boundaries
Pattern pattern = Pattern.compile("[0-9]+"); Matcher matcher = pattern.matcher(str); String result = matcher.replaceAll("#"); Replace all matches. Here we replace all digit sequences with a #.
Pattern pattern = Pattern.compile("[0-9]+"); Matcher matcher = pattern.matcher(str); while (matcher.find()) { process(str.substring(matcher.start(), matcher.end())); } Find all matches.
Pattern pattern = Pattern.compile( "(1?[0-9]):([0-5][0-9])[ap]m"); Matcher matcher = pattern.matcher(str); for (int i = 1; i <= matcher.groupCount(); i++) { process(matcher.group(i)); } Find all groups (indicated by parentheses in the pattern). Here we find the hours and minutes in a date.

Regular Expression Syntax

Characters
c The character c
\unnnn, \xnn, \0n, \0nn, \0nnn The code unit with the given hex or octal value
\t, \n, \r, \f, \a, \e The control characters tab, newline, return, form feed, alert, and escape
\cc The control character corresponding to the character c
Character Classes
[C1C2 . . .] Union: Any of the characters represented by C1C2 , . . . The Ci are characters, character ranges c1-c2, or character classes. Example: [a-zA-Z0-9_]
[^C1C2 . . .] Complement: Characters not represented by any of C1C2 , . . . Example: [^0-9]
[C1&&C2 &&. . .] Intersection: Characters represented by all of C1C2 , . . . Example: [A-f&&[^G-`]]
Predefined Character Classes
. Any character except line terminators (or any character if the DOTALL flag is set)
\d A digit [0-9]
\D A nondigit [^0-9]
\s A whitespace character [ \t\n\r\f\x0B]
\S A nonwhitespace character
\w A word character [a-zA-Z0-9_]
\W A nonword character
\p{name} A named character class-see table below
\P{name} The complement of a named character class
Boundary Matchers
^ $ Beginning, end of input (or beginning, end of line in multiline mode)
\b A word boundary
\B A nonword boundary
\A Beginning of input
\z End of input
\Z End of input except final line terminator
\G End of previous match
Quantifiers
X? Optional X
X* X, 0 or more times
X+ X, 1 or more times
X{n} X{n,} X{n,m} X n times, at least n times, between n and m times
Quantifier Suffixes
? Turn default (greedy) match into reluctant match
+ Turn default (greedy) match into reluctant match
Set Operations
XY Any string from X, followed by any string from Y
X |Y Any string from X or Y
Grouping
(X) Capture the string matching X as a group
\g The match of the gth group
Escapes
\c The character c (must not be an alphabetic character)
\Q . . . \E Quote . . . verbatim
(? . . . ) Special construct-see API notes of Pattern class

Predefined Character Class Names

Lower ASCII lower case [a-z]
Upper ASCII upper case [A-Z]
Alpha ASCII alphabetic [A-Za-z]
Digit ASCII digits [0-9]
Alnum ASCII alphabetic or digit [A-Za-z0-9]
XDigit Hex digits [0-9A-Fa-f]
Print or Graph Printable ASCII character [\x21-\x7E]
Punct ASCII nonalpha or digit [\p{Print}&&\P{Alnum}]
ASCII All ASCII [\x00-\x7F]
Cntrl ASCII Control character [\x00-\x1F]
Blank Space or tab [ \t]
Space Whitespace [ \t\n\r\f\0x0B]
javaLowerCase Lower case, as determined by Character.isLowerCase()
javaUpperCase Upper case, as determined by Character.isUpperCase()
javaWhitespace White space, as determined by Character.isWhiteSpace()
javaMirrored Mirrored, as determined by Character.isMirrored()
InBlock Block is the name of a Unicode character block, with spaces removed, such as BasicLatin or Mongolian.
Category or InCategory Category is the name of a Unicode character category such as L (letter) or Sc (currency symbol).

Flags for matching

The pattern matching can be adjusted with flags, for example:

Pattern pattern = Pattern.compile(patternString,
Pattern.CASE_INSENSITIVE + Pattern.UNICODE_CASE)
Flag Description
CASE_INSENSITIVE Match characters independently of the letter case. By default, this flag takes only US ASCII characters into account.
UNICODE_CASE When used in combination with CASE_INSENSITIVE, use Unicode letter case for matching.
MULTILINE ^ and $ match the beginning and end of a line, not the entire input.
UNIX_LINES Only '\n' is recognized as a line terminator when matching ^ and $ in multiline mode.
DOTALL When using this flag, the . symbol matches all characters, including line terminators.
CANON_EQ Takes canonical equivalence of Unicode characters into account. For example, u followed by ¨ (diaeresis) matches ü.
LITERAL The input string that specifies the pattern is treated as a sequence of literal characters, without special meanings for . [ ] etc.

Logging

Common Tasks

Logger logger = Logger.getLogger("com.mycompany.myprog.mycategory"); Get a logger for a category
logger.info("Connection successful."); Logs a message of level FINE. Available levels are SEVERE, WARNING,INFO,CONFIG,FINE, FINER, FINEST, with corresponding methods severe, warning, and so on.
logger.log(Level.SEVERE, "Unexpected exception", throwable); Logs the stack trace of a Throwable
logger.setLevel(Level.FINE); Sets the logging level to FINE. By default, the logging level is INFO, and less severe logging messages are not logged.
Handler handler = new FileHandler("%h/myapp.log", SIZE_LIMIT, LOG_ROTATION_COUNT); handler.setFormatter(new SimpleFormatter()); logger.addHandler(handler); Adds a file handler for saving the log records in a file. See the table below for the naming pattern. This handler uses a simple formatter instead of the XML formatter that is the default for file handlers.

Logging Configuration Files

The logging configuration can be configured through a logging configuration file, by default jre/lib/logging.properties. Another file can be specified with the system property java.util.logging.config.file when starting the virtual machine. (Note that the LogManager runs before main.)

Configuration Property Description Default
loggerName.level The logging level of the logger by the given name None; the logger inherits the handler from its parent
handlers A whitespace or comma-separated list of class names for the root logger. An instance is created for each class name, using the default constructor. java.util.logging. ConsoleHandler
loggerName.handlers A whitespace or comma-separated list of class names for the given logger list of class names for the given logger None
loggerName. useParenthandlers false if the parent logger's handlers (and ultimately the root logger's handlers) should not be used true
config A whitespace or comma-separated list of class names for initialization. None
java.util.logging.FileHandler.level
java.util.logging.ConsoleHandler.level
The default handler level Level.ALL for FileHandler, Level.INFO for ConsoleHandler
java.util.logging.FileHandler.formatter
java.util.logging.ConsoleHandler.formatter
The class name of the default filter None
java.util.logging.FileHandler.formatter
java.util.logging.ConsoleHandler.formatter
The class name of the default formatter formatter java.util.logging. XMLFormatter for FileHandler, java.util.logging. SimpleFormatter for ConsoleHandler
java.util.logging.FileHandler.encoding
java.util.logging.ConsoleHandler.encoding
The default encoding default platform encoding
java.util.logging.FileHandler.limit The default limit for rotating log files, in bytes 0 (No limit), but set to 50000 in jre/lib/ logging.properties
java.util.logging.FileHandler.count The default number of rotated log files 1
java.util.logging.FileHandler.pattern The default naming pattern for log files. The following tokens are replaced when the file is created:
Token Description
/ Path separator
%t System temporary directory
%h Value of user.home system property
%g The generation number of rotated logs
%u A unique number for resolving naming conflicts
%% The % character
%h/java%u.log
java.util.logging. FileHandler.append The default append mode for file loggers; true to append to an existing log file false

Property Files

  • Contain name/value pairs, separated by =, :, or whitespace
  • Whitespace around the name or before the start of the value is ignored
  • n Lines can be continued by placing an \ as the last character; leading whitespace on the continuation line is ignored
    button1.tooltip = This is a long \
    tooltip text.
  • \t \n \f \r \\ \uxxxx escapes are recognized (but not \b or octal escapes)
  • Files are assumed to be encoded in ISO 8859-1; use native2ascii to encode non-ASCII characters into Unicode escapes
  • Blank lines and lines starting with # or ! are ignored

Typical usage:

Properties props = new Properties();
props.load(new FileInputStream("prog.properties"));
String value = props.getProperty("button1.tooltip");
// null if not present

Also used for resource bundles:

ResourceBundle bundle = ResourceBundle.getBundle("prog");
// Searches for prog_en_US.properties,
// prog_en.properties, etc.
String value = bundle.getString("button1.tooltip");

JAR Files

  • Used for storing applications, code libraries
  • By default, class files and other resources are stored in ZIP file format
  • META-INF/MANIFEST.MF contains JAR metadata
  • META-INF/services can contain service provider configuration
  • Use the jar utility to make JAR files

jar Utility Options

Option Description
c Creates a new or empty archive and adds files to it. If any of the specified file names are directories, the jar program processes them recursively.
C Temporarily changes the directory. For example, jar cvfC myprog.jar classes *.class changes to the classes subdirectory to add class files.
e Creates a Main-Class entry in the manifest jar cvfe myprog.jar com.mycom.mypkg.MainClass files
f Specifies the JAR file name as the second command-line argument. If this parameter is missing, jar will write the result to standard output (when creating a JAR file) or read it from standard input (when extracting or tabulating a JAR file).
i Creates an index file (for speeding up lookups in a large archive)
m Adds a manifest to the JAR file. jar cvfm myprog.jar mymanifest.mf files
M Does not create a manifest file for the entries.
t Displays the table of contents. jar tvf myprog.jar
u Updates an existing JAR file jar uf myprog.jar com/mycom/mypkg/SomeClass.class
v Generates verbose output.
x Extracts files. If you supply one or more file names, only those files are extracted. Otherwise, all files are extracted. jar xf myprog.jar
O Stores without ZIP compression

common javac options

Option Purpose
-cp or -classpath Sets the class path, used to search for class files. The class path is a list of directories, JAR files, or expressions of the form directory/'*' (Unix) or directory\* (Windows). The latter refers to all JAR files in the given directory. Class path items are separated by : (Unix) or ; (Windows). If no class path is specified, it is set to the current directory. If a class path is specified, the current directory is not automatically included-add a . item if you want to include it.
-sourcepath Sets the path used to search for source files. If source and class files are present for a given file, the source is compiled if it is newer. If no source path is specified, it is set to the current directory.
-d Sets the path used to place the class files. Use this option to separate .java and .class files.
-source Sets the source level. Valid values are 1.3, 1.4, 1.5, 1.6, 5, 6
-deprecation Gives detail information about the use of deprecated features
-Xlint:unchecked Gives detail information about unchecked type conversion warnings
-cp or -classpath Sets the class path, used to search for class files. See the previous table for details. Note that javac can succeed when java fails if the current directory is on the source path but not the class path.
-ea or -enableassertions Enable assertions. By default, assertions are disabled.
-Dproperty=value Sets a system property that can be retrieved by System. getProperty(String)
-jar Runs a program contained in a JAR file whose manifest has a Main-Class entry. When this option is used, the class path is ignored.
-verbose Shows the classes that are loaded. This option may be useful to debug class loading problems.
-Xmssize
-Xmxsize
Sets the initial or maximum heap size. The size is a value in bytes. Add a suffix k or m for kilobytes or megabytes, for example, -Xmx10m

About The Author

Photo of author Cay S. Horstmann

Cay S. Horstmann

Cay S. Horstmann has written many books on C++, Java and objectoriented development, is the series editor for Core Books at Prentice-Hall and a frequent speaker at computer industry conferences. For four years, Cay was VP and CTO of an Internet startup that went from 3 people in a tiny office to a public company. He is now a computer science professor at San Jose State University. He was elected Java Champion in 2005.

Publications
  • Core Java, with Gary Cornell, Sun Microsystems Press 1996 - 2007 (8 editions)
  • Core JavaServer Faces, with David Geary, Sun Microsystems Press, 2004-2006 (2 editions)
  • Big Java, John Wiley & Sons 2001 - 2007 (3 editions)
Blog
Web site

Recommended Books

Book cover of Core Java Vol 1 Book cover of Core Java Vol 2

Core Java, now in its 8th edition, is a no-nonsense tutorial and reliable reference into all aspects of Java SE 6.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.