Core Java

ActiveJ: A New, Alternative Java Platform

1. Meet ActiveJ!

ActiveJ is a new, open-source Java platform for quickly building efficient web, cloud, and microservices solutions for high performance environments.

ActiveJ is the result of developing a genuinely high-load, ad-serving infrastructure at AdKernel, an ad-tech platform serving over 200 billion requests per day. With over five years of development, we believe we have achieved the ambitious goal of creating a solution that overcomes the drawbacks of the prevailing Java ecosystems.

ActiveJ is a radically new platform – built from the ground up without a zoo of sub-optimal technologies and dependencies imposed by other frameworks.

The focus has been on simplicity, raw performance and consistency from the very bottom to top.

With this approach, developers can take their best from the platform and get rid of any constraints. ActiveJ allows you to create applications of any complexity: highload data processing platforms, game servers, scalable web apps with a microservices architecture, and much more.

How does it all work? Let’s find out!

2. Quick facts

But before we get into a more detailed description of ActiveJ platform, here’s a quick overview:

  • 15% faster than multithreaded Vert.x HTTP server, even on a single core and with 50% less overall CPU load
  • The full size of minimal ActiveJ web application with an embedded HTTP server is only 1.4MB compared to 17MB for Spring
  • ActiveJ web application launch time is 0.65sec compared to 14sec for Spring
  • ActiveJ DI library is 5.5 times faster than Guice and 100s times faster than Spring DI
  • ActiveJ Promise is 7 times faster than Java CompletableFuture
  • Features the fastest JVM-based Serializer in the world

Surely, benchmarks are very relative measurements, and there can be scenarios where ActiveJ won’t be that efficient in comparison with other solutions. Yet, they’re still worthy to explore to get an idea of ActiveJ performance. You can find the benchmark sources here.

3. ActiveJ Technologies

ActiveJ consists of loosely-coupled components that cover the full application stack. Most of them can be used as stand-alone libraries independently of the platform. Here is a list of the most important ActiveJ components:

3.1 Core

  • Lightweight, fast, and powerful Dependency Injection library named ActiveInject. Supports nested scopes, singletons and transient bindings, modules, optimized multi-threaded and single-threaded injectors. It has no third-party dependencies and can be used independently of ActiveJ platform.
  • ActiveJ has its own high-performance async I/O core (Eventloop, Promise, Net) and async data stream processing (CSP, Datastream)
  • High-performance async HTTP client and server (simple and efficient alternative to Jetty, Netty or Vert.x) (HTTP)
  • Application bootstrapping, lifecycle and management components (Launcher, Service Graph, JMX, Triggers).

3.2 Cluster technologies

  • ActiveRPC. A lightning-fast binary protocol for developing distributed applications and microservices solutions. It introduces an alternative approach to microservices implementation and overcomes the overheads of HTTP protocol with JSON or XML encoding. It is powered by ActiveSerializer, runs on TCP, and has a custom high-performance binary streaming protocol.
  • ActiveFS. Provides a tiny asynchronous abstraction on top of local FS, remote FS, or distributed file storage. It features a simple FTP-like protocol with zero-overhead streaming and supports data redundancy, rebalancing and resharding.
  • Specialized databases: CRDT server database, Operational Transformation (OT) database, OLAP database.

3.4 Bytecode manipulation tools

All these components can be used as stand-alone libraries.

  • ActiveSerializer. According to our measurements using a popular benchmark tool, it’s the fastest JVM-based serializer in the world. ActiveSerializer is implemented with runtime bytecode generation and introduces a schema-less approach for the best performance. It features full support of Java subclasses, collections (including graphs with circular references and also specialized collections like HPPC). Moreover, it supports plugins, extensions, versioning, and can be fine-tuned using Java annotations.
  • ActiveCodegen. Dynamic bytecode generator without the complexity of direct bytecode manipulation with a streamlined and concise API. It directly compiles Lisp-like AST tree expressions into bytecode, using automatic type inference with essentially zero overhead.
  • ActiveSpecializer. A unique technology that automagically speeds up your code by rewriting the bytecode in runtime. Unlike traditional compiler optimization techniques, it relies on a ground-breaking concept of using runtime information of classes instances. According to the benchmarks, ActiveSpecializer can make it 7 times faster.

4. It’s time to code!

Let’s create a simple ActiveJ application. We’ll use ActiveJ HTTP and ActiveInject DI components.

HTTP features a predefined HTTP client and server solutions for typical use-cases and has great performance. We’ll also use the Launcher module. Launcher is a highly-generalized abstraction over main method that takes care of application lifecycle, dependencies, and logging.

HelloWorld.java

public final class HttpHelloWorldExample extends HttpServerLauncher {
@Provides
AsyncServlet servlet() {
    return request -> HttpResponse.ok200().withPlainText("Hello World!");
}

public static void main(String[] args) throws Exception {
    Launcher launcher = new HttpHelloWorldExample();
    launcher.launch(args);
  }
}

We’ve extended HttpServerLauncher class which is a part of the Launcher module.

ActiveInject @Provides annotation will create an AsyncServlet that asynchronously receives an HTTP request from client and sends an HTTP response. In our case the response is a “Hello, World!” message. Finally, we simply use Launcher.launch method to start our server.

That’s it, we’ve just created an asynchronous fully-functioning high-performance server. Start your application and go to localhost:8080 to check it out. With ActiveInject you can simply extend the example and create more complex applications.

You can find this example source code on GitHub or read a more detailed description in ActiveJ docs.

5. Maximum performance with microservices architecture

That was a basic example that illustrated how streamlined ActiveJ is, but let’s dive into some of its most powerful features. Here, we’ll explore the high-performance ActiveRPC. It features highly optimized server and client implementation along with predefined cloud strategies for requests arrangement between servers or shards of servers (first available, round-robin, rendezvous hashing, etc.).

ActiveRPC allows combining such strategies. For example, here is how you can simply manage a pool of 4 connections using first available and round-robin strategies.

RpcRoundRobin.java

RpcStrategy strategy = roundRobin(
firstAvailable(servers(ADDRESS_1, ADDRESS_2)),
firstAvailable(servers(ADDRESS_3, ADDRESS_4)));

And that’s it, you can extend the amount of connections, apply different strategies, and your application will be able to handle high load scenarios out of the box.

You can find ActiveRPC examples on GitHub or in ActiveRPC docs.

6. Something even more specific

ActiveJ platform features the ActiveSpecializer library, which is an absolutely unique solution that “automagically” optimizes your code in runtime.

ActiveSpecializer rewrites your code directly in runtime, using runtime information contained in the instances of your classes. In particular, all class fields are transformed into static class fields, and all virtual methods calls are de-virtualized and replaced with static method calls.

For example, let’s see how a typical AST expressions tree f(x) = ((x + 5) - 5) * (-1) can be optimized and de-virtualized.

SpecializerExample.java

static IntUnaryOperator INT_UNARY_OPERATOR =
    new IntUnaryOperatorProduct(
        new IntUnaryOperatorSum(
            new IntUnaryOperatorSum(
                 new IntUnaryOperatorIdentity(),
                 new IntUnaryOperatorConst(5)),
            new IntUnaryOperatorConst(-5)),
         new IntUnaryOperatorConst(-1));

static IntUnaryOperator INT_UNARY_OPERATOR_SPECIALIZED_MANUALLY =
    new IntUnaryOperator() {
        @Override
        public int applyAsInt(int x) {
            return -x;
        }
    };

static IntUnaryOperator INT_UNARY_OPERATOR_SPECIALIZED =
    SPECIALIZER.specialize(INT_UNARY_OPERATOR);

According to the benchmarks, the original equation was operated in 69.938 ns, while the manually and automatically specialized took only 26.533 ns and 26.691 ns respectively.

Yet, ActiveSpecializer goes far beyond the arithmetical equations. For example, it proved its efficiency with ActiveInject, boosting it up by 30%.

You can find ActiveSpecializer examples on GitHub or in ActiveSpecializer docs.

7. Summing up

ActiveJ offers developers a fundamentally new holistic development platform that provides tools for creating diverse modern applications of any complexity with a lightweight and natively scalable async architecture, squeezing the last bits of performance from your hardware.

We’ve covered only a small fraction of ActiveJ possibilities and hope you’ll give it a try to experience its performance, clear design and flexibility. ActiveJ is an open-source project, so you’re welcome on our GitHub repository! Should you have any questions, ideas or suggestions, we’re eager to discuss them.

Valeria Listratova

Valeria is a content manager at Active LLC who started her career as a Java developer. She has been working on ActiveJ project for more than 2 years, participating in the evolution of the platform and creation of ground-breaking technologies. Now she’s eager to share the results of the team’s work with the community.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Michael
Michael
4 years ago

Hi, you advertise ActiveJ as a platform. There Java Runtime would be a platform or an Application Server or Open shift.

What you are providing is a framework one can use to build applications. It sounds as if the framework components are loosely
coupled.

Wish you success with ActiveJ.

Regards
Michael

Joko Pitoyo
Joko Pitoyo
3 years ago

Really interest migrate to activeJ, but really limited sample code…

Back to top button