Lightweight threads for Java, with message passing, nio, http and scheduling support.

Overview

Kilim: Continuations, Fibers, Actors and message passing for the JVM

Kilim is composed of 2 primary components:

  • The Kilim weaver modifies the bytecode of compiled java classes, enabling a method to save it's state and yield control of it's thread, ie to cooperatively multitask
  • The Kilim runtime library provides constructs that leverage the weaver to simplify concurrent programming, including Coroutines, Task, Actors, Mailboxes (aka channels), and Generators

Together, these facilities allow for simple concurrency and can scale to millions of concurrent tasks

Usage

Code can be woven:

  • during compilation by using the maven plugin
  • during compilation by running kilim.tools.Weaver
  • at runtime by invoking kilim.tools.Kilim com.yourcompany.yourclass
  • at runtime by including if (kilim.tools.Kilim.trampoline(false,args)) return; at the start of main()

Writing code with Kilim

Please see docs/manual.txt and docs/kilim_ecoop08.pdf for a brief introduction.

  • src/kilim/examples contains some simple examples
  • src/kilim/bench contains some performance benchmarks
  • kilim streams is a port of java 8 streams to kilim
  • java empower is a comparison of several async web server techs
    • kj/src/main/java/KilimJetty.java shows integrating with jetty async
    • kilim/src/main/java/KilimHello.java shows the built-in kilim web server (which in addition to doing async connections also does async io)

"hello world" in kilim

for an example of a project that uses kilim (with the trampoline for runtime weaving) see the battle royale demo in this repository. clone this repository, and from that directory execute mvn package exec:java -Dexec.mainClass=kilim.demo.Battle

Similarity to Java Futures

java.util.concurrent.Future is an interface that can represents the result of an asynchronous computation. kilim pre-dates java futures, and uses a slightly different api, but kilim supports the same notion, ie to block until an async computation finishes:

  • kilim.Task.joinb() blocks until a Task completes
  • kilim.Task.isDone() returns true if this Task completed
  • cancellation isn't explicitly supported
  • kilim.Mailbox.getb() is also similar

these methods allow synchronizing threads with async computations. however, the real power of kilim is in enabling communication between async computations. for this, use the join() and get() methods which are Pausable

Maven

for an example of a project that uses kilim, see the kilim jetty demo in this repository

  • the pom.xml specifies kilim as both a dependency and a plugin for ahead-of-time weaving
  • this version supports java 8, 9, 11, 12 and 13-ea (and 10 if you don't use lambdas)
  • there are dedicated artifacts for java 7 and 10 (see below)

the dependency:

    
        org.db4j
        kilim
        2.0.1
    

weaving with the kilim plugin:

    
        org.db4j
        kilim
        2.0.1
        
            
                weave
            
        
    

Overview

  • java.lang.Runnable: once a java.lang.Task starts running, it takes over the thread until it returns

  • kilim.Continuation: like java.lang.Runnable, but can yield (relinquish control of the thread) while preserving state. It’s caller must arrange to resume it at some appropriate time. Used for event-driven state machines where the event loop knows when to resume. The programmer is in charge of the event loop.

  • kilim.Task: like kilim.Continuation, but specifies a reason that it yields, and a scheduler automatically resumes it when the reason is no longer true. Typically used for a system of communicating state machines that communicate using Mailboxes. Releases the programmer from the job of mapping fibers to thread and of managing an event loop and the delivery of events.

  • kilim.Pausable: a hypothetical exception used to declare intent. a method that declares this to be thrown will trigger the weaver

  • kilim.Mailbox: a queue with Pausable methods that cause the calling Task method to yield when an operation would otherwise block and to resume automatically when the Mailbox because available for reading or writing

  • kilim.Fiber: the structure that stores the Continuation (and Task) state

Java Versions

java 8, 11 and 12 are the recommended platforms, but 7, 8, 9, and 10 are regularly tested, and in theory java 6 could probably still be made to work without too much work

java 8, java 9, java 11, java 12 and java 13-ea:

  • maven central: org.db4j : kilim : 2.0.2
  • compiled with java 8 bytecode
  • ASM 7.1 supports all versions of java through java 13-ea (and presumably, java 13 when it's released)

other versions and notes on limitations

java 7:

  • JAVA_HOME=path/to/java7 ant clean weave jar
  • see demos/java7 for usage examples
  • some features are not available, eg jetty integration and lambdas
  • this version is incompatible with lambdas in later java versions because default interface methods aren't supported
  • maven central: 2.0.1-jdk7

java 9:

  • the java 8 compiled version supports java 9
  • see demos/battle/pom9.xml for a usage example
  • kilim does not explicitly support modules, but works with the builtin fallback support, see below
  • JShell works - see demos/jshell

java 10:

  • java 10 has a bug and refuses to load some valid lambdas
  • https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8209112
  • this is already fixed in java 11 but will not be fixed in java 10 due to the new release cycle
  • throws java.lang.NoClassDefFoundError when attempting to load a woven fiber-less lambda
  • workaround: use lambdas that take an explicit last parameter Fiber dummy and a corresponding default method without that last parameter
  • the Fiber argument should not be accessed in the lambda
  • to call a Pausable lambda, call the default method
  • github tag: java10
  • all lambdas that will be loaded need to be woven with this java10 "fiber-included" flavor of kilim
  • this will work fine with java 8 or 9 as well, however it exposes the fiber to the user and makes it harder to detect unwoven Pausable methods, so it's use is discouraged unless you need to support java 10
  • maven central: 2.0.0-28-jdk10
    interface Lambda {
        void execute(Fiber fiber) throws Pausable, Exception;
        default void execute() throws Pausable, Exception {}
    }
    static void dummy() throws Pausable, Exception {
        Lambda lambda = dummy -> {
            Task.sleep(1000);
            System.out.println("hello world");
        };
        lambda.execute();
    }

java 11:

  • constant dynamics and preview classes are not yet supported - they will be when usage in the wild is seen
  • JEP 330 single-file source invocation works with java 11
    • the JEP 330 class loader has some limitations which must be worked around
    • for java 11, use the kilim jar as a -javaagent (fixed in java 12)
    • see demos/java11

specific java features

lambdas:

jshell:

  • working
  • see demos/jshell for an example of automatic weaving

JEP-330 single file source invocation

  • working
  • see demos/java11 for an example
  • for java 11, a java agent (included) is needed, see above (this is fixed in java 12)
  • call Kilim.trampoline in main to enable weaving
  • eg for java 12:
    public static void main(String[] args) {
        if (kilim.tools.Kilim.trampoline(new Object() {},false,args)) return;
    ...

modules:

  • kilim works with java 9 and later using the builtin fallback support
  • no module-info.java is provided
    • if you have a demo project that you can share that "depends" on modules, create an issue and it will be investigated

Project Loom:

  • Project Loom is not yet released and is not yet supported by kilim
    • some testing has been done
  • Loom attempts to run a much larger subset of the java language than kilim, at least initially at the expense of performance
  • when it is released, kilim will integrate with Loom fibers in whatever capacity makes sense

Building

summary:

  • maven and ant are used cooperatively
  • maven is used for downloading dependencies (or manually copy them to ./libs - see pom.xml)
    • only needs to be done once (until dependencies change)
    • mvn initialize (but any pom-based mvn command should work too)
    • and cleaner to delete the copied jars
  • maven can also be used for building, but tests are disabled
  • there's a kilim maven plugin, but it's not used here to avoid a circular dependency - the weaver is run directly instead (using ant)
  • the plugin is only built during the maven build, but once built will be packaged by ant as well, eg mvn package && ant jar

simple: mvn install

build with tests: ant clean testjit test jar doc

details:

  • testjit runs the tests (after compiling) using the runtime weaver
  • test runs the tests using the compile-time weaver, as well as some tests that don't require weaving
  • doc generates sources.jar and javadoc.jar
  • mvn install:install-file -DpomFile=pom.xml -Dfile=$(target/kilim*.jar) -Dsources=target/sources.jar -Djavadoc=target/javadoc.jar

Support

public support:

nqzero is currently the primary maintainer. he's focused on making Kilim easy to use and reliable and is actively using Kilim

Sriram is the original author (in 2006 !) and deserves a great deal of thanks for his excellent work. He continues to provide guidance on kilim and is especially interested in theory and performance, but is not actively using kilim today. He can be reached at kilim at malhar.net

Users

a number of companies (or their employees) appear to have been using Kilim recently and have contributed

Copyright and License

Kilim v2.0

  • Copyright (c) 2006, 2014 Sriram Srinivasan (kilim at malhar.net)
  • Copyright (c) 2016 nqzero
  • Copyright (c) 2013 Nilang Shah
  • Copyright (c) 2013 Jason Pell
  • Copyright (c) 2013 Jestan Nirojan (maven plugin)

This software is released under an MIT-style license (please see the License file). Unless otherwise noted, all files in this distribution are offered under these terms, and files that explicitly refer to the "MIT License" refer to this license

Comments
  • pass task context when dealing with Java Dynamic Proxy

    pass task context when dealing with Java Dynamic Proxy

    Hi , create a new Task inside Dynamic Proxy invoke method could get around the non-weaved problem , but if i put the execution logic inside the Task Body, then i will lost the previous Task's context . `@override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    final Method mtd = method;
    final Object[] ags = args;
    if (!sppCmdMap.containsKey(method.getName())) {
        return null;
    }
    final RpcContext rpcContext = RpcContext.getContext(KilimTask.getCurrentTask().id);
    Task t = new Task() {
        public void execute() throws Exception, Pausable {
    
            if (!sppCmdMap.containsKey(mtd.getName())) {
                return;
            }
            RpcCmdInfo cmd = sppCmdMap.get(mtd.getName());
            if (ags[0] instanceof List) {
                List<Message> reqs = (List<Message>) ags[0];
                exit(rpcInvokeBatch(reqs, cmd, rpcContext));
            } else {
                Message req = (Message) ags[0];
                exit(rpcInvoke(req, cmd, rpcContext));
            }
        }
    };
    t.start();
    ExitMsg m = t.joinb();
    return m.result;
    

    } `

    here if i want get the previous Task's Context , i have to use KilimTask.getCurrentTask().id but this is a Pausable method ... is there any good idea to solve this ? Tks advance ! : ) BTW , Kilim is really awesome ! our team is really enjoy with it .

    opened by JasonHuangHuster 20
  • Local vars not restored properly after call pausable method and throw exception

    Local vars not restored properly after call pausable method and throw exception

    public class Exceptions extends Task { private String fWithOutMailBox() throws Pausable { throw new RuntimeException(); // no pausable method }

    private String fWithMailBox() throws Pausable {
        new Mailbox<String>().get(1000);  // has pausable method
        throw new RuntimeException();
    }
    
    public void execute() throws Pausable {
        String foo = "data";
        try {
            foo = fWithOutMailBox();
        } catch (Throwable t) {
            System.out.println("foo=" + foo);
        }
        String foo2 = "data";
        try {
            foo2 = fWithMailBox();
        } catch (Throwable t) {
            System.out.println("foo2=" + foo2);
        }
    }
    
    public static void main(String args[]) {
        new Exceptions().start();
    }
    

    } ================expect result will be foo=data foo2=data ================while real result is foo=data foo2=null

    opened by wangjia-wang 16
  • Missing test classes?

    Missing test classes?

    Firstly, many thanks for the great work! However, I believe that I have identified a bug in some of the tests.

    The test class kilim.test.TestInvalidPausables refers to the following classes:

    • kilim.test.ex.ExInvalidConstructor
    • kilim.test.ex.ExInvalidStaticBlock
    • kilim.test.ex.ExInvalidCallP_NP
    • kilim.test.ex.ExInvalidPDerived
    • kilim.test.ex.ExInvalidPImp

    However, none of the classes in the above list are in the package kilim.test.ex, or any other package for that matter. (I have greped the entire project for the class names.)

    The tests that involve these missing classes are in fact passing, but only because the test requires an exception to be thrown, and an exception is indeed thrown, but only due to the class missing, instead of the weaving failing.

    Could you confirm that this is a bug? Do you have the source of the missing classes?

    opened by andrewdbate 14
  • Pause specific task? (Especially from within another Task)

    Pause specific task? (Especially from within another Task)

    Is it possible to pause a specific Task, especially from within another Task?

    Example:

        Task counterTask = new Task() {
            @Override
            public void execute() throws Pausable {
                for(int i = 1; i <= 100; i++) {
                    Task.sleep(1000L);
                    System.out.println(i);
                }
            }
        }.start();
    
        Task pauseTask = new Task() {
            @Override
            public void execute() throws Pausable {
                Task.sleep(5000L);
                System.out.println("Pausing counter task...");
                //counterTask.pause(); //<-- this is what I'd like to do.
                Task.sleep(5000L);
                System.out.println("Resuming counter task...");
                counterTask.resume();
            }
        }.start();
    
    opened by ghost 12
  • Please support ASM 4.0

    Please support ASM 4.0

    Can you please support ASM 4 in the library in order to support JDK 7?

    I know that others, such as Kresten, have forked kilim in order to support ASM 4, but the trouble is that fixes to the main repo are not being merged into these forks and it is all becoming difficult and a bit complicated.

    Many thanks :-)

    opened by andrewdbate 12
  • Exception catch problem

    Exception catch problem

    Hi, our team use kilim based on kilim1.0. Here, we has a problem about Exception-catch . The problem we can reprodue by code:

    package kilim.examples;
    
    import kilim.Mailbox;
    import kilim.Pausable;
    import kilim.Task;
    
    public class IllegalArException extends Task {
    	public static void main(String[] args) {
    		new IllegalArException().start();
    	}
    
    	public void execute() throws Pausable {
    		int i = 2;
    		try {
    			new Mailbox<String>().get(1000);// RPC
    			throw new DolphinRunException();
    		} catch (DolphinRunException ex) {
    			System.out.println("DolphinRunException:" + i);
    		} catch (Exception ex) {
    			System.out.println("Exception:" + i);
    		}
    	}
    
    }
    
    class DolphinRunException extends RuntimeException {
    	
    }
    

    expect result:

    DolphinRunException:2
    

    but we get the result:

    Exception:2
    

    Thanks first.

    opened by walkerzhao 9
  • Annotation on method is removed by Kilim Weaver

    Annotation on method is removed by Kilim Weaver

    i have annotations on class name and method also , after kilim weaver only annotation on class is keeped , but annotation on method is gone .

    ` @RpcService(value = "javasvr_ckv_cdb", modid = 670209, cmdid = 232072, routeIp = "") public interface CkvCdbChain {

    @RpcCmd(value = "Add", retry = 2, timeout = 400)
    EduCkvChainMsg.AddRsp  addEntry(EduCkvChainMsg.AddReq addReq)throws Pausable,APIException;
    
    @RpcCmd(value = "Del", retry = 2, timeout = 400)
    EduCkvChainMsg.DelRsp  delEntry(EduCkvChainMsg.DelReq delReqReq)throws Pausable,APIException;
    
    @RpcCmd(value = "GetOne", retry = 2, timeout = 400)
    EduCkvChainMsg.GetOneRsp  getOne(EduCkvChainMsg.GetOneReq getOneReq)throws Pausable,APIException;
    
    @RpcCmd(value = "Mod", retry = 2, timeout = 400)
    EduCkvChainMsg.ModRsp  modEnry(EduCkvChainMsg.ModReq modReq)throws Pausable,APIException;
    
    @RpcCmd(value = "GetList", retry = 2, timeout = 400)
    EduCkvChainMsg.GetListRsp  getList(EduCkvChainMsg.GetListReq getListReq)throws Pausable,APIException;
    
    @RpcCmd(value = "MultiGetList", retry = 2, timeout = 400)
    EduCkvChainMsg.MultiGetListRsp multiGetList(EduCkvChainMsg.MultiGetListReq multiGetListReq) throws Pausable, APIException;
    
    @RpcCmd(value = "GetReverseList", retry = 2, timeout = 400)
    EduCkvChainMsg.GetReverseListRsp getReverseList(EduCkvChainMsg.GetReverseListReq getReverseListReq) throws Pausable,APIException;
    

    } `

    need help here , tks advance . :)

    opened by JasonHuangHuster 9
  • Implementation of equals() and merge() in class kilim.analysis.Value (out of date FIXME?)

    Implementation of equals() and merge() in class kilim.analysis.Value (out of date FIXME?)

    The equals() method of kilim.analysis.Value has the following implementation of equals:

    public boolean equals(Object obj) {
        // TODO FIXME : This is WRONG. Two values can be created at the same site when
        // entering a method (all incoming parameter values are given location 0).
        // That would make two distinct params with the same type equal.
        if (this == obj) return true;
        Value other = (Value)obj;
        if (this.typeDesc.equals(other.typeDesc) &&
                this.constVal.equals(other.constVal) &&
                    this.numSites == other.numSites) {
            // Check sites
            for (int i = 0; i < this.numSites; i++) {
                if (sites[i] != other.sites[i]) {
                    return false;
                }
            }
                return true;
            }
        return false;
    }
    

    The comment says that the equals implementation is wrong. Is this really the case, or is the comment out of sync with the code?

    If the check this.constVal.equals(other.constVal) is removed, then I agree with the comment (since then you could not distinguish between two formal parameters with the same type, both of which have have site position zero and the typeDesc's are the same). However, checking the constVal's guards against this, right?

    By the same argument, in the the implementation of the method merge() in the same class, shouldn't the line

    if (newNumSites != numSites || newType != typeDesc) { ... }
    

    be replaced with:

    if (newNumSites != numSites || newType != typeDesc || !constVal.equals(other.constVal)) { ... }
    

    Right?

    Therefore, in summary:

    1. I believe that the FIXME comment in equals() should be deleted, since it is out-of-sync with the code.
    2. The implementation of merge() may be have bug, since the above check is missing. (Although I expect merge() would never be called in this case, it should operate correctly nonetheless.)

    Many thanks!

    opened by andrewdbate 9
  • @synchronized annotation

    @synchronized annotation

    This is just a note to document this idea, I might try to implement this...

    Currently synchronized methods must be rewritten to use the kilim.ReentrantLock. So this class...

    class SomeClass {
        synchronized void someMethod() throws Pausable { 
        }
    }
    

    needs to be rewritten like this...

    class SomeClass {
        private final kilim.ReentrantLock lock= new kilim.ReentrantLock();
        void someMethod() throws Pausable { 
            lock.lock();
            try {
            }
            finally {
                lock.unlock();
            }
        }
    }
    

    However, it would be really convenient if kilim weaver would do this automatically. I imagine an annotation named @synchronized that would replace the synchronized keyword. Thus, the original method could just be written like this...

    class SomeClass {
        @synchronized void someMethod() throws Pausable { 
        }
    }
    

    and the kilim weaver would apply the appropriate changes using kilimReentrantLock.

    out-of-scope 
    opened by tstockwell 9
  • runtime weaver with java 8: java.lang.ClassCircularityError

    runtime weaver with java 8: java.lang.ClassCircularityError

    i'm trying to use the runtime weaver with java 8 (asm5-jdk8 branch). for some simple classes it works, but for others, such as kilim.examples.Tree, i get errors

    ant clean compile
    cp -R classes c1
    ant weave
    cp -R classes c2
    rm -R c2/kilim/examples/
    java -cp "c2:libs/*" -Dkilim.class.path=c1 kilim.tools.Kilim kilim.examples.Spawn
    java -cp "c2:libs/*" -Dkilim.class.path=c1 kilim.tools.Kilim kilim.examples.Tree
    

    Spawn works (prints "Hello from 0...)", Tree fails:

    Exception in thread "main" java.lang.ClassCircularityError: kilim/examples/Tree
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2688)
        at java.lang.Class.getDeclaredMethods(Class.java:1962)
        at kilim.mirrors.RuntimeClassMirror.getDeclaredMethods(RuntimeClassMirrors.java:163)
        at kilim.mirrors.Detector.findPausableMethod(Detector.java:119)
        at kilim.mirrors.Detector.getPausableStatus(Detector.java:71)
        at kilim.analysis.MethodFlow.visitMethodInsn(MethodFlow.java:219)
        at org.objectweb.asm.MethodVisitor.visitMethodInsn(Unknown Source)
        at org.objectweb.asm.tree.MethodNode.visitMethodInsn(Unknown Source)
        at org.objectweb.asm.ClassReader.a(Unknown Source)
        at org.objectweb.asm.ClassReader.b(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at kilim.analysis.ClassFlow.analyze(ClassFlow.java:85)
        at kilim.analysis.ClassWeaver.weave(ClassWeaver.java:93)
        at kilim.tools.Weaver.weave(Weaver.java:297)
        at kilim.tools.Weaver.weave(Weaver.java:255)
        at kilim.WeavingClassLoader.findClass(WeavingClassLoader.java:61)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2688)
        at java.lang.Class.getDeclaredMethods(Class.java:1962)
        at kilim.mirrors.RuntimeClassMirror.getDeclaredMethods(RuntimeClassMirrors.java:163)
        at kilim.mirrors.Detector.findPausableMethod(Detector.java:119)
        at kilim.mirrors.Detector.getPausableStatus(Detector.java:71)
        at kilim.analysis.MethodFlow.visitMethodInsn(MethodFlow.java:219)
        at org.objectweb.asm.MethodVisitor.visitMethodInsn(Unknown Source)
        at org.objectweb.asm.tree.MethodNode.visitMethodInsn(Unknown Source)
        at org.objectweb.asm.ClassReader.a(Unknown Source)
        at org.objectweb.asm.ClassReader.b(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at kilim.analysis.ClassFlow.analyze(ClassFlow.java:85)
        at kilim.analysis.ClassWeaver.weave(ClassWeaver.java:93)
        at kilim.tools.Weaver.weave(Weaver.java:297)
        at kilim.tools.Weaver.weave(Weaver.java:255)
        at kilim.WeavingClassLoader.findClass(WeavingClassLoader.java:61)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at kilim.tools.Kilim.main(Kilim.java:24)
    
    opened by nqzero 8
  • putb(T msg, final long timeoutMillis)

    putb(T msg, final long timeoutMillis)

    Hi, I read the MailBox.java and have a question. Why the method putb(T msg, final long timeoutMillis) not reput the msg when the mailbox is not full. But the method put(T msg, int timeoutMillis) reput the msg in a loop. Thanks.

        /**
         * put a non-null message in the mailbox, and block the calling thread  for timeoutMillis
         * if the mailbox is full. 
         */
        public void putb(T msg, final long timeoutMillis) {
            BlockingSubscriber evs = new BlockingSubscriber();
            if (!put(msg, evs)) {
                evs.blockingWait(timeoutMillis);
            }
            if (!evs.eventRcvd) {
                removeSpaceAvailableListener(evs);
            }
        }
    
    /**
         * put a non-null message in the mailbox, and pause the calling task  for timeoutMillis
         * if the mailbox is full. 
         */
    
        public boolean put(T msg, int timeoutMillis) throws Pausable {
            final Task t = Task.getCurrentTask();
            long begin = System.currentTimeMillis();
            while (!put(msg, t)) {
                TimerTask tt = new TimerTask() {
                    public void run() {
                        Mailbox.this.removeSpaceAvailableListener(t);
                        t.onEvent(Mailbox.this, timedOut);
                    }
                };
                Task.timer.schedule(tt, timeoutMillis);
                Task.pause(this);
                removeSpaceAvailableListener(t);
                if (System.currentTimeMillis() - begin >= timeoutMillis) {
                    return false;
                }
            }
            return true;
        }
    
    opened by CurryGaifan 6
  • java.lang.reflect.InvocationTargetException JDK 11, 8 works fine

    java.lang.reflect.InvocationTargetException JDK 11, 8 works fine

    Version: classpath group: 'org.db4j', name: 'kilim', version: '2.0.2' No errors if I use JDK 8. Only happening with 11. Any ideas? Thanks in advance!

    `java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at kilim.tools.Kilim.trampoline(Kilim.java:113) at kilim.tools.Kilim.trampoline(Kilim.java:79) at io.ruin.GameServer.main(GameServer.java:77) Caused by: java.lang.reflect.InvocationTargetException Caused by: java.lang.reflect.InvocationTargetException

    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at kilim.WeavingClassLoader.run(WeavingClassLoader.java:122)
    at kilim.tools.Kilim.trampoline(Kilim.java:110)
    ... 2 more
    

    Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException

    at com.ea.agentloader.AgentLoader$1.loadAgent(AgentLoader.java:244)
    at com.ea.agentloader.AgentLoader.loadAgent(AgentLoader.java:77)
    at com.ea.agentloader.AgentLoader.loadAgentClass(AgentLoader.java:148)
    at com.ea.agentloader.AgentLoader.loadAgentClass(AgentLoader.java:102)
    at io.ruin.GameServer.main(GameServer.java:80)
    ... 8 more
    

    Caused by: java.lang.reflect.InvocationTargetException Caused by: java.lang.reflect.InvocationTargetException

    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at com.ea.agentloader.AgentLoader$1.loadAgent(AgentLoader.java:240)
    ... 12 more
    

    Caused by: java.lang.RuntimeException: java.io.IOException: Can not attach to current VM Caused by: java.lang.RuntimeException: java.io.IOException: Can not attach to current VM

    at com.ea.agentloader.AgentLoaderHotSpot.getVirtualMachine(AgentLoaderHotSpot.java:90)
    at com.ea.agentloader.AgentLoaderHotSpot.loadAgent(AgentLoaderHotSpot.java:56)
    ... 17 more
    

    Caused by: java.io.IOException: Can not attach to current VM at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.(HotSpotVirtualMachine.java:75) Caused by: java.io.IOException: Can not attach to current VM

    at jdk.attach/sun.tools.attach.VirtualMachineImpl.<init>(VirtualMachineImpl.java:48)
    at jdk.attach/sun.tools.attach.AttachProviderImpl.attachVirtualMachine(AttachProviderImpl.java:69)
    at jdk.attach/com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:207)
    at com.ea.agentloader.AgentLoaderHotSpot.getVirtualMachine(AgentLoaderHotSpot.java:86)
    ... 18 more
    

    java.io.FileNotFoundException: null\errors.txt (The system cannot find the path specified) at java.base/java.io.FileOutputStream.open0(Native Method) at java.base/java.io.FileOutputStream.open(FileOutputStream.java:298) at java.base/java.io.FileOutputStream.(FileOutputStream.java:237) at java.base/java.io.FileOutputStream.(FileOutputStream.java:158) at java.base/java.io.FileWriter.(FileWriter.java:82) at io.ruin.api.utils.SimpleLogger.log(SimpleLogger.java:38) at io.ruin.api.utils.ServerWrapper.logError(ServerWrapper.java:26) at io.ruin.api.process.ProcessFactory.lambda$static$0(ProcessFactory.java:10) at java.base/java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1055) at java.base/java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1050) at java.base/java.lang.Thread.dispatchUncaughtException(Thread.java:2001) `

    opened by crazzmc 2
  • IDE Debugger/Java Agent Support

    IDE Debugger/Java Agent Support

    Are there any plans to add support for IDEs who build classes independently from maven/gradle for debugging? Speaking of Visual Studio Code in particular, the run/debug and hot code replace are all useless because there's no way to weave the classes without java agent support.

    opened by Palidino 1
  • a thread-safe problem

    a thread-safe problem

    Hi, I read the code of writeHeader method of kilim.http.HttpResponse class recently. And I found that a static field gmtdf with type java.text.SimpleDateFormat is used for writing HTTP Date header. But as is known to me, the format method of java.text.SimpleDateFormat is not safe in concurrent environment without any synchronization. In order to solve this problem, I think creating a SimpleDateFormat instance for every HttpResponse.writeHeader call, adding an external synchronized block for SimpleDateFormat.format call, or using ThreadLocal for field gmtdf will all be helpful. Anyway, I can submit a PR for this problem after a confirm.

    opened by seedeed 4
  • A return value of boolean type for method: kilim.Cell.putb(T msg, final long timeoutMillis)

    A return value of boolean type for method: kilim.Cell.putb(T msg, final long timeoutMillis)

    I think a boolean return value of method: kilim.Cell.putb(T msg, final long timeoutMillis) is quite needed because a failure due to timeout need handling may be occur.

    opened by seedeed 2
  • Serializable lambdas that are woven fail on deserialization

    Serializable lambdas that are woven fail on deserialization

    Caused by: java.lang.IllegalArgumentException: Invalid lambda deserialization
    

    javac generates a synthetic method to perform the deserialization, but that method first checks the target signature and detects that we've added the fiber arg and fails. using the cfr decompiler (and munging the name), that's equivalent to:

        private static /* synthetic */ Object $deserializeLambda$(SerializedLambda lambda) {
            switch (lambda.getImplMethodName()) {
                case "lambda$static$adfb2a4f$1": {
                    if (lambda.getImplMethodKind() != 6 || !lambda.getFunctionalInterfaceClass().equals("SerTask") || !lambda.getFunctionalInterfaceMethodName().equals("task") || !lambda.getFunctionalInterfaceMethodSignature().equals("()V") || !lambda.getImplClass().equals("SerTask") || !lambda.getImplMethodSignature().equals("()V")) break;
                    return fiber -> {
                        // woven lambda contents omitted for the issue report
                    };
                }
            }
            throw new IllegalArgumentException("Invalid lambda deserialization");
        }
    

    kilim is especially useful for large distributed systems so this is an important use case, ie at present Pausable lambdas cannot be executed on a remote machine

    some options:

    • weave lambdas that include a fiber argument (something similar was done in the jdk10 variant to work around a but in java 10 classloading). downsides: harder to detect unwoven code, no longer possible to manually weave and exposes the fiber arg to the user
    • use ASM to modify the signature check
    • bypass java serialization and create a class by other means on deserialization (not sure that this is doable but conceptually seems possible since that's how the class is generated in the first place). the only component that's needed here is the creation - populating fields would be left to the user, eg using kryo

    any thoughts ?

    opened by nqzero 0
Owner
Sriram Srinivasan
Sriram Srinivasan
Simple Binary Encoding (SBE) - High Performance Message Codec

Simple Binary Encoding (SBE) SBE is an OSI layer 6 presentation for encoding and decoding binary application messages for low-latency financial applic

Real Logic 2.8k Dec 28, 2022
Table-Computing (Simplified as TC) is a distributed light weighted, high performance and low latency stream processing and data analysis framework. Milliseconds latency and 10+ times faster than Flink for complicated use cases.

Table-Computing Welcome to the Table-Computing GitHub. Table-Computing (Simplified as TC) is a distributed light weighted, high performance and low la

Alibaba 34 Oct 14, 2022
Eclipse Collections is a collections framework for Java with optimized data structures and a rich, functional and fluent API.

English | 中文 | Deutsch | Español | Ελληνικά | Français | 日本語 | Norsk (bokmål) | Português-Brasil | Русский | हिंदी Eclipse Collections is a comprehens

Eclipse Foundation 2.1k Dec 29, 2022
A Java library for quickly and efficiently parsing and writing UUIDs

fast-uuid fast-uuid is a Java library for quickly and efficiently parsing and writing UUIDs. It yields the most dramatic performance gains when compar

Jon Chambers 142 Jan 1, 2023
gRPC and protocol buffers for Android, Kotlin, and Java.

Wire “A man got to have a code!” - Omar Little See the project website for documentation and APIs. As our teams and programs grow, the variety and vol

Square 3.9k Jan 5, 2023
The Java collections framework provides a set of interfaces and classes to implement various data structures and algorithms.

Homework #14 Table of Contents General Info Technologies Used Project Status Contact General Information Homework contains topics: Sorting an ArrayLis

Mykhailo 1 Feb 12, 2022
Immutable key/value store with efficient space utilization and fast reads. They are ideal for the use-case of tables built by batch processes and shipped to multiple servers.

Minimal Perfect Hash Tables About Minimal Perfect Hash Tables are an immutable key/value store with efficient space utilization and fast reads. They a

Indeed Engineering 92 Nov 22, 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 5, 2023
Hollow is a java library and toolset for disseminating in-memory datasets from a single producer to many consumers for high performance read-only access.

Hollow Hollow is a java library and toolset for disseminating in-memory datasets from a single producer to many consumers for high performance read-on

Netflix, Inc. 1.1k Dec 25, 2022
Java Collections till the last breadcrumb of memory and performance

Koloboke A family of projects around collections in Java (so far). The Koloboke Collections API A carefully designed extension of the Java Collections

Roman Leventov 967 Nov 14, 2022
LWJGL is a Java library that enables cross-platform access to popular native APIs useful in the development of graphics (OpenGL, Vulkan), audio (OpenAL), parallel computing (OpenCL, CUDA) and XR (OpenVR, LibOVR) applications.

LWJGL - Lightweight Java Game Library 3 LWJGL (https://www.lwjgl.org) is a Java library that enables cross-platform access to popular native APIs usef

Lightweight Java Game Library 4k Dec 29, 2022
A modern I/O library for Android, Kotlin, and Java.

Okio See the project website for documentation and APIs. Okio is a library that complements java.io and java.nio to make it much easier to access, sto

Square 8.2k Dec 31, 2022
Immutable in-memory R-tree and R*-tree implementations in Java with reactive api

rtree In-memory immutable 2D R-tree implementation in java using RxJava Observables for reactive processing of search results. Status: released to Mav

Dave Moten 999 Dec 20, 2022
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

RxJava: Reactive Extensions for the JVM RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-base

ReactiveX 46.7k Dec 30, 2022
Comparison between Java and Common Lisp solutions to a phone-encoding problem described by Prechelt

Prechelt Phone Number Encoding This project implements the phone number encoding described by Lutz Prechelt in his article for the COMMUNICATIONS OF T

Renato Athaydes 27 Nov 30, 2021
Jalgorithm is an open-source Java library which has implemented various algorithms and data structure

We loved Java and algorithms, so We made Jalgorithm ❤ Jalgorithm is an open-source Java library which has implemented various algorithms and data stru

Muhammad Karbalaee 35 Dec 15, 2022
Persistent (immutable) collections for Java and Kotlin

What are Dexx Collections? Dexx Collections are a port of Scala's immutable, persistent collection classes to pure Java. Persistent in the context of

Andrew O'Malley 208 Sep 30, 2022