javalite / activeweb

ActiveWeb moved, see below

Home Page:http://javalite.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom route not recognized when controller in sub-package

ipolevoy opened this issue · comments

It still fails to load the right action when using the latest 2.3-SNAPSHOT version.
Here is my routes definition:

package app.config;

import app.controllers.api.v2.AuthorsController;
import app.controllers.api.v2.InterventionsController;
import org.javalite.activeweb.AbstractRouteConfig;
import org.javalite.activeweb.AppContext;


public class RouteConfig extends AbstractRouteConfig {
    @Override
    public void init(AppContext appContext) {
      route("/{controller}/invoiceNumber/{invoiceNumber}").to(InterventionsController.class).action("findByInvoiceNumber");
      route("/{controller}/documentNumber/{documentNumber}/states").to(InterventionsController.class).action("statesByDocumentNumber");
      route("/{controller}/documentNumber/{documentNumber}/events").to(InterventionsController.class).action("eventsByDocumentNumber");
      route("/{controller}/documentNumber/{documentNumber}").to(InterventionsController.class).action("findByDocumentNumber");
      route("/{controller}/{aut_id}").to(AuthorsController.class).action("findById");
    }
}

Here is the controller:

package app.controllers.api.v2;
...
    public void findByInvoiceNumber() {
        if (blank("invoiceNumber")) {
            throw new RuntimeException("Invoice number is mandatory but was empty or null");
        } else {
            String invoiceNumber = takeFirst16digitsOf(param("invoiceNumber"));
            final Intervention intervention = Intervention.findFirst("ITV_INVOICE = ?", invoiceNumber);
            String jsonResponse = intervention.toJson(false);
            respond(jsonResponse);
        }
    }

The error stack trace:

qtp437098149-24] INFO org.javalite.activeweb.RequestDispatcher - {"info":"executing controller","controller":"app.controllers.api.v2.InterventionsController","action":"invoiceNumber","method":"GET"}
[qtp437098149-24] INFO org.javalite.activejdbc.Configuration - Environment variable ACTIVE_ENV not provided, defaulting to 'development'
[qtp437098149-24] INFO org.javalite.activeweb.controller_filters.TimingFilter - Processed request in: 299 milliseconds, path: /api/v2/interventions/invoiceNumber/316838999866677400000000978000, method: GET
[qtp437098149-24] INFO org.javalite.activeweb.RequestDispatcher - {"controller":"app.controllers.api.v2.InterventionsController","duration_millis":839,"remote_ip":"0:0:0:0:0:0:0:1","method":"GET","action":"invoiceNumber","error":"java.lang.NoSuchMethodException: app.controllers.api.v2.InterventionsController.invoiceNumber(); app.controllers.api.v2.InterventionsController.invoiceNumber()","url":"http://localhost:8080/api/v2/interventions/invoiceNumber/316838999866677400000000978000","status":404}
[qtp437098149-24] INFO org.javalite.activeweb.freemarker.FreeMarkerTemplateManager - Rendering template: '/system/404.ftl' with layout: '/layouts/default_layout.ftl'. 
...

Here is the snapshot of Maven dependencies:
screen shot 2018-09-19 at 14 30 26

The same error for AuthorsController, it tries to call "action":"9" when hitting url":"http://localhost:8080/api/v2/authors/9

It seems like the error comes from DynamicClassFactory#compileClass method when calling compile.invoke((Object)null, args, out); and throws the error:
screen shot 2018-09-19 at 17 05 27

Moreover, I have:

[qtp1661690256-22] ERROR org.javalite.activeweb.RequestDispatcher - ActiveWeb internal error: 
java.lang.NoClassDefFoundError: org/javalite/common/JsonHelper

To reproduce the issue, I created a project here.

By the way, tools.jar is in the right place on my Mac, OS X 10.13.6:
/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/lib there is no more ned to use custom profiles as you proposed.

I found the issue. If you declare the custom route like this:

route("/api/v2/{controller}/{aut_id}").to(AuthorsController.class).action("findById");

then your calls will work just fine:

curl http://localhost:8080/api/v2/authors/9

The {controller} segment in the custom route points to a "controller name", which is an underscored short name of the controller class. This needs to documented better.

I simplified code in controller so as not to deal with a database:

public class AuthorsController extends APIController {
    public void findById() {
        respond("hello: " + param("aut_id"));
    }
}

and getting this response:

curl http://localhost:8080/api/v2/authors/9
hello: 9 

so, this is working as expected.

You do not need to use TimingFilter - the framework does the timing now, since 2.2. Also, register CatchAllFilter before any other filter, so you catch and process any exceptions, including DB - related.

Great ! Thank you so much, Igor, - I updated the code source as you suggested. It works as needed now. Just one minor point (may be not related to the framework), - I'm getting the below error
screen shot 2018-09-20 at 09 46 22

no matter when using Restlet Client or Postman
screen shot 2018-09-20 at 09 52 52

not sure about that, try a different client, such as curl :

curl http://localhost:8080/api/v2/authors/9

Yeah, it works just fine both with curl and HTTPie, thank you.