0
votes

The Jersey documentation (version 2.29.1) has the following example (Example 9.50. Use of @FormDataParam annotation):

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String postForm(
    @DefaultValue("true") @FormDataParam("enabled") boolean enabled,
    @FormDataParam("data") FileData bean,
    @FormDataParam("file") InputStream file,
    @FormDataParam("file") FormDataContentDisposition fileDisposition) {

    // ...
}

In my case, the method is as follows:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/test")
public Response saveFiles(        
    @FormDataParam("file") InputStream file,
    @FormDataParam("file") FormDataContentDisposition fileDisposition
){
    return Response.ok().build();
}

When the server starts (that is, it does not even reach the method call), I get the following error (using Apache Tomcat / 8.5.16):

Type Exception Report

Message Servlet.init() for servlet [rest.ApplicationConfig] threw exception

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

javax.servlet.ServletException: Servlet.init() for servlet [rest.ApplicationConfig] threw exception org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Thread.java:748)

Root Cause

java.lang.IllegalStateException: The resource configuration is not modifiable in this context. org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:246) org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:193) org.glassfish.jersey.server.ResourceConfig.register(ResourceConfig.java:426) org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:306) org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154) org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:346) javax.servlet.GenericServlet.init(GenericServlet.java:158) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Thread.java:748)

Note The full stack trace of the root cause is available in the server logs.

Moreover, if you remove the @FormDataParam (" file ") InputStream file and@FormDataParam ("file") FormDataContentDisposition fileDisposition, then the server starts normally:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/test")
public Response saveFiles(){
    return Response.ok().build();
}

The server itself is configured without using web.xml, if that matters:

@ApplicationPath("/")
public class ApplicationConfig extends Application {

}

Tried it this way, the result is exactly the same:

@ApplicationPath("/")
public class ApplicationConfig extends ResourceConfig {
    public ApplicationConfig(){            
        register(MultiPartFeature.class);
    }
}

What is the problem and how to fix it?

1

1 Answers

0
votes

Indeed, the problem is in the ApplicationConfig class.
First, the class is in the rest package.
Secondly, this package needs to be added to the constructor of the ApplicationConfig class.

package rest;

@ApplicationPath("/")
public class ApplicationConfig extends ResourceConfig {
    public ApplicationConfig(){
        register(MultiPartFeature.class);
        packages("rest");
    }
}