ClassLoader general usage with webapp-webjars

Hi all,

I’m trying to use the webapp-webjar dependency in my project, but it seems that the structur in the webjar could not be directly loaded via ResourceLoader. If I try to open an app (i.e. admin) the following error is raised:

SCHWERWIEGEND: Servlet.service() for servlet [default] in context with path [/component.web.camunda] threw exception
java.lang.RuntimeException: java.lang.NullPointerException
	at org.camunda.bpm.webapp.impl.security.auth.AuthenticationFilter$1.execute(AuthenticationFilter.java:61)
	at org.camunda.bpm.webapp.impl.security.auth.AuthenticationFilter$1.execute(AuthenticationFilter.java:56)
	at org.camunda.bpm.webapp.impl.security.SecurityActions.runWithAuthentications(SecurityActions.java:38)
	at org.camunda.bpm.webapp.impl.security.auth.AuthenticationFilter.doFilter(AuthenticationFilter.java:56)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
	at java.io.Reader.<init>(Reader.java:78)
	at java.io.InputStreamReader.<init>(InputStreamReader.java:72)
	at org.camunda.bpm.webapp.impl.filter.AbstractTemplateFilter.getWebResourceContents(AbstractTemplateFilter.java:92)
	at org.camunda.bpm.webapp.impl.engine.ProcessEnginesFilter.serveIndexPage(ProcessEnginesFilter.java:225)
	at org.camunda.bpm.webapp.impl.engine.ProcessEnginesFilter.serveIndexPage(ProcessEnginesFilter.java:155)
	at org.camunda.bpm.webapp.impl.engine.ProcessEnginesFilter.applyFilter(ProcessEnginesFilter.java:105)
	at org.camunda.bpm.webapp.impl.filter.AbstractTemplateFilter.doFilter(AbstractTemplateFilter.java:42)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.camunda.bpm.webapp.impl.security.filter.SecurityFilter.doFilterSecure(SecurityFilter.java:67)
	at org.camunda.bpm.webapp.impl.security.filter.SecurityFilter.doFilter(SecurityFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.camunda.bpm.webapp.impl.security.auth.AuthenticationFilter$1.execute(AuthenticationFilter.java:59)
	... 21 more

In debug I can see, that camunda tries to load the index.html from admin-app, but the code:
is = filterConfig.getServletContext().getResourceAsStream(name);

is null and so the resource couldn’t be loaded. Is there any hint I’m missing to get static resources out of the webjar?

If I paste the content directly to my project everything is working fine and I can start all apps.

I’m running Camunda 7.6.0-alpha2 on Tomcat 8.0.26 with process engine standalone in project (not shared in tomcat).

Looking forward to your answers with sunny cheers :slight_smile:
Thomas

Me again :grin:

Has no one an idea or hint how to locate the static-content in the webjar?

The structure is not “classic” like jars from http://www.webjars.org/ - in this case the static content is included in folder:

META-INF/resources/webjar/{product}/{version}"

so we can use the webjar-locator to scan all jars for webjar-style, but in camunde-webjar the static content is placed in root of the jar, so I’ve got no idea how to locate the content.

For the spring-environment there seems to be a solution to register the paths to the ResourceHandlerRegistry like:
registry.addResourceHandler("/lib/").addResourceLocations(“classpath:/lib/”);
registry.addResourceHandler("/api/
").addResourceLocations(“classpath:/api/”);
registry.addResourceHandler("/app/**").addResourceLocations(“classpath:/app/”);

but in non-spring-environment I got no idea how to solve the problem. (OK, decompress the jar at runtime could be a solution, but this isn’t the prevered way) :slight_smile:

Any suggestions on this are welcome?

Looking forward to your answer.

Cheers, Thomas

Hi @webert,

where are you getting webjar from? maven central? There have been a problem with 7.6.0-alpha2 deployment to maven central. Could you try using camunda nexus?

Cheers,
Askar.

Hi Askar,

thanks for your reply. I use the webjar from camunda nexus - I know the bug with maven-central and jcenter (I reported it) :slight_smile:

It looks like the structure in the jar is wrong to load as classical webjar … I think there must be a servler-filter or something to get resources out of the jar. AFAIK the “normal” way with a classloader couldn’t work, cause the files are not in folder META-INF/resources, so tomcat is not able to load them.

UPDATE: I patched locally the camunda-webapp-webjar-alpha2.jar and moved all resources from the jar-root to the folder “META-INF/resources” and now tomcat is able to load all static stuff (html, css, images, etc.) from jar without any Filter or ResourceLoader.

Now my local jar follows the servlet 3.x specification. (see section 10.5 in Servlet 3.0 specification) and everything seems OK.

Is there a plan to structure the camunda-webapp-webjar to follow the specification?

Cheers,
Thomas

Hi Thomas … have a look at https://app.camunda.com/jira/browse/CAM-5835

It would be great if you could contribute your changes.

Jan

Hi Jan,

no problem - just registered to your JIRA, yet.

But I’m not so versed in JIRA, can you tell me, where I can upload my patched version?

Actually I’m on the way, and I will do the upload later.

Cheers,
Thomas

cool. You create a pull request to github. The jira is just for tracking the issues. Its good practice to pull-request from a feature branch named like the jira issue …

OK, back again :slight_smile:

Since Github no longer supports multiple accounts, I cannot clone the repository to my company-laptop which is configured to our company git-server. The other problem is, that the firewall is blocking the traffic.

I patched the jar manually and can send it to you (or write down the differences - they are easy to explain).

Old structure:
/META-INF/maven/…
/META-INF/MANIFEST.MF
/app/…
/lib/…
/plugin/…
/index.html
/securityFilterRules.json

New structure:
/META-INF/maven/…
/META-INF/MANIFEST.MF
/META-INF/resources/app/…
/META-INF/resources/lib/…
/META-INF/resources/plugin/…
/META-INF/resources/index.html
/META-INF/resources/securityFilterRules.json

As you can see, I simply put the content from the root to “META-INF/resources” and leave the other stuff as is.

This follows the specification explained above and can be loaded with all servlet-containers.

If you plan to publish the webjar to http://www.webjars.org/ you can follow a deeper structure like:

webjar.org structure:
/META-INF/maven/…
/META-INF/MANIFEST.MF
/META-INF/resources/webjars/camunda-webapp-webjar/7.0.6-alpha2/app/…
/META-INF/resources/webjars/camunda-webapp-webjar/7.0.6-alpha2/lib/…
/META-INF/resources/webjars/camunda-webapp-webjar/7.0.6-alpha2/plugin/…
/META-INF/resources/webjars/camunda-webapp-webjar/7.0.6-alpha2/index.html
/META-INF/resources/webjars/camunda-webapp-webjar/7.0.6-alpha2/securityFilterRules.json

…but to load this efficient with a servlet-container, you have to use a filter build on webjar-locator. It requires also to check all sources for relative/absolute paths and so on… (Think this is too much at this time).

I would be happy, if the webjars follows the structure described in New structure above and it should be easy to change in the build-process.

What do you mean?

PS: If you prefer the webjar.org structure I can send you a dynamicWebjarFilter which I developed to use the webjars in any versions without changing any code.

Cheers,
Thomas

1 Like

Hi @webert,

could you attach a patch file to the ticket if you cant do a pull request?

Cheers,
Askar

Hi @aakhmerov,

gladly :slight_smile: added attachment to the ticket.

Cheers,
Thomas