ActiveJ is an alternative Java platform built from the ground up. ActiveJ redefines web, high load, and cloud programming in Java, featuring ultimate performance and scalability!

Overview

Maven Central GitHub

Introduction

ActiveJ is a full-featured modern Java platform, created from the ground up as an alternative to Spring/Micronauts/Netty/Jetty. It is designed to be self-sufficient (no third-party dependencies), simple, lean and to provide ultimate performance. ActiveJ consists of a range of libraries, from dependency injection and high-performance async I/O (inspired by Node.js), to application servers and big data solutions. You can use ActiveJ to build scalable web applications, distributed systems and use it for high-load data processing.

ActiveJ components

ActiveJ consists of several modules that can be logically grouped into following categories :

  • Async.io - High-performance asynchronous IO with efficient event loop, NIO, promises, streaming and CSP. Alternative to Netty, RxJava, Akka and others. (Promise, Eventloop, Net, CSP, Datastream)
  • HTTP - High-performance HTTP server and client with WebSocket support. Can be used as a simple web server or as an application server. An alternative to Jetty and other conventional HTTP clients and servers. (HTTP)
  • ActiveJ Inject - Lightweight powerful dependency injection library. Optimized for fast application start-up and ultimate runtime performance. Supports annotation-based component wiring as well as reflection-free wiring. (ActiveJ Inject)
  • Boot - Production-ready tools for launching and monitoring ActiveJ application. Concurrently starts and stops services based on their dependencies. Various service monitoring utilities with the support of JMX and Zabbix. (Launcher, Service Graph, JMX, Triggers)
  • Bytecode manipulation
    • ActiveJ Codegen - Dynamic class and method bytecode generator on top of ObjectWeb ASM library. Abstracts the complexity of direct bytecode manipulation and allows creating custom classes on the fly using Lisp-like AST expressions. (ActiveJ Codegen)
    • ActiveJ Serializer - Extremely fast and space-efficient serializers created with bytecode engineering. Introduces schema-less approach for the best performance. (ActiveJ Serializer)
    • ActiveJ Specializer - Innovative technology for enhancing class runtime performance by automatically transforming class instances into specialized static classes, and class instance fields into baked-in static fields. Enables a wide variety of JVM optimizations for static classes, not possible otherwise: dead code elimination, aggressively inlining methods, and static constants. (ActiveJ Specializer)
  • Cloud components
    • ActiveJ FS - Asynchronous abstraction over file system for building efficient, scalable local or remote file storages, supporting data redundancy, rebalancing, and resharding. (ActiveJ FS)
    • ActiveJ RPC - Ultra high-performance binary client-server protocol. Allows building distributed, sharded and fault-tolerant microservices applications. (ActiveJ RPC)
    • Various extra services: ActiveJ CRDT, Redis client, Memcache, OLAP Cube, Dataflow

Quick start

Insert this snippet to your terminal...

mvn archetype:generate -DarchetypeGroupId=io.activej -DarchetypeArtifactId=archetype-http -DarchetypeVersion=5.1

... and open the project in your favourite IDE. Then, build the application and run it. Open your browser on localhost:8080 to see the "Hello World" message.

Fully-featured embedded web application server with Dependency Injection:

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);
	}
}

Some technical details regarding the above example:

  • Features a JAR file size of only 1.4 MB. In comparison, a minimal Spring web app size is approximately 17 MB.
  • The cold start time is 0.65 sec.
  • The ActiveJ Inject DI library which is used, is 5.5 times faster than Guice and hundreds of times faster than Spring.

To learn more about ActiveJ, please visit https://activej.io or follow our 5-minute getting-started guide.

Examples for usage of the ActiveJ platform and all the ActiveJ libraries can be found in examples module.

Release notes for ActiveJ can be found here

Comments
  • ActiveJ Redis client and Redis ACL.

    ActiveJ Redis client and Redis ACL.

    The Redis client is working great for us. Thank you. However, we enabled AUTH on the test server, and some hell broke loose.

    We added AUTH right after connecting but we seem to be missing something because Redis complains about AUTH for some of our requests. Even ActiveJ unit tests fail GETTTT/SETTT tests. We're still debugging the exception handler. However a good majority of messages go through without issues. Any hints where to look?

    Peripherally, is there a need for connection pooling or do we just throw multiple @Workers at it because this puppy is very robust (no dangling connections), and it is Real Fast(tm)?

    Thank you for ActiveJ it has been a pleasure to work with.

    opened by a1730 12
  • FileUploadExample does not finish

    FileUploadExample does not finish

    File upload in FileUploadExample does not finish properly, I don't get "File 'example.txt' successfully uploaded" as expected, it just keeps waiting forever. However I can see in the GUI that 'example.txt' is there with "example text" in it.

    Tested on: 9f08c20efe309f13d248b81cba48d191f27f9e45 (revision number)

    opened by arsentiikaptsan 11
  • SerializeNullable annotation not work

    SerializeNullable annotation not work

    protocol

    public class GetUserIdByIdRes {
        private @SerializeNullable byte[] userId;
    
        public GetUserIdByIdRes(@Deserialize("userId") byte[] userId) {
            this.userId = userId;
        }
    
        @Serialize
        public byte[] getUserId() {
            return userId;
        }
    }
    

    exception

    java.util.concurrent.ExecutionException: io.activej.rpc.protocol.RpcRemoteException: java.lang.NullPointerException
    	at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
    	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1928)
    	at com.test.rookiedb.rpc.RookieClient.multiGet(RookieClient.java:150)
    	at com.test.rookiedb.rpc.RookieClient.getUserIdById(RookieClient.java:168)
    	at com.test.rookiedb.RookieDbEngine.getUserIdById(RookieDbEngine.java:190)
    	at com.test.BaseEngine.read(BaseEngine.java:164)
    	at com.test.DefaultEngine.read(DefaultEngine.java:116)
    	at com.test.DefaultEngineTest$ReadTask.run(DefaultEngineTest.java:161)
    	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    	at java.util.concurrent.FutureTask.run(FutureTask.java)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at java.lang.Thread.run(Thread.java:748)
    Caused by: io.activej.rpc.protocol.RpcRemoteException: java.lang.NullPointerException
    
    opened by xsank 10
  • Ambiguous services found

    Ambiguous services found

    Hello,

    I'm trying to run the example here but I receive the following error and I have no idea what I'm doing wrong or it's a bug in the framework itself?

    Exception in thread "main" java.lang.IllegalArgumentException: Ambiguous services found for class com.zaxxer.hikari.HikariDataSource : [interface java.io.Closeable, interface javax.sql.DataSource]. Use register() methods to specify service.
    	at io.activej.service.ServiceGraphModule.doLookupAdapter(ServiceGraphModule.java:600)
    	at io.activej.service.ServiceGraphModule.lookupAdapter(ServiceGraphModule.java:570)
    	at io.activej.service.ServiceGraphModule.getServiceOrNull(ServiceGraphModule.java:542)
    	at io.activej.service.ServiceGraphModule.getCombinedServiceOrNull(ServiceGraphModule.java:474)
    	at io.activej.service.ServiceGraphModule.doStart(ServiceGraphModule.java:428)
    	at io.activej.service.ServiceGraphModule.doStart(ServiceGraphModule.java:401)
    	at io.activej.service.ServiceGraphModule.lambda$serviceGraph$3(ServiceGraphModule.java:283)
    	at io.activej.service.ServiceGraph.startFuture(ServiceGraph.java:278)
    	at io.activej.service.ServiceGraphModule$1.start(ServiceGraphModule.java:296)
    	at io.activej.launcher.Launcher.startServices(Launcher.java:235)
    	at io.activej.launcher.Launcher.launch(Launcher.java:158)
    	at ship.cars.dataone.WebApp.main(WebApp.java:73)
    

    My snippet

    import com.zaxxer.hikari.HikariDataSource;
    import io.activej.config.Config;
    import io.activej.http.AsyncServlet;
    import io.activej.http.HttpResponse;
    import io.activej.inject.annotation.Inject;
    import io.activej.inject.annotation.Provides;
    import io.activej.inject.module.AbstractModule;
    import io.activej.inject.module.Module;
    import io.activej.inject.module.Modules;
    import io.activej.launcher.Launcher;
    import io.activej.launchers.http.MultithreadedHttpServerLauncher;
    import io.activej.promise.Promise;
    import io.activej.service.ServiceGraphModule;
    import ship.cars.dataone.utils.HikariConfigConverter;
    
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    
    public class WebApp extends MultithreadedHttpServerLauncher {
        @Inject
        DataSource dataSource;
    
        @Override
        protected void run() {
            try (Connection connection = dataSource.getConnection();
                 Statement statement = connection.createStatement()
            ) {
                statement.executeUpdate("SELECT NOW();");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        protected void onStart() {
            System.out.println("TABLES BEFORE:");
        }
    
        @Override
        protected Module getOverrideModule() {
            return Modules.combine(
                    ServiceGraphModule.create(),
                    // db module
                    new AbstractModule() {
                        @Provides
                        DataSource dataSource(Config config) {
                            HikariConfigConverter converter = HikariConfigConverter.create().withAllowMultiQueries();
                            return new HikariDataSource(config.get(converter, "hikari"));
                        }
                    }
            );
        }
    
        @Provides
        AsyncServlet servlet() {
            return request -> Promise.of(
                    HttpResponse.ok200()
                        .withPlainText("Hello, World!"));
        }
    
        public static void main(String[] args) throws Exception {
            Launcher launcher = new WebApp();
            launcher.launch(args);
        }
    }
    

    Thank you in advance :)

    opened by vencivenc 10
  • Do not enforce .class on bytecode output path.

    Do not enforce .class on bytecode output path.

    The output path should actually be the output path and not the file name with an enforced extension just so developers can have custom file extentions.

    opened by alphaqu 10
  • CodeGen API Simplification

    CodeGen API Simplification

    I believe the codegen API can be simplified. E.g.

    .withMethod("setIdAndName", sequence(
    				set(property(self(), "id"), arg(0)),
    				set(property(self(), "name"), arg(1))))
    

    can become

    .method("setIdAndName").args("id", "name").of(int.class, String.class).body(statements(assign("this.id", "this.name").to("id", "name")))
    

    or

    .method("setIdAndName").body(assign("this.id", "this.name").to("id", "name"))
    

    as Person defines the arguments and types this is implied.

    Similarly

    .withField("id", int.class)
    ...
    .withMethod("getId", property(self(), "id"))
    

    can become

    .getter("id", int.class)
    

    Also,

    .withMethod("hashOfPojo", hash(property(arg(0), "id"), property(arg(0), "name")))
    

    can become

    .method("hashOfPojo").args("personPojo").of("ExamplePojo").returning(int.class).body(statements(returning(hash("personPojo.id", "personPojo.name"))))
    

    or

    .method("hashOfPojo").body(returning(hash("personPojo.id", "personPojo.name")))
    

    as Person defines the arguments

    etc.

    Basically,

    • add shortcuts to all JavaBeans specific constructs
    • Use builder pattern and fluent API
    • a simple way to access arguments, fields, etc.
    • a simple way to set fields and return values
    opened by sirinath 9
  • Rpc server listen with exception...

    Rpc server listen with exception...

    java.lang.ArrayIndexOutOfBoundsException: 0 at org.objectweb.asm.Frame.merge(Frame.java:1268) at org.objectweb.asm.Frame.merge(Frame.java:1233) at org.objectweb.asm.MethodWriter.computeAllFrames(MethodWriter.java:1610) at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1546) at org.objectweb.asm.commons.GeneratorAdapter.endMethod(GeneratorAdapter.java:1348) at io.activej.codegen.ClassBuilder.toBytecode(ClassBuilder.java:484) at io.activej.codegen.ClassBuilder.toBytecode(ClassBuilder.java:393) at io.activej.codegen.ClassBuilder.toBytecode(ClassBuilder.java:381) at io.activej.codegen.ClassBuilder.defineClass(ClassBuilder.java:355) at io.activej.codegen.ClassBuilder.defineClassAndCreateInstance(ClassBuilder.java:369) at io.activej.serializer.SerializerBuilder.build(SerializerBuilder.java:479) at io.activej.serializer.SerializerBuilder.build(SerializerBuilder.java:457) at io.activej.rpc.server.RpcServer.onListen(RpcServer.java:213) at io.activej.net.AbstractServer.listen(AbstractServer.java:226) at the exception is caused by 'encode_Object_2([BILjava/lang/Object;)I'

    version: 5.4

    opened by xsank 8
  • [Question] Redis Client

    [Question] Redis Client

    Hi, Thank you for this excellent product/project. We are having much fun with it.

    Could you please point us to a tutorial on how on one might create a Redis, or redis-like (connector) client? We could take a wack at it but comparing your SSE demo code to our embarassing attempt to implement SSE without guidance tells us to ask for "professional help:)" Thank you for that code gist.

    Generally, we are looking to leverage ActiveJ for for interactions with Redis and PostgreSQL (JDBC). Any tutorial about creating this type of connectors with ActiveJ would be welcome.

    Thanks again for a clean and awesome project. Yes, we are using ActiveJ!

    opened by a1730 8
  • basic questions about ActiveJ Serializer. overflow, public field, annotation, platform independent, thread safe.

    basic questions about ActiveJ Serializer. overflow, public field, annotation, platform independent, thread safe.

    ActiveJ Serializer is extreme fast in my JMH benchmark:

    # JMH version: 1.34
    # VM version: JDK 1.8.0_312, OpenJDK 64-Bit Server VM, 25.312-b07
    
    Benchmark                                   Mode  Cnt      Score   Error  Units
    BenchmarkActiveJ.deserialize               thrpt    2  20456.246          ops/s
    BenchmarkActiveJ.serialize                 thrpt    2  43678.163          ops/s
    BenchmarkKryo.deserialize                  thrpt    2  10062.984          ops/s
    BenchmarkKryo.serialize                    thrpt    2  13294.549          ops/s
    BenchmarkKryoCustomSerializer.deserialize  thrpt    2  15841.880          ops/s
    BenchmarkKryoCustomSerializer.serialize    thrpt    2  36915.721          ops/s
    

    no code because of copyright of JMH by Oracle.

    I have some questions.

    1. kryo supports mix buffer of byte[] and ByteArrayOutputStream. So you can design without the risk of overflow with good performance of fixed buffer. How about ActiveJ Serializer?

         private static final ByteArrayOutputStream bufferKryo = new ByteArrayOutputStream();
         private static final Output outputKryo = new Output(bufferKryo,
      			SerializerBenchmarkCommon.bufferSize);
      
      		if (bufferKryo.size() != 0) {
      			outputKryo.flush();
      			serializedKryo = bufferKryo.toByteArray();
      		} else {
      			serializedKryo = outputKryo.toBytes();
      		}
      
    2. ActiveJ Serializer requests public field. Is there a way to handle private fields?

    3. ActiveJ Serializer requests annotations and full constructor. There is a risk of forgetting to write annotations and full constructor. any practice?

    4. If ActiveJ Serializer serialized equivalent objects in different environment for each, does it create equivalent byte array in any environment?

    5. Is ActiveJ Serializer pure bytecode?

    6. Is BinarySerializer thread safe?

    opened by lifeinwild 7
  • Encountering class cast exception with RPC Client

    Encountering class cast exception with RPC Client

    Hi,

    I am encountering a class cast exception when using an RPC client to communicate from an ActiveJ HTTP server to and ActiveJ RPC Server. I am doing a performance benchmark using the framework you have provided in your other examples. I was wondering if you can shed any light on how my setup might be off or if there is an underlying issue.

    io.activej.common.exception.UnknownFormatException: Parse exception, io.activej.datastream.csp.ChannelDeserializer@36b0cd56 : bufs:1 bytes:6102 at io.activej.datastream.csp.ChannelDeserializer.onResumed(ChannelDeserializer.java:88) at io.activej.datastream.AbstractStreamSupplier.resume(AbstractStreamSupplier.java:142) at io.activej.datastream.AbstractStreamSupplier.asyncResume(AbstractStreamSupplier.java:135) at io.activej.datastream.csp.ChannelDeserializer.lambda$onResumed$1(ChannelDeserializer.java:117) at io.activej.promise.AbstractPromise$25.accept(AbstractPromise.java:1134) at io.activej.promise.AbstractPromise.complete(AbstractPromise.java:114) at io.activej.promise.SettablePromise.set(SettablePromise.java:68) at io.activej.csp.queue.ChannelZeroBuffer.put(ChannelZeroBuffer.java:83) at io.activej.csp.queue.ChannelQueue$1.doAccept(ChannelQueue.java:66) at io.activej.csp.AbstractChannelConsumer.accept(AbstractChannelConsumer.java:51) at io.activej.csp.ChannelSuppliers.lambda$streamToImpl$6(ChannelSuppliers.java:236) at io.activej.promise.AbstractPromise.complete(AbstractPromise.java:114) at io.activej.promise.SettablePromise.set(SettablePromise.java:68) at io.activej.net.socket.tcp.AsyncTcpSocketNio.onReadReady(AsyncTcpSocketNio.java:374) at io.activej.eventloop.Eventloop.onRead(Eventloop.java:751) at io.activej.eventloop.Eventloop.processSelectedKeys(Eventloop.java:498) at io.activej.eventloop.Eventloop.run(Eventloop.java:411) at io.activej.service.adapter.ServiceAdapters$10.lambda$start$0(ServiceAdapters.java:282) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.ClassCastException: com.traceql.storage.lmdb.api.GetTokenResponse cannot be cast to com.traceql.storage.lmdb.api.GetQuotaResponse at io.activej.promise.AbstractPromise$1.accept(AbstractPromise.java:196) at io.activej.promise.AbstractPromise.complete(AbstractPromise.java:114) at io.activej.promise.SettablePromise.set(SettablePromise.java:68) at io.activej.promise.SettablePromise.accept(SettablePromise.java:55) at io.activej.rpc.client.RpcClientConnection$JmxConnectionMonitoringResultCallback.onResult(RpcClientConnection.java:397) at io.activej.rpc.client.RpcClientConnection$JmxConnectionMonitoringResultCallback.accept(RpcClientConnection.java:385) at io.activej.rpc.client.RpcClientConnection.accept(RpcClientConnection.java:215) at io.activej.rpc.client.RpcClientConnection.accept(RpcClientConnection.java:49) at io.activej.datastream.AbstractStreamSupplier.send(AbstractStreamSupplier.java:153) at io.activej.datastream.csp.ChannelDeserializer.process(ChannelDeserializer.java:159) at io.activej.datastream.csp.ChannelDeserializer.onResumed(ChannelDeserializer.java:83) ... 18 common frames omitted

    I have ensured the the MessageTypes for both the RPC client and the RPC server are listed in the same order. Both the RPC server and HTTP server are using the Primary/Worker event loop architecture. Any thoughts or questions to help me provide more information?

    opened by alexandermjames 6
  • Inject: Kotlin support for sets and map

    Inject: Kotlin support for sets and map

    Hi,

    Currently we have to explicity specify java.util.Set and java.util.Map for kotlin bindings when using @ProvidesIntoSet or bindIntoSet

    It would be great if we could support Kotlin Sets and Maps or at least this limitation is documented:

    Works:

    class Test @Inject constructor(val set: java.util.Set<Hej>)
    

    Breaks:

    class Test @Inject constructor(val set: Set<Hej>)
    
    opened by richarddd 6
  • `Promise` returned from `AsyncHttpClient` request doesn't handle exceptions thrown in `then` function

    `Promise` returned from `AsyncHttpClient` request doesn't handle exceptions thrown in `then` function

    fun get() {
      val httpClient = AsyncHttpClient.create(eventloop).withKeepAliveTimeout(Duration.ofHours(1))
      val promise = httpClient.request(HttpRequest.get(url)).then { response ->
       response.loadBody().map {
            try {
              throw RuntimeException("test exception")
            } catch( e: Exception) {
              throw e
            }
        }
      }
      return promise.map {response, ex -> if (ex != null) HttpResponse.ofCode(400) else response}
    }
    

    Above function (in Kotlin) expected to return HttpResponse.ofCode(400) but its promise is never completing since exception thrown in map block is not deligated to promise. After putting try-catch block into then block I found that exception thrown in map is not thrown inside map block but it is thrown inside then block.

    Stack trace

    
    	at io.activej.promise.AbstractPromise$12.accept(AbstractPromise.java:604)
    	at io.activej.promise.AbstractPromise.complete(AbstractPromise.java:114)
    	at io.activej.promise.AbstractPromise.complete(AbstractPromise.java:103)
    	at io.activej.promise.AbstractPromise.complete(AbstractPromise.java:114)
    	at io.activej.promise.SettablePromise.set(SettablePromise.java:68)
    	at io.activej.http.HttpClientConnection.onHeadersReceived(HttpClientConnection.java:214)
    	at io.activej.http.AbstractHttpConnection.readBody(AbstractHttpConnection.java:408)
    	at io.activej.http.AbstractHttpConnection.readHeaders(AbstractHttpConnection.java:274)
    	at io.activej.http.AbstractHttpConnection.readStartLine(AbstractHttpConnection.java:244)
    	at io.activej.http.HttpClientConnection.readMessage(HttpClientConnection.java:126)
    	at io.activej.http.AbstractHttpConnection$1.thenRun(AbstractHttpConnection.java:101)
    	at io.activej.http.AbstractHttpConnection$ReadConsumer.accept(AbstractHttpConnection.java:595)
    	at io.activej.http.AbstractHttpConnection$ReadConsumer.accept(AbstractHttpConnection.java:568)
    	at io.activej.promise.AbstractPromise.complete(AbstractPromise.java:114)
    	at io.activej.promise.SettablePromise.set(SettablePromise.java:68)
    	at io.activej.net.socket.tcp.AsyncTcpSocketNio.onReadReady(AsyncTcpSocketNio.java:374)
    	at io.activej.eventloop.Eventloop.onRead(Eventloop.java:883)
    	at io.activej.eventloop.Eventloop.processSelectedKeys(Eventloop.java:630)
    	at io.activej.eventloop.Eventloop.run(Eventloop.java:543)
    	at io.activej.service.adapter.ServiceAdapters$10.lambda$start$0(ServiceAdapters.java:282)
    

    I expect any then and map functions of any Promise implementation must delegate exception thrown inside their map blocks to the promise itself. I am not sure if I can produce it in Java though.

    opened by Qudratillo 3
  • How to get an RPC example with generic response

    How to get an RPC example with generic response

    i am trying to create an RPC server/client but i want the response to be generic but i failed this is an example from error that i get in server when trying to listen on port. Can you provide an example with solution here if possible?

    thanks in advance

    Exception in thread "Thread-2" java.lang.IllegalArgumentException: Type not found: sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeVariableImpl@12388301
    	at io.activej.types.AnnotatedTypes.bind(AnnotatedTypes.java:94)
    	at io.activej.types.AnnotatedTypes.bind(AnnotatedTypes.java:76)
    	at io.activej.serializer.SerializerBuilder.tryAddGetter(SerializerBuilder.java:1012)
    	at io.activej.serializer.SerializerBuilder.scanGetters(SerializerBuilder.java:896)
    	at io.activej.serializer.SerializerBuilder.scanClass(SerializerBuilder.java:798)
    	at io.activej.serializer.SerializerBuilder.doScan(SerializerBuilder.java:779)
    	at io.activej.serializer.SerializerBuilder.scan(SerializerBuilder.java:758)
    	at io.activej.serializer.SerializerBuilder.lambda$with$35(SerializerBuilder.java:230)
    	at io.activej.types.scanner.TypeScannerRegistry.scan(TypeScannerRegistry.java:378)
    	at io.activej.types.scanner.TypeScannerRegistry$Context.scan(TypeScannerRegistry.java:217)
    	at io.activej.types.scanner.TypeScannerRegistry$Context.scan(TypeScannerRegistry.java:207)
    	at io.activej.serializer.SerializerBuilder.lambda$with$35(SerializerBuilder.java:219)
    	at io.activej.types.scanner.TypeScannerRegistry.scan(TypeScannerRegistry.java:378)
    	at io.activej.types.scanner.TypeScannerRegistry$Context.scan(TypeScannerRegistry.java:217)
    	at io.activej.serializer.SerializerBuilder.tryAddGetter(SerializerBuilder.java:1012)
    	at io.activej.serializer.SerializerBuilder.scanGetters(SerializerBuilder.java:896)
    	at io.activej.serializer.SerializerBuilder.scanClass(SerializerBuilder.java:798)
    	at io.activej.serializer.SerializerBuilder.doScan(SerializerBuilder.java:779)
    	at io.activej.serializer.SerializerBuilder.scan(SerializerBuilder.java:758)
    	at io.activej.serializer.SerializerBuilder.lambda$with$35(SerializerBuilder.java:230)
    	at io.activej.types.scanner.TypeScannerRegistry.scan(TypeScannerRegistry.java:378)
    	at io.activej.types.scanner.TypeScannerRegistry.lambda$scanner$1(TypeScannerRegistry.java:359)
    	at io.activej.serializer.SerializerBuilder.build(SerializerBuilder.java:479)
    	at io.activej.serializer.SerializerBuilder.build(SerializerBuilder.java:459)
    	at io.activej.rpc.server.RpcServer.onListen(RpcServer.java:213)
    	at io.activej.net.AbstractServer.listen(AbstractServer.java:226)
    

    Here is what i want to achieve this is my response class:

    import io.activej.serializer.annotations.Deserialize;
    import io.activej.serializer.annotations.Serialize;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Response<T> {
    
        private List<T> data;
    
        public Response(@Deserialize("data")List<T> data) {
            this.data = data;
        }
    
        @Serialize
        public List<T> getData() {
            return data;
        }
    
        public void setData(List<T> data) {
            this.data = data;
        }
    }
    

    here is what i do

    T typeParameterClass=new MyClass();
    Type fluentType=setModelAndGetCorrespondingList2(typeParameterClass.getClass());
    rpcServer = RpcServer.create(eventloop)
                        .withMessageTypes(Request.class,fluentType.getClass())
                        .withSerializerBuilder(this.rpcserialize)
                        .withHandler(Request.class, helloServiceRequestHandler(new Service(typeParameterClass.getClass())))
                        .withListenAddress(inetSocketAddress);
    
    
     private <T> Type setModelAndGetCorrespondingList2(Class<T> type) {
            return new TypeToken<Response<T>>() {
            }
                    .where(new TypeParameter<T>() {
                    }, type)
                    .getType();
        }
    
    

    and i think the problem is here in this line .withMessageTypes(Request.class,fluentType.getClass()) Any help how to fix this issue?

    An alternative way that i thinking is to send bytes as response and then manually deserialize it when it will bereceived. will this approach add extra delay overhead or its ok to do it?

    opened by l16h7n1n6s 2
  • How to maintain the reverse order of a treemap during deserialization

    How to maintain the reverse order of a treemap during deserialization

    Hello again, i hope you have a wonderful day. I am facing a simple problem where i have a treemap that stores values in reverse order and my problem is that during deserialization the values are not maintained in the same reverse-order sequence. How to fix it?

    This is my simple code:

    import io.activej.serializer.annotations.Serialize;
    
    import java.util.Collections;
    import java.util.Map;
    import java.util.TreeMap;
    
    public class MapClass {
    
        private Map<Double,String> map;
    
        public MapClass() {
            this.map = new TreeMap<>(Collections.reverseOrder());
        }
    
        @Serialize
        public Map<Double, String> getMap() {
            return map;
        }
    
        public void setMap(Map<Double, String> map) {
            this.map = map;
        }
    
    }
    
    import java.util.Collections;
    import java.util.Map;
    import java.util.TreeMap;
    
    public class MapMain {
    
        public static void main(String[] args) {
            byte[] buffer = new byte[200];
           MapClass a=new MapClass();
           a.getMap().put(10.0,"val1");
           a.getMap().put(13.0,"val2");
            BinarySerializer<MapClass> serializer = SerializerBuilder.create().build(MapClass.class);
            serializer.encode(buffer, 0,a);
            MapClass copy =  serializer.decode(buffer, 0);
            System.out.println(copy.toString());
        }
    }
    

    this is a screenshot from debugging I expect 13 to be first.

    image

    What i 've tried so far to make it work is the following code and its working correct but i don't know if its the right way to do it or there exists a smarter way.

    import io.activej.serializer.*;
    import lombok.SneakyThrows;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.TreeMap;
    
    public class CustomSerializerMap extends SimpleSerializerDef<TreeMap<Double, String>> {
        private int length;
        @Override
        protected BinarySerializer<TreeMap<Double, String>> createSerializer(int version, CompatibilityLevel compatibilityLevel) {
            return new BinarySerializer<TreeMap<Double, String>>() {
                @SneakyThrows
                @Override
                public void encode(BinaryOutput out, TreeMap<Double, String> item) {
                    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
                    ObjectOutputStream outstream = new ObjectOutputStream(byteOut);
                    outstream.writeObject(item);
                    out.write(byteOut.toByteArray());
                }
    
                @SneakyThrows
                @Override
                public TreeMap<Double, String> decode(BinaryInput in) throws CorruptedDataException {
                    byte[] bytes = new byte[245];
                    in.read(bytes);
                    ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
                    ObjectInputStream instream = new ObjectInputStream(byteIn);
                    TreeMap<Double, String> treemap = (TreeMap<Double, String>) instream.readObject();
                    return treemap;
                }
            };
        }
    }
    

    One last thing i want something to avoid the static byte assignment because during the decode the size will not be known, i am talking for these lines of code:

      byte[] bytes = new byte[245];
      in.read(bytes);
    

    Can we avoid to to write custom serializer for treemap what's your suggestion for the most efficient approach?

    opened by PanagiotisDrakatos 2
  • MultipartDataHandler missing fields while mapping

    MultipartDataHandler missing fields while mapping

    My front end is in svelte; Just created a very simple form with enctype="multipart/form-data" and is as -

    (Just for simplicity, I ignored file input)

            <form method="POST" enctype="multipart/form-data">
                <fieldset>
                    <label for="name">Name</label>
                    <input type="text" name="name" id="name">
                    <label for="type">Type</label>
                    <input type="text" name="type" id="type">
                    <label for="description">Description</label>
                    <input type="text" name="description" id="description">
                    <input type="submit" value="Submit">
                </fieldset>
            </form>
    

    I use the following line to map the form data fields into map -

     HashMap<String, String> fields = new HashMap<String, String>();
     request.handleMultipart(MultipartDecoder.MultipartDataHandler.fieldsToMap(fields));
    

    But, not all the 3 inputs in the html form is received in fields HashMap. I got only 2 fields mapped.

    Logs is as follows -

    20:10:27.869 ERROR servlet.CRUDServlet - --- Enter POST Request --- 20:10:27.871 ERROR servlet.CRUDServlet - Headers : [Accept-Language=, sec-fetch-mode=cors, Accept-Encoding=gzip, deflate, Content-Type=multipart/form-data; boundary=----formdata-undici-0.3572468109466933, Connection=keep-alive, Accept=/*, Transfer-Encoding=chunked, User-Agent=undici, Host=localhost:8080] 20:10:27.872 ERROR servlet.CRUDServlet - Path parameters : {} 20:10:27.872 ERROR servlet.CRUDServlet - Query parameters : {} 20:10:27.872 ERROR servlet.CRUDServlet - Post parameters : {} 20:10:27.873 ERROR servlet.CRUDServlet - Contains MultipartData? : true 20:10:27.873 ERROR servlet.CRUDServlet - Body as String : ------formdata-undici-0.3572468109466933 Content-Disposition: form-data; name="name"

    Container1 ------formdata-undici-0.3572468109466933 Content-Disposition: form-data; name="type"

    Private ------formdata-undici-0.3572468109466933 Content-Disposition: form-data; name="description"

    Abcdefg ------formdata-undici-0.3572468109466933-- Mapped fields: {name=Container1, type=Private} Mapped fields size: 2 20:10:27.909 ERROR servlet.CRUDServlet - --- Exit POST Request ---

    opened by kkrprodev 1
  • FatalErrorHandler not works under some conditions.

    FatalErrorHandler not works under some conditions.

    some online server maybe break down forever, the rpc client should close in this case

    08:06:00.165 [client-loop] ERROR io.activej.rpc.client.RpcClientConnection - Receiver error: /192.168.1.42:9000
    java.io.IOException: Connection reset by peer
            at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
            at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
            at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:225)
            at sun.nio.ch.IOUtil.read(IOUtil.java:199)
            at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:393)
            at io.activej.net.socket.tcp.AsyncTcpSocketNio.doRead(AsyncTcpSocketNio.java:397)
            at io.activej.net.socket.tcp.AsyncTcpSocketNio.onReadReady(AsyncTcpSocketNio.java:364)
            at io.activej.eventloop.Eventloop.onRead(Eventloop.java:883)
            at io.activej.eventloop.Eventloop.processSelectedKeys(Eventloop.java:630)
            at io.activej.eventloop.Eventloop.run(Eventloop.java:543)
            at java.lang.Thread.run(Thread.java:855)
    08:06:00.165 [client-loop] ERROR io.activej.rpc.client.RpcClientConnection - Sender error: /192.168.1.42:9000
    io.activej.async.exception.AsyncCloseException: RPC Channel Closed
    08:06:00.165 [client-loop] INFO io.activej.rpc.client.RpcClient - Connection closed: /192.168.1.42:9000
    

    i custom a Errorhandler to handle this case, but found it not works, until i found the code below...

    FatalErrorHandlers

    public static void handleError(@NotNull FatalErrorHandler fatalErrorHandler, @NotNull Throwable e, @Nullable Object context) {
            if (e instanceof RuntimeException || !(e instanceof Exception)) {
                fatalErrorHandler.handle(e, context);
            }
    
        }
    

    for the IOException is instance of Exception and is not RuntimeException...

    why the activej add this condition? and how should i handle the reset event immediately? thank you~

    opened by xsank 1
  • How to structure the application?

    How to structure the application?

    Hi people, I'm learning ActiveJ.

    I code a simple http service using MultithreadedHttpServerLauncher, like the http docs. It just query a h2 database and sends a json response. Today I have a simple class that extends MultithreadedHttpServerLauncher and overrides servlet() method. In servlet() I use BasicAuth and RoutingServlet. There is a hikaricp pool for the database access.

    Now I want to code two more services in that app. Each service will open a https connection to another host:port, gets the content, process and return a json.

    I read tutorials, docs and examples but I could not understand how to structure that app with Launchers, Modules, Services...

    How could I struture that app? (like, a HttpLauncher, a Service1Module, a Service2Module) And how to bind these classes? How should I call the services in a RoutingServlet? I need to configure and use a AsyncHttpClient to connect to host:port, that's ok, but I don't know how the client can be injected?

    Thanks in advance.

    opened by romulloal 1
Owner
ActiveJ LLC
ActiveJ LLC
A modular, high performance, headless e-commerce(ecommerce) platform built with Java,Springboot, Vue.

What is Shopfly? Shopfly is modular, high performance, headless e-commerce(ecommerce) platform built with Java,Springboot, Vue. Architecture Shopfly i

Shopfly 29 Apr 25, 2022
A spring cloud infrastructure provides various of commonly used cloud components and auto-configurations for high project consistency

A spring cloud infrastructure provides various of commonly used cloud components and auto-configurations for high project consistency.

Project-Hephaestus 2 Feb 8, 2022
A high availability shopping(ecommerce) system using SpringBoot, Spring Cloud, Eureka Server, Spring Cloud Gateway, resillience4j, Kafka, Redis and MySQL.

High-availability-shopping-system A high availability shopping(ecommerce) system using SpringBoot, Spring Cloud, Eureka Server, Spring Cloud Gateway,

LeiH 1 Oct 26, 2022
SurvivalCore featuring SMP features like claims and land protection for Nukkit!

SurvivalCore SurvivalCore featuring Survival characterstics and claims and land protection for Nukkit! Features: Claims System : Use /claim or /c to c

OP Heroes Development Team 1 Jan 4, 2022
GitactionBoard - Ultimate Dashboard for GithubActions.

Gitaction Board Gitaction Board - Ultimate Dashboard for GithubActions. Table of contents Usage Pull docker image Run docker image Configurations UI D

OTTO (GmbH & Co. KG) 43 Dec 2, 2022
Cloud Native and Low Code Platform to create FullStack web Admin applications in minutes

Cloud Native and Low Code Platform to create FullStack web Admin applications in minutes ✨ Features & Technologies REST API generator Low Code CRUD &

Gemini Framework 171 Dec 26, 2022
Demo microservice architecture with Spring ,Spring Cloud Gateway , Spring Cloud config server , Eureuka , keycloak and Docker.

spring-microservice Demo microservice architecture with Spring ,Spring Cloud Gateway , Spring Cloud config server , Eureuka , keycloak and Docker. Arc

null 4 Sep 13, 2022
DSMovie is a full stack web and mobile application built during Spring React Week, an event organized by DevSuperior

projeto-DSMovie Sobre o projeto DSMovie é uma aplicação full stack web e mobile construída durante a Semana Spring React, evento organizado pela DevSu

Matheus Maia Alvarez 7 Apr 18, 2022
循序渐进,学习Spring Boot、Spring Boot & Shiro、Spring Batch、Spring Cloud、Spring Cloud Alibaba、Spring Security & Spring Security OAuth2,博客Spring系列源码:https://mrbird.cc

Spring 系列教程 该仓库为个人博客https://mrbird.cc中Spring系列源码,包含Spring Boot、Spring Boot & Shiro、Spring Cloud,Spring Boot & Spring Security & Spring Security OAuth2

mrbird 24.8k Jan 6, 2023
一个涵盖六个专栏:Spring Boot 2.X、Spring Cloud、Spring Cloud Alibaba、Dubbo、分布式消息队列、分布式事务的仓库。希望胖友小手一抖,右上角来个 Star,感恩 1024

友情提示:因为提供了 50000+ 行示例代码,所以艿艿默认注释了所有 Maven Module。 胖友可以根据自己的需要,修改 pom.xml 即可。 一个涵盖六个主流技术栈的正经仓库: 《Spring Boot 专栏》 《Spring Cloud Alibaba 专栏》 《Spring Clou

芋道源码 15.7k Dec 31, 2022
一套涵盖大部分核心组件使用的Spring Cloud教程,包括Spring Cloud Alibaba及分布式事务Seata,基于Spring Cloud Greenwich及SpringBoot 2.1.7。22篇文章,篇篇精华,32个Demo,涵盖大部分应用场景。

springcloud-learning 简介 一套涵盖大部分核心组件使用的Spring Cloud教程,包括Spring Cloud Alibaba及分布式事务Seata,基于Spring Cloud Greenwich及SpringBoot 2.1.7。22篇文章,篇篇精华,32个Demo,涵盖

macro 5.6k Dec 30, 2022
Java-Programs---For-Practice is one of the Java Programming Practice Series By Shaikh Minhaj ( minhaj-313 ). This Series will help you to level up your Programming Skills. This Java Programs are very much helpful for Beginners.

Java-Programs---For-Practice is one of the Java Programming Practice Series By Shaikh Minhaj ( minhaj-313 ). This Series will help you to level up your Programming Skills. This Java Programs are very much helpful for Beginners. If You Have any doubt or query you can ask me here or you can also ask me on My LinkedIn Profile

Shaikh Minhaj 3 Nov 8, 2022
Cosmic Ink is a transcript application which was built with the help of Symbl AI and At Sign platform for back-end to store our data and authenticate

Cosmic-Ink Cosmic Ink is a transcript application which was built with the help of Symbl AI and At Sign platform for back-end to store our data and au

Venu Sai Madisetti 4 Dec 1, 2022
Tuya 37 Dec 26, 2022
A code sharing platform built using spring boot, hibernate and JPA as ORM with PostgreSQL which also follows a RESTful architecture.

Snap-Snippet A code sharing platform built using spring boot, hibernate and JPA as ORM with PostgreSQL which also follows a RESTful architecture. Tech

Adnan Hossain 7 Nov 29, 2022
Programming Services and Processes - 04 Secure Programming Techniques

Programación de Servicios y Procesos - 04 Técnicas de Programación Segura Tema 04. Técnicas de Programación segura. Curso 2021/2022. Contenidos Introd

José Luis González Sánchez 5 Dec 27, 2022
PolarDB-X is a cloud native distributed SQL Database designed for high concurrency, massive storage, complex querying scenarios.

中文文档 What is PolarDB-X ? PolarDB-X is a cloud native distributed SQL Database designed for high concurrency, massive storage and complex querying scen

null 1.2k Dec 31, 2022
Spring-Boot-Plus is a easy-to-use, high-speed, high-efficient,feature-rich, open source spring boot scaffolding

Everyone can develop projects independently, quickly and efficiently! What is spring-boot-plus? A easy-to-use, high-speed, high-efficient, feature-ric

geekidea 2.3k Dec 31, 2022
High Performance data structures and utility methods for Java

Agrona Agrona provides a library of data structures and utility methods that are a common need when building high-performance applications in Java. Ma

Real Logic 2.5k Jan 7, 2023