Giter VIP home page Giter VIP logo

actframework's Introduction

ACT Framework

APL v2 Maven Central Build Status Javadocs Join the chat at https://gitter.im/actframework/actframework Get Support on StackOverflow Feature Requests

Install

Add act-starter-parent into your pom.xml file

  <parent>
    <groupId>org.actframework</groupId>
    <artifactId>act-starter-parent</artifactId>
    <version>1.9.2.0</version>
  </parent>

Or use maven archetype to start a new project:

mvn archetype:generate -B \
    -DgroupId=com.mycom.helloworld \
    -DartifactId=helloworld \
    -DarchetypeGroupId=org.actframework \
    -DarchetypeArtifactId=archetype-quickstart \
    -DarchetypeVersion=1.9.2.0

tips don't forget replace the groupId, artifactId and appName in the above script, or you can use interactive mode to generate your project:

mvn archetype:generate -DarchetypeGroupId=org.actframework -DarchetypeArtifactId=archetype-quickstart -DarchetypeVersion=1.9.2.0

Note There are more ActFramework application archetypes for use. Please get them here.

Features

  • A full stack MVC framework

    • Actframework is NOT a servlet framework. Act app does not run in a servlet container. Instead it run as an independent Java application and it starts in seconds
  • Unbeatable development experience w/ great performance

    • Never restart your app when you are developing. Act's dev mode provides hot reloading feature makes it the dream of every Java web app developer. Check out this 3 mins video and feel it!
    • According to TechEmpower Framework Benchmark Act beats most full stack Java web framework on the market. In some cases Act can be over 10 times faster than Springboot
  • Fully JSR330 Dependency Injection support

    • ActFramework's DI support is built on top of Genie, a lightweight yet fast JSR330 implementation.
    • Benefit from Act's powerful class scan feature, it does not require the user to create injector from modules (as the usually way you use Guice). Declare your module and your binding is automatically registered
  • Superb SPA/Mobile app support

  • Uncompromising Security

  • Annotation aware but not annotation stack

    • Annotation is one of the tool ActFramework used to increase expressiveness. However we do not appreciate crazy annotation stacked code. Instead we make the code to express the intention in a natural way and save the use of annotation whenever possible.

      For example, for the following SpringMVC code:

      @RequestMapping(value="/user/{userId}/invoices", method = RequestMethod.GET)
      public List listUsersInvoices(
        @PathVariable("userId") int user,
        @RequestParam(value = "date", required = false) Date dateOrNull) {
          ...
      }

      The corresponding ActFramework app code is:

      @GetAction("/user/{user}/invoices")
      public List listUsersInvoices(int user, Date date) {
        ...
      }
  • Multi-environment configuration

    • ActFramework supports the concept of profile which allows you to organize your configurations in different environment (defined by profile) easily. Take a look at the following configurations from one of our real project:

      resources
        ├── conf
        │   ├── common
        │   │   ├── app.properties
        │   │   ├── db.properties
        │   │   ├── mail.properties
        │   │   ├── payment.properties
        │   │   └── social.properties
        │   ├── local-no-ui
        │   │   ├── app.properties
        │   │   ├── db.properties
        │   │   └── port.properties
        │   ├── local-sit
        │   │   └── app.properties
        │   ├── local-ui
        │   │   ├── app.properties
        │   │   └── db.properties
        │   ├── sit
        │   │   ├── app.properties
        │   │   └── db.properties
        │   └── uat
        ...
      

      Suppose on your UAT server, you start the application with JVM option -Dprofile=uat, ActFramework will load the configuration in the following sequence:

      1. Read all .properties files in the /resources/conf/common dir
      2. Read all .properties files in the /resources/conf/uat dir

      This way ActFramework use the configuration items defined in uat profile to overwrite the same items defined in common profile. The common items that are not overwritten still effective.

  • Simple yet powerful database support

  • Powerful view architecture with multiple render engine support

  • An unbelievable automate testing framework that never presented in any other MVC frameworks

  • Commonly used tools

Sample code

A HelloWorld app

package demo.helloworld;

import act.Act;
import act.Version;
import org.osgl.mvc.annotation.GetAction;

public class HelloWorldApp {

    @GetAction
    public String sayHelloTo(@DefaultValue("World") String who) {
        return "Hello " + who + "!";
    }

    public static void main(String[] args) throws Exception {
        Act.start();
    }

}

See this 7 mins video on how to create HelloWorld in Eclipse from scratch. or for users without youtube access

A full RESTful service

package demo.rest;

import act.controller.Controller;
import act.db.morphia.MorphiaAdaptiveRecord;
import act.db.morphia.MorphiaDao;
import org.mongodb.morphia.annotations.Entity;
import org.osgl.mvc.annotation.*;

import java.util.Map;

import static act.controller.Controller.Util.notFoundIfNull;

@Entity("user")
public class User extends MorphiaAdaptiveRecord<User> {

    @UrlContext("user")
    public static class Service extends MorphiaDao<User> {

        @PostAction
        public User create(User user) {
            return save(user);
        }

        @GetAction
        public Iterable<User> list() {
            return findAll();
        }

        @GetAction("{id}")
        public User show(@DbBind("id") User user) {
            return user;
        }

        @PutAction("{id}")
        public User update(@DbBind("id") @NotNull User user, Map<String, Object> data) {
            user.mergeValues(data);
            return save(user);
        }

        @DeleteAction("{id}")
        public void delete(String id) {
            deleteById(id);
        }
    }

    public static void main(String[] args) throws Exception {
        Act.start();
    }

}

See this 1 hour video on RESTful support or for user without youtube access

See this 7 mins video to understand more about AdaptiveRecord or for user without youtube access

Background

I love PlayFramework v1.x because it is simple, clear and expressive. It brought us a completely different experience in web development with Java. However I don't totally agree with where Play 2.X is heading for, and it looks like I am not the only person with the concern as per this open letter to Play Framework Developers.

I have thought of rolling out something that could follow the road paved by Play 1.x, something that is simple, clear, expressive and Java (specifically) developer friendly. About one and half year after that I decide I could start the project seriously, and now another one and half year passed by, I've got this ACT framework in a relatively good shape.

Happy coding!

actframework's People

Contributors

benstonezhang avatar dependabot[bot] avatar gitter-badger avatar greenlaw110 avatar jlleitschuh avatar leeaee avatar naixinxiaozi avatar yangyang0507 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

actframework's Issues

Improve response with array type return result

Given the following action code:

@GetAction("/foo")
public boolean[] foo(boolean[] v) {
    return v;
}

If no template is defined, it renders something like [Z@84f028a. Expected result: [true, false]

DataObjectEnhancer generated hashCode method failed when fields number exceed 5

Here is the stacktrace:

java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    testapp/model/Person2.hashCode()I @30: invokestatic
  Reason:
    Type 'java/lang/Integer' (current frame, stack[5]) is not assignable to '[Ljava/lang/Object;'
  Current Frame:
    bci: @30
    flags: { }
    locals: { 'testapp/model/Person2' }
    stack: { 'java/lang/String', 'java/lang/String', 'testapp/model/Address2', 'testapp/model/Person2$Gender', 'java/lang/Integer', 'java/lang/Integer' }
  Bytecode:
    0000000: 2ab4 0021 2ab4 0023 2ab4 0025 2ab4 001f
    0000010: 2ab4 002d b800 5e2a b400 2fb8 005e b800
    0000020: 62ac                                   


    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2595)
    at java.lang.Class.getConstructors(Class.java:1530)
    at org.osgl.Osgl.newInstance(Osgl.java:5305)
    at act.util.DataObjectEnhancerTest.setup(DataObjectEnhancerTest.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Application take 20s to bootup

In my application (over 9500 lines of code), it takes 20 seconds to bootup. Need to check what caused the slow app start behavior

Cannot resolve byte type parameter if pass in a JSON body

For a given action:

@Action("/foo")
public byte foo(byte b) {
    return b;
}

Send a POST request with JSON body:

{"b": 127}

The system will respond with 400 Bad Request. Expected response: 200 with 127 in the body

Note, GET request with query parameters, or POST request with x-www-form-urlencoded form data won't trigger this issue

URL dynamic part variable name not captured

Given the following two action handlers:

@GetAction("/dyna/{s1}/abc")
public String handleAbc(String s1) {
    return s1;
}

@GetAction("/dyna/{s2}/xyz")
public String handleXyz(String s2) {
    return s2;
}

Calling to /dyna/some_string/xyz returns empty string, instead of some_string

Support File type parameters in commander method

Allow user to put File type parameters in commander method e.g.

   @Command(name = "bn.contract.set", help = "set a contract to a business node")
    public void setContract(
            @Required(lead = "-n --node", help = "specify the business node") String business_node,
            @Required(lead = "-f", help = "specify the template content or path") File templateFile,
            @Optional("optionally specify the render id. Default value is rythm") String render,
            @Context CliContext context
    ) {
        BusinessNode.Service bnService = BusinessNode.dao();
        BusinessNode businessNode = bnService.findOne(business_node);
        notFoundIfNull(businessNode);
        AAA.requirePermission(businessNode, ConnPermissions.MANAGE_BUSINESS_NODE);
        String template = IO.readContentAsString(templateFile);
        Contract contract = new Contract(template, ContractRender.get(render));
        businessNode.setContract(contract);
        bnService.save(businessNode);
        context.println("contract has been set on business node");
    }

In the command line, user can specify the file by path. e.g.

bn.contract.set -f contract.html -n myaccount:accouting

The framework shall get the file based on current working dir

bytecode enhancement on handling returned Result failure on HelloWorld demo

The working code is:

    @GetAction("/greeting")
    public Result greeting(String who, int age) {
        return render(who, age);
    }

As I update it as

    @GetAction("/greeting")
    public void greeting(String who, int age) {
        render(who, age);
    }

It raises the follow error:

java.lang.VerifyError: Operand stack overflow
Exception Details:
  Location:
    act/fsa/helloworld/HelloWorldApp.greeting(Ljava/lang/String;I)V @10: ldc
  Reason:
    Exceeded max stack size.
  Current Frame:
    bci: @10
    flags: { }
    locals: { 'act/fsa/helloworld/HelloWorldApp', 'java/lang/String', integer }
    stack: { '[Ljava/lang/Object;', '[Ljava/lang/Object;', integer, 'act/app/AppContext' }
  Bytecode:
    0000000: 05bd 0004 5903 2ab4 002a 1255 1cb8 005b
    0000010: b600 5f12 612b b600 5f12 63b6 0067 572b
    0000020: 5359 041c b800 5b53 b800 6bbf          

        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:274)
        at org.osgl._.classForName(_.java:4586)
        at act.handler.builtin.controller.impl.ReflectedHandlerInvoker.<init>(ReflectedHandlerInvoker.java:52)
        at act.handler.builtin.controller.impl.ReflectedHandlerInvoker.createControllerAction(ReflectedHandlerInvoker.java:206)
        at act.Act$Mode.createRequestHandler(Act.java:70)
        at act.handler.builtin.controller.RequestHandlerProxy.generateHandlers(RequestHandlerProxy.java:216)
        at act.handler.builtin.controller.RequestHandlerProxy.ensureAgentsReady(RequestHandlerProxy.java:193)
        at act.handler.builtin.controller.RequestHandlerProxy.handle(RequestHandlerProxy.java:117)
        at act.handler.DelegateRequestHandler.handle(DelegateRequestHandler.java:18)
        at act.route.Router$ContextualHandler.handle(Router.java:514)
        at act.xio.NetworkClient.handle(NetworkClient.java:40)
        at act.xio.undertow.ActHttpHandler.handleRequest(ActHttpHandler.java:27)
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197)
        at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:181)
        at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:108)
        at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:130)
        at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:81)
        at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:45)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
        at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:291)
        at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:286)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
        at org.xnio.nio.NioTcpServerHandle.handleReady(NioTcpServerHandle.java:53)
        at org.xnio.nio.WorkerThread.run(WorkerThread.java:539)

ClassNotFoundException after refactoring source code

After Refactoring Guice demo app by moving module classes into other package, hit F5 on browser, got the following error in the app console:

org.osgl.exception.UnexpectedException: java.lang.ClassNotFoundException: act.fsa.guice.modules.HiModule
        at org.osgl._.classForName(_.java:4588)
        at act.di.guice.GuicePlugin$1.apply(GuicePlugin.java:26)
        at act.di.guice.GuicePlugin$1.apply(GuicePlugin.java:16)
        at act.util.SubTypeFinder2$ByteCodeSensor.scanFinished(SubTypeFinder2.java:104)
        at act.app.AppClassLoader.scanByteCode(AppClassLoader.java:127)
        at act.app.DevModeClassLoader.scanSources(DevModeClassLoader.java:119)
        at act.app.DevModeClassLoader.scan2(DevModeClassLoader.java:48)
        at act.app.App.scanAppCodes(App.java:248)
        at act.app.App.refresh(App.java:118)
        at act.xio.NetworkClient.handle(NetworkClient.java:34)
        at act.xio.undertow.ActHttpHandler.handleRequest(ActHttpHandler.java:27)
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197)
        at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:181)
        at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:108)
        at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:49)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
        at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
        at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
        at org.xnio.nio.WorkerThread.run(WorkerThread.java:539)
Caused by: java.lang.ClassNotFoundException: act.fsa.guice.modules.HiModule
        at java.lang.ClassLoader.findClass(ClassLoader.java:531)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at act.boot.app.FullStackAppBootstrapClassLoader.loadClass(FullStackAppBootstrapClassLoader.java:113)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        at act.app.AppClassLoader.loadClass(AppClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:278)
        at org.osgl._.classForName(_.java:4586)
        ... 18 more

Binding to BigInteger and BigDecimal failed

Sending request to the following action method will always result in null value be set on bar:

@Action("/foo")
public void foo(BigInteger bar) {
    System.out.println(bar);
}

Provide sequence number generator facility

So the facility shall allow application developer to generate sequence number based on sequence names. In the mean time, admin tool shall be provided to inspect or generate sequence numbers

Support @async annotation on public void method

For a given class:

public class Foo {
    private static final Logger logger = LogManager.get(Foo.class);
    @Async
    public void bar(String s, int i) {
        logger.info("calling Foo.bar with s=%s, i = %i", s, i);
    }
}

Enhance the Foo.bar(...) method so that calling to that method will be invoked asynchronously in a different thread

Enhance metric access command

Provide the more options to access actframework metric:

  • tree view: organize metric in a tree hierarchy
  • filter: display/suppress metrics matches specific regular expression
  • level: display metrics at specific level in the hierarchy
  • intelli-metric: display time duration in days/hours/minutes/seconds/ms/ns based on the value

Console command cannot process single quotation mark

When I type the following command

act[1sbKTo1d1]>survey.add -s 56ca7c17fa2f5b7dc867257e -q 'Why are you visiting the shop today?'

I got the following data:

act[1sbKTo1e1]>survey.show -s 56ca7c17fa2f5b7dc867257e
[default]
'Why

Expected data should be:

act[1sbKTo1e1]>survey.show -s 56ca7c17fa2f5b7dc867257e
[default]
Why are you visiting the shop today?

Guice dependency injection error while code refactoring

After refactoring code and hit F5 on browser, app console got the following error:

May 30, 2015 8:06:31 AM act.handler.builtin.controller.RequestHandlerProxy error
SEVERE: Error handling request
com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for act.fsa.guice.modules.greeting.GreetingService was bound.
  while locating act.fsa.guice.modules.greeting.GreetingService
    for field at act.fsa.guice.DemoController.greeting(DemoController.java:13)
  while locating act.fsa.guice.DemoController

2) No implementation for act.fsa.guice.modules.hi.HiService was bound.
  while locating act.fsa.guice.modules.hi.HiService
    for field at act.fsa.guice.DemoController.hi(DemoController.java:13)
  while locating act.fsa.guice.DemoController

2 errors
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1042)
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1001)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
    at act.di.guice.GuiceDependencyInjector.create(GuiceDependencyInjector.java:35)
    at act.app.App.newInstance(App.java:170)
    at act.handler.builtin.controller.impl.ReflectedHandlerInvoker.controllerInstance(ReflectedHandlerInvoker.java:111)
    at act.handler.builtin.controller.impl.ReflectedHandlerInvoker.handle(ReflectedHandlerInvoker.java:81)
    at act.handler.builtin.controller.impl.ReflectedHandlerInvoker$_Before.handle(ReflectedHandlerInvoker.java:235)
    at act.handler.builtin.controller.RequestHandlerProxy$GroupInterceptorWithResult.apply(RequestHandlerProxy.java:357)
    at act.handler.builtin.controller.RequestHandlerProxy.handleBefore(RequestHandlerProxy.java:257)
    at act.handler.builtin.controller.RequestHandlerProxy.handle(RequestHandlerProxy.java:123)
    at act.handler.DelegateRequestHandler.handle(DelegateRequestHandler.java:18)
    at act.route.Router$ContextualHandler.handle(Router.java:530)
    at act.xio.NetworkClient.handle(NetworkClient.java:40)
    at act.xio.undertow.ActHttpHandler.handleRequest(ActHttpHandler.java:27)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197)
    at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:181)
    at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:108)
    at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:49)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
    at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
    at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
    at org.xnio.nio.WorkerThread.run(WorkerThread.java:539)

Render template with return type "Object[]"

The framework at the moment does not handle the case when template is defined and action method return type is Object[].

It needs to implement the logic as below:

  1. If the template engine support passing render parameters by position, e.g. Rythm, it shall apply to that feature
  2. If the engine does not support passing render parameters by position, it needs to create a render argument Map with key set to "result" and value set to the return object

Support binding request parameter to controller class field

At the moment ActFramework support binding to controller method declared parameter. This request is to allow application developer to declare request parameter as Controller class field.

Quality gate the following case can run as expected:

public class ParamVsField {

    public static final String PATH = "param_vs_field";

    String bar;

    @Action(PATH)
    public String concatenate(String foo) {
        return foo + bar;
    }

}

Allow command line function declare a String type parameter to read the specified file

Create an new annotation ReadFileContent so that if the specified parameter is a file then read that file content to fill into the parameter

@Commander(name = "do.something", help = "do something with configuration specified") 
public String doSomething(
    @Required @ReadFileContent String conf
) {
   return conf;
}

Scenario A, specified parameter is a file:

do.something --conf /tmp/my.conf

This will print out the content of /tmp/my.conf

Scenario B, specified parameter is not a file:

do.something --conf 'foo=bar'

This will print out foo=bar

Improve daemon facilities

  • keep timestamp for events including started, error happened
  • report status should include the timestamp info
  • improve daemon keeper logic: restart daemon duration shall be based on fibonacci sequence

Source code refresh triggered error

While I played around with the HelloWorld demo I run into this error:

SEVERE: Error handling request
java.lang.ClassCastException: act.fsa.helloworld.HelloWorldApp cannot be cast to act.fsa.helloworld.HelloWorldApp
        at act.fsa.helloworld.HelloWorldAppFieldAccess.set(Unknown Source)
        at act.handler.builtin.controller.impl.ReflectedHandlerInvoker$2.apply(ReflectedHandlerInvoker.java:192)
        at act.handler.builtin.controller.impl.ReflectedHandlerInvoker$2.apply(ReflectedHandlerInvoker.java:186)
        at act.handler.builtin.controller.impl.ReflectedHandlerInvoker.applyAppContext(ReflectedHandlerInvoker.java:119)
        at act.handler.builtin.controller.impl.ReflectedHandlerInvoker.handle(ReflectedHandlerInvoker.java:82)
        at act.handler.builtin.controller.impl.ReflectedHandlerInvoker$_Before.handle(ReflectedHandlerInvoker.java:235)
        at act.handler.builtin.controller.RequestHandlerProxy$GroupInterceptorWithResult.apply(RequestHandlerProxy.java:346)
        at act.handler.builtin.controller.RequestHandlerProxy.handleBefore(RequestHandlerProxy.java:251)
        at act.handler.builtin.controller.RequestHandlerProxy.handle(RequestHandlerProxy.java:120)
        at act.handler.DelegateRequestHandler.handle(DelegateRequestHandler.java:18)
        at act.route.Router$ContextualHandler.handle(Router.java:514)
        at act.xio.NetworkClient.handle(NetworkClient.java:40)
        at act.xio.undertow.ActHttpHandler.handleRequest(ActHttpHandler.java:27)
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197)
        at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:181)
        at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:108)
        at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:49)
        at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
        at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
        at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
        at org.xnio.nio.WorkerThread.run(WorkerThread.java:539)

Job method in an embedded class cause app failed to start

Stacktrace:

Exception in thread "main" org.osgl.exception.UnexpectedException: Unknown error captured starting the application
        at org.osgl.util.E.unexpected(E.java:127)
        at act.boot.app.RunApp.start(RunApp.java:66)
        at act.boot.app.RunApp.start(RunApp.java:32)
        at com.p.c.Conn.main(Conn.java:20)
Caused by: java.lang.NoClassDefFoundError: com/p/c/model/NotificationModel$DaoMethodAccess (wrong name: com/p/c/model/NotificationModel)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at act.app.AppClassLoader.loadAppClass(AppClassLoader.java:379)
        at act.app.AppClassLoader.loadClass(AppClassLoader.java:181)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at com.esotericsoftware.reflectasm.AccessClassLoader.loadClass(AccessClassLoader.java:79)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at com.esotericsoftware.reflectasm.MethodAccess.get(MethodAccess.java:99)
        at act.job.bytecode.ReflectedJobInvoker.init(ReflectedJobInvoker.java:48)
        at act.job.bytecode.ReflectedJobInvoker.apply(ReflectedJobInvoker.java:63)
        at act.job._Job.doJob(_Job.java:200)
        at act.job._Job.run(_Job.java:162)
        at act.job._Job.runFollowingJobs(_Job.java:215)
        at act.job._Job.run(_Job.java:194)
        at act.job.AppJobManager$_AppEventListener.on(AppJobManager.java:252)
        at act.event.EventBus.callOn(EventBus.java:203)
        at act.event.EventBus.callOn(EventBus.java:227)
        at act.event.EventBus.callOn(EventBus.java:248)
        at act.event.EventBus.emit(EventBus.java:269)
        at act.event.EventBus.emit(EventBus.java:257)
        at act.app.App.emit(App.java:582)
        at act.app.App.refresh(App.java:334)
        at act.app.AppManager.load(AppManager.java:50)
        at act.app.AppManager$_F$1.visit(AppManager.java:115)
        at act.app.AppManager$_F$1.visit(AppManager.java:112)
        at org.osgl.Osgl$Visitor.apply(Osgl.java:2227)
        at org.osgl.Osgl$Visitor.apply(Osgl.java:2217)
        at act.app.AppScanner.scan(AppScanner.java:74)
        at act.app.AppScanner.scan(AppScanner.java:54)
        at act.app.AppManager.loadSingleApp(AppManager.java:28)
        at act.Act.start(Act.java:244)
        at act.Act.startApp(Act.java:218)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at act.boot.app.RunApp.start(RunApp.java:60)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.