Skip to content

Regression in ServerServlet.createComponent()  #926

@caleryn

Description

@caleryn

This issue in version 2.2+ appears to have been introduced in issue #876 and due to earlier issues with #767, #766.

Due to this issue it is no longer possible to use a Custom Component with ServerServlet, without using the restlet.xml mechanism. Regrettably this also fails silently, providing only 404s when the application is then called.

There is a workaround available in that the component can be created with the altered constructor and a blank restlet.xml file supplied although this is an unfortunate additional upgrade requirement.

The following addition:

    }else if (targetClass != null){
            log("[Restlet] ServerServlet: configuring component without war:///WEB-INF/restlet.xml");
            component = (Component) targetClass.newInstance();            
    }

Full function below...

Can be made to the function to restore the option of the custom target component, with a default constructor and no restlet.xml file, called in the case where no restlet.xml file is found to configure the Component.

protected org.restlet.Component createComponent() {
    // Detect both customized Component and configuration with restlet.xml
    // file.
    Client warClient = createWarClient(new Context(), getServletConfig());
    String componentClassName = getInitParameter(COMPONENT_KEY, null);
    Class<?> targetClass = null;
    org.restlet.Component component = null;

    if (componentClassName != null) {
        try {
            targetClass = loadClass(componentClassName);
        } catch (ClassNotFoundException e) {
            log("[Restlet] ServerServlet couldn't find the target component class. Please check that your classpath includes "
                    + componentClassName, e);
        }
    }

    // Look for the Component XML configuration file.
    Response response = warClient.handle(new Request(Method.GET,
            "war:///WEB-INF/restlet.xml"));

    try {
        log("[Restlet] ServerServlet: component class is "
                + componentClassName);
        if (response.getStatus().isSuccess()
                && response.isEntityAvailable()) {
            if (targetClass != null) {
                @SuppressWarnings("unchecked")
                Constructor<? extends org.restlet.Component> ctor = ((Class<? extends org.restlet.Component>) targetClass)
                        .getConstructor(Representation.class);

                log("[Restlet] ServerServlet: configuring component from war:///WEB-INF/restlet.xml");
                component = (org.restlet.Component) ctor.newInstance(response
                        .getEntity());
            } else {
                component = new org.restlet.Component(response.getEntity());
            }
        }else if (targetClass != null){
                log("[Restlet] ServerServlet: configuring component without war:///WEB-INF/restlet.xml");
                component = (Component) targetClass.newInstance();            
        }
    } catch (IllegalAccessException e) {
        log("[Restlet] ServerServlet couldn't instantiate the target class. Please check that you have proper access rights to "
                + componentClassName, e);
    } catch (InvocationTargetException e) {
        log("[Restlet] ServerServlet encountered an exception instantiating the target class "
                + componentClassName, e.getTargetException());
    } catch (InstantiationException e) {
        log(String.format(
                "[Restlet] ServerServlet couldn't instantiate the target class. Please check that %s has %s.",
                componentClassName,
                ((response.getStatus().isSuccess()) ? "a constructor taking a Representation as single parameter"
                        : "an empty constructor")), e);
    } catch (NoSuchMethodException e) {
        log(String.format(
                "[Restlet] ServerServlet couldn't instantiate the target class. Please check that %s has %s.",
                componentClassName,
                ((response.getStatus().isSuccess()) ? "a constructor taking Representation as single parameter"
                        : "an empty constructor")), e);
    }

    // Create the default Component
    if (component == null) {
        component = new org.restlet.Component();

        // The status service is disabled by default.
        component.getStatusService().setEnabled(false);

        // Define the list of supported client protocols.
        final String clientProtocolsString = getInitParameter(CLIENTS_KEY,
                null);
        if (clientProtocolsString != null) {
            final String[] clientProtocols = clientProtocolsString
                    .split(" ");
            Client client;

            for (final String clientProtocol : clientProtocols) {
                client = new Client(clientProtocol);

                if (client.isAvailable()) {
                    component.getClients().add(client);
                } else {
                    log("[Restlet] Couldn't find a client connector for protocol "
                            + clientProtocol);
                }
            }
        }
    }

    return component;
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions