简体   繁体   中英

Static resources from WebJars on IBM WebSphere Application Server not visible

I'm writing a simple reporting web application using JAX-RS and AngularJS deployed to IBM WebSphere Application Server. Since it is really very simple I try to keep as little dependencies as possible, so I am not using any fancy framework server-side.

For serving static resources I wrote this controller. I keep them in src/main/resources folder.

@Path("/")
public class Assets {

    @GET
    @Path("{path:.*\\.js}")
    public Response javascript(@PathParam("path") String resourceName) {
        return serveResource(resourceName, "application/javascript");
    }

    private Response serveResource(String resourceName, String contentType) {
        InputStream inputStream =
            getClass().getClassLoader().getResourceAsStream(resourceName);

        return Response.ok(inputStream)
                .header(HttpHeaders.CONTENT_TYPE, contentType)
                .build();
    }
}

So far so good.

As I use several JavaScript libraries (jQuery, Underscore.js, AngularJS), I wanted to make use of WebJars . According to documentation on webjars.org:

With any Servlet 3 compatible container, the WebJars that are in the WEB-INF/lib directory are automatically made available as static resources. This works because anything in a META-INF/resources directory in a JAR in WEB-INF/lib is automatically exposed as a static resource.

When I put corresponding WebJars into my pom.xml , things stopped working. This is what I found out so far:

  • WebJars are, of course, present in the resulting .war package, in WEB-INF/lib folder.
  • ClassLoader used in my serveResource method claims in has all WebJars in its classpath.
  • The ClassLoader 's implementation is com.ibm.ws.classloader.CompoundClassLoader .
  • None of the resources in present in WebJars in META-INF/resources folder is visible to the ClassLoader . None.

How can I make the class loader see the resources in the WebJars?

For serving files form JAR META-INF/resources you need WebSphere v8.5 .
Check this page for more details - Web container configuration for JavaServer Pages static file access

Use the following methods to locate your static files:

URL ServletContext.getResource(String path)
Set ServletContext.getResourcePaths(String path) 

META-INF/resources directories of fragments under the WEB-INF/Lib directory in the application WAR file

After searching pre-fragment document roots, the web container searches web fragments. A web fragment comprises a JAR file in an application WEB-INF/lib directory. The JAR might include static resources in a META-INF/resources directory that are defined within the JAR file. To prevent the web container from searching META-INF/resources directories, set the com.ibm.ws.webcontainer.SkipMetaInfResourcesProcessing web container custom property to true. The default value for the custom property is false .

 com.ibm.ws.webcontainer.SkipMetaInfResourcesProcessing = true 

UPDATE
Try to change your method to something like this (pseudo code, no exception handling):

public Response javascript(@PathParam("path") String resourceName, 
                           @Context ServletContext servletContext) {

    // make sure resource name starts with / and should be relative path to META-INF/resources
    URL url = serveltContext.getResource(resourceName);  
    InputStream inputStream = url.openStream();

    return Response.ok(inputStream)
            .header(HttpHeaders.CONTENT_TYPE, "application/javascript")
            .build();
}

See ServletContext.getResource and URL.openStream

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM