What's New in JMS 2.0: Ease of Use


Continuing our Java EE 7 series, Oracle's Nigel Deakin shows how to new ease-of-use features enable you to write fewer lines of code. Reprinted with permission from the Oracle Technology Network, Oracle Corporation.
This article, which is the first article in a two-part series, assumes a basic familiarity with Java Message Service (JMS) 1.1 and introduces some of the new ease-of-use features in JMS 2.0. In Part Two, we will look at new messaging features.
JMS 2.0, which was released in April 2013, is the first update to the JMS specification since version 1.1 was released in 2002. One might think that an API that has remained unchanged for so long has grown moribund and unused. However, if you judge the success of an API standard by the number of different implementations, JMS is one of the most successful APIs around.
In JMS 2.0, the emphasis has been on catching up with the ease-of-use improvements that have been made to other enterprise Java technologies. While technologies such as Enterprise JavaBeans or Java persistence are now much simpler to use than they were a decade ago, JMS had remained unchanged with a successful, but rather verbose, API.
The single biggest change in JMS 2.0 is the introduction of a new API for sending and receiving messages that reduces the amount of code a developer must write. For applications that run in a Java EE application server, the new API also supports resource injection. This allows the application server to take care of the creation and management of JMS objects, simplifying the application even further.
JMS 2.0 is part of the Java EE 7 platform and can be used in Java EE Web or EJB applications, or it can be used standalone in a Java SE environment. As I explain below, some of the features described here are available only in a standalone environment while others are available only in Java EE Web or EJB applications.
Simplified API
The new API is known as the simplified API. As the name suggests, it is intended to be simpler and easier to use than the existing JMS 1.1 API, which is (rather predictably) now referred to as the classic API.
The simplified API consists of three new interfaces: JMSContext, JMSProducer, and JMSConsumer:
  • JMSContext replaces the separate Connection and Session objects in the classic API with a single object.
  • JMSProducer is a lightweight replacement for the MessageProducer object in the classic API. It allows message delivery options, headers, and properties to be configured using method chaining (sometimes known as a builder pattern).
  • JMSConsumer replaces the MessageConsumer object in the classic API and is used in a similar way.
Developers now have a choice as to whether to use the classic API (the familiar Connection, Session, MessageProducer, andMessageConsumer objects of JMS 1.1) or the simplified API (the JMSContext, JMSProducer, and JMSConsumer objects introduced in JMS 2.0).
The simplified API offers all the features of the classic API plus some additional features. The classic API is not deprecated and will remain part of JMS indefinitely.
Using the Simplified API to Send a Message
The JMS 1.1 classic API has been in use for over a decade and has proven its usefulness. In what ways is the JMS 2.0 simplified API better? The JMS 2.0 simplified API requires less code.
Listing 1 below shows a simple example that uses the classic API to send a single text message.
Listing 1

public void sendMessageJMS11(ConnectionFactory connectionFactory, Queue queueString text) {
   try {
      Connection connection = connectionFactory.createConnection();
      try {
         Session session =connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
         MessageProducer messageProducer = session.createProducer(queue);
         TextMessage textMessage = session.createTextMessage(text);
         messageProducer.send(textMessage);
      } finally {
         connection.close();
      }
   } catch (JMSException ex) {
      // handle exception (details omitted)
   }
}

Now compare Listing 1 to Listing 2, which shows how we might do exactly the same thing using the simplified API in JMS 2.0:
Listing 2

public void sendMessageJMS20(ConnectionFactory connectionFactory, Queue queue, 
String text) {
   try (JMSContext context = connectionFactory.createContext();){
      context.createProducer().send(queue, text);
   } catch (JMSRuntimeException ex) {
      // handle exception (details omitted)
   }
}


As you can see, the amount of code we have to write is significantly reduced. Let's look at this in more detail.
  • Instead of creating separate Connection and Session objects, we create a single JMSContext object.
  • The JMS 1.1 version used a finally block to call close on the Connection after use. In JMS 2.0, the JMSContext object also has a close method that needs to be called after use. However, there's no need to explicitly call close from your code.JMSContext implements the Java SE 7 java.lang.AutoCloseable interface. This means that if we create the JMSContext in atry-with-resources block (also a new feature of Java SE 7), the close method will be called automatically at the end of the block without the need to explicitly add it to your code.

    In fact, all JMS interfaces that have a close method have been extended to implement the java.lang.AutoCloseable interface, so they can all be used in try-with-resources blocks. This includes the Connection and Session interfaces as well asJMSContext. So even if you're using the classic API, you can still benefit from this feature. Note that because of this change, JMS 2.0 can be used only with Java SE 7.
  • When the JMS 1.1 version created the Session object, it passed in the parameters (false and Session.AUTO_ACKNOWLEDGE) to specify that we want to create a non-transacted session in which any received messages will be acknowledged automatically. In JMS 2.0, this is the default (for Java SE applications), so we don't need to specify any parameters.

    If we wanted to specify one of the other session modes (local transaction, CLIENT_ACKNOWLEDGE, or DUPS_OK_ACKNOWLEDGE), we would pass in just a single parameter rather than two.
  • There's no need to create a TextMessage object and set its body to be the specified string. Instead, we simply pass the string into the send method. The JMS provider will automatically create a TextMessage and set its body to the supplied string.
  • The JMS 1.1 example provided a catch block for the JMSException that almost all methods throw. The JMS 2.0 simplified API example has a similar block, but it catches a JMSRuntimeException instead.

    One feature of the simplified API is that its methods do not declare checked exceptions. If an error condition is encountered, aJMSRuntimeException is thrown. This new exception is a subclass of RuntimeException, which means it does not need to be explicitly caught by the calling method or declared in its throws clause. This contrasts with the classic API, in which almost every method is declared to throw a JMSException that the calling method must either catch or throw itself.
Both Listing 1 and Listing 2 show the ConnectionFactory and Queue objects being passed in as parameters. The way that these are obtained hasn't changed, so we won't cover this here or in the other listings in this article. Typically, they would be obtained by a JNDI lookup from a JNDI repository.

Using the Simplified API to Receive Messages Synchronously

Listing 3 shows a simple example that uses JMS 1.1 to receive a single TextMessage synchronously and extract its text.
Listing 3

public String receiveMessageJMS11(ConnectionFactory connectionFactory,Queue queue){
   String body=null;
   try {
      Connection connection = connectionFactory.createConnection();
      try {
         Session session =connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
         MessageConsumer messageConsumer = session.createConsumer(queue);
         connection.start();
         TextMessage textMessage = TextMessage)messageConsumer.receive();
         body = textMessage.getText();
      } finally {
         connection.close();
      }
   } catch (JMSException ex) {
      // handle exception (details omitted)
   }
   return body;


Listing 4 shows how we might do exactly the same thing using the simplified API in JMS 2.0:
Listing 4

public String receiveMessageJMS20(
ConnectionFactory connectionFactory,Queue queue){
   String body=null;
   try (JMSContext context = connectionFactory.createContext();){
      JMSConsumer consumer = session.createConsumer(queue);
      body = consumer.receiveBody(String.class);
   } catch (JMSRuntimeException ex) {
      // handle exception (details omitted)
   }
   return body;
}


As with sending a message, the amount of code we have to write is reduced. Some of the reasons are the same as in the previous example:
  • Instead of creating separate Connection and Session objects, we create a single JMSContext object.
  • We can create the JMSContext in a try-with-resources block so that it will be closed automatically at the end of the block. This removes the need to call close.
  • We don't need to specify that we want received messages to be acknowledged automatically, because that is the default.
Also, there are two additional ways in which JMS 2.0 reduces the amount of code needed to receive a message:
  • Whereas in JMS 1.1 we need to call connection.start() to start delivery of messages to the consumer, in the JMS 2.0 simplified API we don't: the connection is automatically started. (You can disable this behavior if you need to.)
  • There's no need to receive a Message object, cast it to a TextMessage, and then call getText to extract the message body. Instead, we call receiveBody, which returns the message body directly.

Java EE 7: An Overview of Batch Processing

Batch processing is used in many industries for tasks ranging from payroll processing; statement generation; end-of-day jobs such as interest calculation and ETL (extract, load, and transform) in a data warehouse; and many more. Typically, batch processing is bulk-oriented, non-interactive, and long running—and might be data- or computation-intensive. Batch jobs can be run on schedule or initiated on demand. Also, since batch jobs are typically long-running jobs, check-pointing and restarting are common features found in batch jobs.
JSR 352 (Batch Processing for Java Platform), part of the recently introduced Java EE 7 platform, defines the programming model for batch applications plus a runtime to run and manage batch jobs. This article covers some of the key concepts including feature highlights, an overview of selected APIs, the structure of Job Specification Language, and a sample batch application. The article also describes how you can run batch applications using GlassFish Server Open Source Edition 4.0.
Batch Processing Architecture
This section and Figure 1 describe the basic components of the batch processing architecture.
  • A job encapsulates the entire batch process. A job contains one or more steps. A job is put together using a Job Specification Language (JSL) that specifies the sequence in which the steps must be executed. In JSR 352, JSL is specified in an XML file called the job XML file. In short, a job (with JSR 352) is basically a container for steps.
  • A step is a domain object that encapsulates an independent, sequential phase of the job. A step contains all the necessary logic and data to perform the actual processing. The batch specification deliberately leaves the definition of a step vague because the content of a step is purely application-specific and can be as complex or simple as the developer desires. There are two kinds of steps: chunk and batchlet.
    • A chunk-style step contains exactly one ItemReader, one ItemProcessor, and one ItemWriter. In this pattern, ItemReaderreads one item at a time, ItemProcessor processes the item based upon the business logic (such as "calculate account balance"), and hands it to the batch runtime for aggregation. Once the "chunk-size" number of items are read and processed, they are given to an ItemWriter, which writes the data (for example, to a database table or a flat file). The transaction is then committed.
    • JSR 352 also defines a roll-your-own kind of a step called a batchlet. A batchlet is free to use anything to accomplish the step, such as sending an e-mail.
  • JobOperator provides an interface to manage all aspects of job processing, including operational commands, such as start, restart, and stop, as well as job repository commands, such as retrieval of job and step executions. See section 10.4 of the JSR 352 specification for more details about JobOperator.
  • JobRepository holds information about jobs currently running and jobs that ran in the past. JobOperator provides APIs to access this repository. A JobRepository could be implemented using, say, a database or a file system.

Developing a simple Payroll processing application

This article demonstrates some of the key features of JSR 352 using a simple payroll processing application. The application has been intentionally kept quite simple in order to focus on the key concepts of JSR 352.
The SimplePayrollJob batch job involves reading input data for payroll processing from a comma-separated values (CSV) file. Each line in the file contains an employee ID and the base salary (per month) for one employee. The batch job then calculates the tax to be withheld, the bonus, and the net salary. The job finally needs to write out the processed payroll records into a database table.
We use a CSV file in this example just to demonstrate that JSR 352 allows batch applications to read and write from any arbitrary source.

Job specification language for the Payroll processing application

We discussed that a step is a domain object that encapsulates an independent, sequential phase of the job, and a job is basically a container for one or more steps.
In JSR 352, a JSL basically specifies the order in which steps must be executed to accomplish the job. The JSL is powerful enough to allow conditional execution of steps, and it also allows each step to have its own properties, listeners, and so on.
A batch application can have as many JSLs as it wants, thus allowing it to start as many batch jobs as required. For example, an application can have two JSLs, one for payroll processing and another for report generation. Each JSL must be named uniquely and must be placed in the META-INF/batch-jobs directory. Subdirectories under META-INF/batch-jobs are ignored.
Our JSL for payroll processing is placed in a file called SimplePayrollJob.xml and looks like Listing 1:
<job id="SimplePayrollJob" xmlns=http://xmlns.jcp.org/xml/ns/javaee version="1.0">
    <step id="process">
        <chunk item-count="2">
            <reader ref="simpleItemReader/>
            <processor ref="simpleItemProcessor/>
            <writer ref="simpleItemWriter/>
        </chunk>
    </step>
</job>

Our SimplePayrollJob batch job has just one step (called "process"). It is a chunk-style step and has (as required for a chunk-style step), an ItemReader, an ItemProcessor, and an ItemWriter. The implementations for ItemReader, ItemProcessor, andItemWriter for this step are specified using the ref attribute in the <reader>, <processor>, and <writer> elements.
When the job is submitted (we will see later how to submit batch jobs), the batch runtime starts with the first step in the JSL and walks its way through until the entire job is completed or one of the steps fails. The JSL is powerful enough to allow both conditional steps and parallel execution of steps, but we will not cover those details in this article.
The item-count attribute, which is defined as 2 in Listing 1, defines the chunk size of the chunk.
Here is a high-level overview of how chunk-style steps are executed. Please see section "Regular Chunk Processing" of the JSR 352 specification for more details.
  1. Start a transaction.
  2. Invoke the ItemReader and pass the item read by the ItemReader to the ItemProcessor. ItemProcessor processes the item and returns the processed item to the batch runtime.
  3. The batch runtime repeats Step 2 item-count times and maintains a list of processed items.
  4. The batch runtime invokes the ItemWriter that writes item-count number of processed items.
  5. If exceptions are thrown from ItemReader, ItemProcessor, or ItemWriter, the transaction fails and the step is marked as "FAILED." Please refer to Section 5.2.1.2.1 ("Skipping Exceptions") in the JSR 352 specification.
  6. If there are no exceptions, the batch runtime obtains checkpoint data from ItemReader and ItemWriter (see section 2.5 in the JSR 352 specification for more details). The batch runtime commits the transaction.
  7. Steps 1 through 6 are repeated if the ItemReader has more data to read.
This means that in our example, the batch runtime will read and process two records and the ItemWriter will write out two records per transaction.

Writing the ItemReader, ItemProcessor and ItemWriter

Writing the ItemReader

Our payroll processing batch JSL defines a single chunk style step and specifies that the step uses an ItemReader namedsimpleItemReader. Our application contains an implementation of ItemReader to read input CSV data. Listing 2 shows a snippet of our ItemReader:

@Named
public class SimpleItemReader
       extends AbstractItemReader {

       @Inject
       private JobContext jobContext; 
       ...
}

Note that the class is annotated with the @Named annotation. Because the @Named annotation uses the default value, the Contexts and Dependency Injection (CDI) name for this bean is simpleItemReader. The JSL specifies the CDI name of the ItemReader in the<reader> element. This allows the batch runtime to instantiate (through CDI) our ItemReader when the step is executed.
Our ItemReader also injects a JobContext. JobContext allows the batch artifact (ItemReader, in this case) to read values that were passed during job submission.
Our payroll SimpleItemReader overrides the open() method to open the input from which payroll input data is read. As we shall see later, the parameter prevCheckpointInfo will not be null if the job is being restarted.
In our example, the open() method, which is shown in Listing 3, opens the payroll input file (which has been packaged along with the application).
public void open(Serializable prevCheckpointInfo) throws Exception {
        JobOperator jobOperator = BatchRuntime.getJobOperator();
        Properties jobParameters = jobOperator.getParameters(jobContext.getExecutionId());
        String resourceName = (String) jobParameters.get("payrollInputDataFileName");
        inputStream = new FileInputStream(resourceName);        
        br = new BufferedReader(new InputStreamReader(inputStream));

        if (prevCheckpointInfo != null)
            recordNumber = (Integer) prevCheckpointInfo;
        for (int i=1; i<recordNumber; i++) {   //Skip upto recordNumber
            br.readLine();
        } 
       System.out.println("[SimpleItemReader] Opened Payroll file for reading from record number: "              + recordNumber);
    }

The readItem() method basically reads one line of data from the input file and determines whether the line contains two integers (one for employee ID and one for base salary). If there are two integers, it creates and returns a new instance of PayrollInputRecord and returns to the batch runtime (which is then passed to ItemWriter).
Listing 4
public Object readItem() throws Exception {       
       Object record = null;
       if (line != null) {
            String[] fields = line.split("[, \t\r\n]+");
            PayrollInputRecord payrollInputRecord = new PayrollInputRecord();
            payrollInputRecord.setId(Integer.parseInt(fields[0]));
            payrollInputRecord.setBaseSalary(Integer.parseInt(fields[1]));
            record = payrollInputRecord;
            //Now that we could successfully read, Increment the record number
           recordNumber++;
        }
        return record;
}

The method checkpointInfo() is called by the batch runtime at the end of every successful chunk transaction. This allows the Reader to check point the last successful read position.
In our example, the checkpointInfo() returns the recordNumber indicating the number of records that have been read successfully, as shown in Listing 5.
@Override
public Serializable checkpointInfo() throws Exception {
        return recordNumber;
}

Writing the ItemProcessor

Our SimpleItemProcessor follows a pattern similar to the pattern for SimpleItemReader.

The processItem() method receives (from the batch runtime) the PayrollInputRecord. It then calculates the tax and net and returns a PayrollRecord as output. Notice in Listing 6 that the type of object returned by an ItemProcessor can be very different from the type of object it received from ItemReader.

@Named
public class SimpleItemProcessor
    implements ItemProcessor {

    @Inject
    private JobContext jobContext;

    public Object processItem(Object obj) 
                        throws Exception {
        PayrollInputRecord inputRecord =
                (PayrollInputRecord) obj;
        PayrollRecord payrollRecord = 
                new PayrollRecord();

        int base = inputRecord.getBaseSalary();
        float tax = base * 27 / 100.0f;
        float bonus = base * 15 / 100.0f;

        payrollRecord.setEmpID(inputRecord.getId());
        payrollRecord.setBase(base);
        payrollRecord.setTax(tax);
        payrollRecord.setBonus(bonus);
        payrollRecord.setNet(base + bonus - tax);   
        return payrollRecord;
    } 
}

Writing the ItemWriter 

By now, SimpleItemWriter must be following predictable lines for you.
The only difference is that it injects an EntityManager so that it can persist the PayrollRecord instances (which are JPA entities) into a database, as shown in Listing 7.
@Named
public class SimpleItemWriter
    extends AbstractItemWriter {

    @PersistenceContext
    EntityManager em;

    public void writeItems(List list) throws Exception {
        for (Object obj : list) {
            System.out.println("PayrollRecord: " + obj);
            em.persist(obj);
        }
    }
    
}
The writeItems() method persists all the PayrollRecord instances into a database table using JPA. There will be at most item-count entries (the chunk size) in the list.
Now that we have our JSL, ItemReader, ItemProcessor, and ItemWriter ready, let's see how a batch job can be submitted.

Starting a batch job from a servlet

Note that the mere presence of a job XML file or other batch artifacts (such as ItemReader) doesn't mean that a batch job is automatically started when the application is deployed. A batch job must be initiated explicitly, say, from a servlet or from an Enterprise JavaBeans (EJB) timer or an EJB business method.
In our payroll application, we use a servlet (named PayrollJobSubmitterServlet) to submit a batch job. The servlet displays an HTML page that presents to the user a form containing two buttons. When the first button, labeled Calculate Payroll, is clicked, the servlet invokes the startNewBatchJob method, shown in Listing 8, which starts a new batch job.

private long startNewBatchJob()
throws Exception {
        JobOperator jobOperator = BatchRuntime.getJobOperator();
        Properties props = new Properties();
        props.setProperty("payrollInputDataFileName", payrollInputDataFileName);
        return jobOperator.start(JOB_NAME, props);
}

The first step is to obtain an instance of JobOperator. This can be done by calling the following:
JobOperator jobOperator = BatchRuntime.getJobOperator(); 

The servlet then creates a Properties object and stores the input file name in it. Finally, a new batch job is started by calling the following:
jobOperator.start(jobName, properties) 

The jobname is nothing but the job JSL XML file name (minus the .xml extension). The properties parameter serves to pass any input data to the job. The Properties object (containing the name of the payroll input file) is made available to other batch artifacts (such as ItemReader, ItemProcessor, and so on) through the JobContext interface.
The batch runtime assigns a unique ID, called the execution ID, to identify each execution of a job whether it is a freshly submitted job or a restarted job. Many of the JobOperator methods take the execution ID as parameter. Using the execution ID, a program can obtain the current (and past) execution status and other statistics about the job. The JobOperator.start() method returns the execution ID of the job that was started.

Retrieving details about batch jobs

When a batch job is submitted, the batch runtime creates an instance of JobExecution to track it. JobExecution has methods to obtain various details such as the job start time, job completion time, job exit status, and so on. To obtain the JobExecution for an execution ID, you can use the JobOperator.getJobExecution(executionId) method. Listing 9 shows the definition of JobExecution:

package javax.batch.runtime;
public interface JobExecution {
    long getExecutionId();
    java.lang.String getJobName();
    javax.batch.runtime.BatchStatus getBatchStatus();
    java.util.Date getStartTime();
    java.util.Date getEndTime();
    java.lang.String getExitStatus();
    java.util.Date getCreateTime();
    java.util.Date getLastUpdatedTime();
    java.util.Properties getJobParameters();
}

“Ultra-irresponsible” Firefox devs attacked for Java block

Java now requires explicit permission to run in the latest version of Firefox, thanks to a patch that rolled out late last week.
Developers at Mozilla, the not-for-profit behind Firefox, are hoping that it will help protect end users from the notoriously unsafe browser plugin – but many have complained that the move has disrupted their businesses (and even the entire nation of Denmark).
Since January, the browser has already blocked out-of-date (and vulnerable) versions of Java. However, in the wake of a particularly nasty SSL-decrypting exploit, Firefox devs made the decision to prevent any version of Java from auto-running.
The blocks were implemented last week, displaying an ominous red dialog (or an easy-to-miss icon, shown below) when users land on a page with a Java applet.

Despite the move being made with the best possible intentions, by the end of the weekend the bug ticket began to fill up with complaints from irate users.
“Have you all suddenly gone insane?” asked one, a user named ‘ipatrol’, who compared the situation to a Dilbert comic in which a character proclaims: “Security is more important than usability.” Others were even less kind: one described the move as “ultra-irresponsible”.
“Our company and our users are legitimate users of Firefox,” wrote a software engineer at Ephox, which produces in-browser rich text editing software. “We have needs and requirements - one of those is for Java to work.”
Users of outdated government sites appeared to be particularly affected. “It affects all citizens of Denmark, as the national login is blocked,” noted one commenter. Another, claiming to work in Spanish local government, said that “just about ever [sic] ministerial applet is written in JAVA - and since yesterday we're screwed”.
And the comments kept coming. “Our business depends on using some java applications,” said one sysadmin. “Blocking java the way you did it, simply means: We can't use Firefox in our company anymore.”
Mozillans attempted to point out that Java was still a couple of clicks away, and that sysadmins can enable Java en masse with a Click-To-Play manager plugin. However, commenters emphasised the difficulty of educating users about the changes, and some even claimed that the click-to-play dialog did not appear for them.
Firefox’s developers are not the first to shield users from Java applets. The Chrome team implemented a similar – if less alarmist – permissions dialog over a year ago, and the latest version of Java already has a similar dialog by default across all browsers.
Still, Mozilla’s bold move appears to have a struck a nerve – even if it may be among a relative minority. For better or worse, Java applets are still crucial to a number of web users.

Google ditches Oracle for MySQL fork MariaDB

Monty Widenius has always regretted not taking more action to block his creation MySQL from being owned by Oracle when it took over Sun Microsystems in 2010 - and whilst it’s hard to forget your first love, there’s nothing more satisfying than getting one up on your ex. Widenius must be pretty gleeful, then, to have lured Google across to MariaDB, his new open-source database project.
Google hasn’t made any official announcements about the switch, but Google senior systems engineer Jeremy Cole broke the news at the Extremely Large Databases (XLDB) conference in Stanford as part of a presentation on the general state of the MySQL ecosystem.
In an interview with the Register, Cole stated that, whilst MariaDB and MySQL were “more or less equivalent other than if you look at specific features and how they implement them," the big difference was the ideologies behind them - namely, the fact that many, Widenius included, see My SQL as ‘neutered’ to the point of no longer being truly open source.
Oracle might care to disagree with this, considering the source code is still released under a GPL license, but many remain unconvinced. In fact, the Googler went as far as to claim that Oracle “ignores bugs, feedback, communication from community”, and that development is “often without much public visibility until release”.
Cole explained that, since version 4.0, Google has been running a bespoke version of MySQL 5.1, but is now shifting to MariaDB 10.0, which is roughly the same as MySQL 5.6. As a result, Google has been working to make sure that the transition is as seamless as possible by identifying and changes that have occurred since 5.1.
Google’s move to MariaDB is likely to be interpreted by many as a an attempt to disentangle itself from a dependence on Oracle technology. It’s been working with the MariaDB Foundation since the beginning of the year to smooth over any problems, and there are currently five Google technicians working part-time on MariaDB patches and bug fixes.
With Google on board, MariaDB is now packing a considerable punch. Red Hat is also following Google in trading MySQL for MariaDB in Red Hat Enterprise Linux 7, and with the general antipathy towards Oracle’s NoSQL stance, no doubt Widenius is basking in the warm glow of schadenfreude

Apache Camel tunes its core with new release

The community around open-source integration framework Apache Camel is a prolific little hub, and in the space of just four and a half months, has put together a shiny new release -  Apache Camel 2.12 - the 53rd Camel version to date.

On the menu for developers is a total of 17 new components, four new examples, and souped-up performance in simple or bean languages and general routing. More than three hundred JIRA tickets have been solved, and a lot of bug swatting and general fine tuning has taken place. Reflecting the hugely active community around the platform, around half of these  new components come courtesy of external contributors, and the rest from Camel team developers.
Fulltime Apache Camel committer Claus Ibsen notes in his blog that this is the first release where steps have been taken to “allow Camel components documentation in the source code which gets generated and included in the binaries.” He also writes that “a Camel component can offer endpoint completion which allows tooling to offer smart completion”, citing the hawtio web console as an example of the ways in which this enables functions like auto completion for JMS queue names, file directory names, bean names in the registry.
Another notable development is the effective displacement of the camel-seda by the camel-disruptor, which by utilising the LMAX Disruptor provides SEDA behaviour in Camel.
There have also been some tunings of the camel-core to improve usability. This includes a reduction of stack-frames during routing making logging Camel’s stack traces less clunky, and reducing the need for AsyncCallback callbacks during routing. Stream caching configuration has become more simple with StreamCachingStrategy, and New FlexibleAggregationStrategy now acts as, “a one-stop to perform typical aggregation strategy logic out-of-the-box: filtering results, storing them in properties, headers or bodies, as a list, casting results, etc.”
Finally, for camel’s increasingly sociable user base,  camel-yammer and camel-facebook have been added to help integrate applications with social network APIs. And those on the sales side will now be able to use camel-salesforce to write integration code for platform.
You can download Apache Camel 2.12 here.

Oracle delivers a contradictory verdict on open-source


Oracle’s distaste for genuine open-source is evident in so many ways. From its slow disengagement with the MySQL community, to the cloak and dagger approach it takes to Java security, it’s clear Larry Ellison et al would much prefer to keep their cards and code very close to their chests.


And then there’s the less subtle things. The software Sauron’s approach to open source is made resoundingly obvious in new Oracle, white paper titled “The Department of Defence (DoD) and Open Source Software”.
In it, Oracle delivers a damning critique of open source software - writing that the US DoD’s belief that it can save money by developing their own applications with open source software as a foundation is misguided. After a lengthy discussion, it arrives at the crux of its argument; it would be far better to just cough up and partner with Oracle, which, wouldn’t you know, has tons of open-source projects at its fingertips. That is, ones which “as needs grow” (so says the report) can be switched for “the commercial offering from Oracle”.
Although the paper does raise a few valid points, such as the fact that it would be more difficult to guarantee the security of open source- rooted software projects than those from one single source, the overall gist is that it would be ridiculous for the DoD to even contemplate turning to more diverse open-source for their development.
This paper comes at a time when the US government is wrangling with the repercussions of its decision to entrust its complex new health insurance registration service to one hapless vendor - an issue that actually underlines the advantages of open-sourcing.