jooby-project / jooby

The modular web framework for Java and Kotlin
https://jooby.io
Apache License 2.0
1.71k stars 196 forks source link

Make jooby a more general framework. #422

Closed wenerme closed 7 years ago

wenerme commented 8 years ago

...

wenerme commented 8 years ago

This is how I build my Jooby

    public static void main(String[] args) throws Throwable {
        ServiceApplication
            .builder()
            .scanScope(TextServiceLauncher.class)
            .disableHttp(true)
            .args(args)
            .start();
    }

scanScope is also very useful to bootstrap my service application.

We use Jooby as a basic framework to build out micro services(currently sms-service, chat-service).Jooby is not comparable to spring boot, but Jooby has it's own advantage so I think we should focus on these.

jknack commented 8 years ago

few questions and concerns:

Allowed to disable HTTP So, you need a fake server? That is probably easy to do, but we you probably discuss what the Fake Server does.

Application builder Don't think we need a builder, I think jooby is a builder by itself and everything can be instantiated/added without much trouble... so why a builder?

scanScope Don't think is possible in general... probably for services with a new/extra module... not sure.

Routes/Jooby instances can't be added by scanning... route order defines how the app respond to a request, component scan will break that rule.

Another rule will break is that: we keep reflection to minimum. Also, classpath scanning increase application startup time. Keeping application startup time slow is key to fast and efficient micro-services (boot in few ms)

Jooby is not comparable to spring boot I would love to hear why they aren't comparable (they are in my mind). Also, love to know what benefit do you think Jooby has over SpringBoot (and viceversa)

wenerme commented 8 years ago

Fake server do nothing

    public static class FakeServerModule implements Jooby.Module {
        @Override
        public void configure(Env env, com.typesafe.config.Config conf, Binder binder) {
            binder.bind(Server.class).toInstance(new FakeServer());
        }
    }

    private static class FakeServer implements Server {

        @javax.inject.Inject
        ServiceManager serviceManager;

        @Override
        public void start() throws Exception {
            log.info("FakeServer[Start]");
        }

        @Override
        public void stop() throws Exception {
            log.info("FakeServer[Stop]");
        }

        @Override
        public void join() throws InterruptedException {
            log.info("FakeServer[Join]");
            serviceManager.awaitStopped();
        }
    }

So dose mvc, it is very rare that they got same pattern,if this become a problem an @Order will resolve this problem easily just like Spring dose.

Routes/Jooby instances can't be added by scanning... route order defines how the app respond to a request, component scan will break that rule.


Path scan is fast enought, this should be a feature not required for every application,with project grow it's impossible to specify every route in one Jooby or import every Jooby and things we need to build a real application server.

Another rule will break is that: we keep reflection to minimum. Also, classpath scanning increase application startup time. Keeping application startup time slow is key to fast and efficient micro-services (boot in few ms)


Our project is a tranditional EE project,Spring Boot handle this well

Data (currently ~150 table/enity/repository)
Transaction
Security

This is spring good at,but we also need services that small, do one thing well, fast startup, fast develop to cooperate with the main server, this is Jooby good at, these services will communicat with main server throw redis/hazelcast/http/etc.

I would love to hear why they aren't comparable (they are in my mind). Also, love to know what benefit do you think Jooby has over SpringBoot (and viceversa)

jknack commented 8 years ago

need to think on some of these thoughts, really don't like scanning+order for routes.

Also, isn't impossible to add or maintain routes in large applications and we offer 3 diff approaches for split or organize logically all the routes:

  1. MVC classes
  2. Jobby app
  3. Jooby.Module via env.routes()

What I like from jooby is the deterministic and explicit order of routes (what you see is what you get)... introducing an @Order annotation is verbose, make the framework bloated and I can also say is a source of troubles in large applications too.

wenerme commented 8 years ago

In Spring we got 59 MVC class in main module, convert to jooby, we need to maintain these 59 mvc'class registry, like 59 line of use(mvcClass), also order problem is very rare in real application, we will not put a filter in common mvc class.

The path scan should be a module not a build-in facility, jooby just need to expose some mechanism to make this work.

BTW, we use fast-classpath-scanner it's fast.

jknack commented 8 years ago

ok, convert/moving to jooby makes more sense... yea we can add it as a module

didn't know fast-classpath-scanner looks very good!

let's keep this thread open, will file new issues later.

also, if you enjoy/like jooby please star the project and follow us at https://twitter.com/joobyproject

jknack commented 8 years ago

@wenerme I'm playing with fast-classpath-scanner and want to get/collect all the Guava Services with:

scanner.matchClassesImplementing(Service.class, ...);

But that call doesn't work if my service extends for example: AbstractIdleService

Foo extends AbstractIdleService {...}

Any idea how to fix this?

wenerme commented 8 years ago

Most of time, we only need scan required component,annotated with @Named(like Service or Component in spring), so I scan service by

        scanner
            .matchClassesWithAnnotation(Named.class, named::add)
            .matchClassesWithAnnotation(com.google.inject.name.Named.class, named::add)
        ;

Maybe you problem is Foo not explicit implement Service,

public static class MySvc extends AbstractIdleService implements Service{

When fast-classpath-scanner scan that class do not found any relationship with Service.

jknack commented 8 years ago

Thanks, yea that's the problem... seems silly I have to implements explicitly..

Two more question:

  1. The new module assumes every single services (Named or not) are singleton.. seems OK to me (specially for Guava Services), no?
  2. When you scan for Named do you bind services with name too? Or just type?
wenerme commented 8 years ago

Feel uncomfortable too,maybe we should ask the author, according to the doc the implements is not needed.

  1. @Named scan is singleton by default, same as spring, all service is managed by ServiceManager in guava if there any,then bind ServiceManager's life cycle to jooby.
  2. Just @Named,the name is optional, I'm not using it yet.