Child pages
  • Changes Between 2.x and 1.x
Skip to end of metadata
Go to start of metadata

Apache MINA 2.x provides a new API that is partly backward-incompatible from 1.x. Sacrificing backward-compatibility somewhat, 2.x simplifies the overly complex part of the previous API into more intuitive one. Please note that this document explains incompatible changes only, because most part of the API is backward-compatible.

Table of contents

Packaging and naming

All classes and methods follow camel notation strictly.

For example, SSLFilter has been renamed to SslFilter, and many more.

All NIO transport classes has 'Nio-' prefix in their names.

Because NIO will not be the only socket/datagram transport implementation, 'Nio-' prefix has bee prepended to all NIO transport classes.

Before:

SocketAcceptor acceptor = new SocketAcceptor();

After:

SocketAcceptor acceptor = new NioSocketAcceptor();

Filter classes have been reorganized into multiple subpackages.

As the number of out-of-the-box filter implementations increase, all filters have been moved into appropriate subpackages (e.g. StreamWriteFilter into org.apache.mina.filter.stream).

*.support packages have been moved up to its parent package (or somewhere else)

All classes in *.support packages have moved up to its parent package or somewhere else to fix cyclic dependency. You can simply reorganize your imports to fix any consequent compilation errors in your IDE (e.g. Eclipse).

Buffers

MINA ByteBuffer has been renamed to IoBuffer

Many users found difficulty of communication with their teammates because MINA ByteBuffer has the same class name with NIO ByteBuffer. Based on user feed back, we renamed MINA ByteBuffer to IoBuffer, which takes less keystrokes and unambiguous.

Buffer pooling has been removed, and IoBuffer.allocate(int) allocates a heap buffer by default.

  • No more error-prone acquire() and release()** You can call free() instead if you want, but it's completely optional. Please use at your own risk.
  • Better out-of-the-box performance and stability in most JVMs

Direct buffer pooling was one of the cool features that MINA advertised in early days. According to recent benchmarks, however, direct buffers are known to perform worse than heap buffers in most modern JVMs. Moreover, unexpected OutOfMemoryError is often thrown if the maximum direct buffer memory is not configured properly.

To provide out-of-the-box best performance and stability, the Apache MINA project team decided to change the default buffer type from 'direct' to 'heap'. Because heap buffers don't need any pooling, PooledByteBufferAllocator has been removed. ByteBuffer.acquire() and ByteBuffer.release() also have been removed, because there's no pooling anymore.

However, there's a case that allocation of heap buffers becomes bottleneck if the allocation occurs too fast. It's because any allocation of byte arrays requires filling up the content of the array with '0', which consumes memory bandwidth. CachedBufferAllocator is provided to address this concern, but you won't need to change the default SimpleBufferAllocator in most cases.

Bootstrapping and configuration

IoService configuration has been simplified.

In 1.x, IoService and its sub-interfaces (i.e. IoAcceptor and IoConnector) had many ways to configure itself. Basically, it had two ways to configure a service:

  • Specifying an IoServiceConfig with bind() or connect() call explicitly.
    SocketAcceptor acceptor = new SocketAcceptor();
    SocketAcceptorConfig myServiceConfig = new SocketAcceptorConfig();
    myServiceConfig.setReuseAddress(true);
    acceptor.bind(myHandler, myServiceConfig);
    
  • Using IoService.defaultConfig property, which is employed when no IoServiceConfig is specified.
    SocketAcceptor acceptor = new SocketAcceptor();
    acceptor.getDefaultConfig().setReuseAddress(true);
    acceptor.bind(new InetSocketAddress(8080), myHandler);
    

Configuring an IoFilterChain brings another headache. In IoService, there's an additional global IoFilterChainBuilder besides the IoFilterChainBuilder in an IoServiceConfig. This means that two IoFilterChainBuilders are used to configure one IoFilterChain. Most users configure an IoFilterChain using only the global IoFilterChainBuilder and find that's enough.

IoAcceptor acceptor = new SocketAcceptor();
acceptor.getFilterChain().addLast("myFilter1", new MyFisrtFilter());
acceptor.getDefaultConfig().getFilterChain().addLast("myFilter2", new MySecondFilter());
acceptor.bind(new InetSocketAddress(8080), myHandler); // Which filter will be the first?

To address this complication, MINA 2.0 simplified the API to enable easy bootstrapping of your network application. Please compare the following code to the previous examples.

SocketAcceptor acceptor = new SocketAcceptor();
acceptor.setReuseAddress(true);
acceptor.getFilterChain().addLast("myFilter1", new MyFirstFilter());
acceptor.getFilterChain().addLast("myFilter2", new MySecondFilter());
acceptor.getSessionConfig().setTcpNoDelay(true);

// You can specify more than one addresses to bind to multiple addresses or interface cards.
acceptor.setLocalAddress(new InetSocketAddress(8080));
acceptor.setHandler(myHandler);

acceptor.bind();

// New API restricts one bind per acceptor, and  you can't bind more than once.
// The following statement will raise an exception.
acceptor.bind();

You might already have noticed that Spring framework integration became much easier, too.

Threading

ThreadModel has been removed.

ThreadModel was initially introduced to simplify the process to apply a predefined thread model to an IoService. However, configuring most thread models has turned out to be too simple to introduce any new construct. ThreadModeal caused a lot of confusion rather than ease of use. In 2.x, you have to add an ExecutorFilter by yourself explicitly, of course only when you want to add it.

ExecutorFilter maintains the order of events only with a certain Executor implementation.

In 1.x, ExecutorFilter maintained the order of events whatever Executor you specified. In 2.0, instead, two new ThreadPoolExecutor implementations are provided; OrderedThreadPoolExecutor and UnorderedThreadPoolExecutor. ExecutorFilter maintains the order of the events only when:

  • it's constructed via a convenience constructor, which creates a new OrderedThreadPoolExecutor or
  • OrderedThreadPoolExecutor is specified explicitly.

OrderedThreadPoolExecutor and UnorderedThreadPoolExecutor also has prevention mechanism against OutOfMemoryError, so you will prefer these two classes to other Executor implementations probably.

Protocol codec

DemuxingProtocolCodecFactory has been rewritten.

DemuxingProtocolEncoder and DemuxingProtocolDecoder have been added. DemuxingProtocolCodecFactory is just a facade to these two classes now. register() methods have been renamed to addMessageEncoder() and addMessageDecoder(). This change gives more freedom to a codec implementor by allowing mix-up of different encoders and decoders.

MessageEncoder interface also has been changed. MessageEncoder.getMessageTypes() method has been removed; you have to specify the type of the message that the encoder can encode when you call addMessageEncoder() instead.

Integration

JMX integration has been rewritten

JMX integration has been completely re-written. Most of the old code has been discarded. The latest JMX integration module is based on Model MBeans and uses OGNL for property management.

Refer to Image Server example for JMX Integration details.

Spring integration has been simplified

Spring integration has been significantly re-weritten and simplified. Sumamry of changes is as given below

  • Package org\apache\mina\integration\spring\ssl has been removed
  • The package org.apache.mina.integration.spring has been renamed as org.apache.mina.integration.xbean, to decouple from Spring and support other DI frameworks
  • The new integration is based on integration beans package, as specified above

Refer to Chat example for latest Spring integration details

Miscellaneous changes

TransportType has been renamed to TransportMetadata.

It has been renamed because its role is rather metadata than just an enumeration.

IoSessionLogger has been rewritten.

IoSessionLogger now implements SLF4J Logger interface so you can declare it as Logger type like it's a plain SLF4J logger instance, which makes you don't need to expose IoSessionLogger to other party unnecessarily. Please also consider using MdcInjectionFilter which simply makes IoSessionLogger unnecessary at all by using MDC (supported by Log4J and Logback).

Before:

IoSessionLogger.debug(session, ...);

After:

Logger logger = IoSessionLogger.getLogger(session);
logger.debug(...);

BroadcastIoSession has been merged into IoSession.

ReadThrottleFilterBuilder has been replaced with ReadThrottleFilter and finally removed.

Check this thread for more details : http://www.nabble.com/Dropping-traffic-throttling-from-2.0-td16092085.html

  • No labels