Specifying external Javascript URL respecting current sceme


Preface

I have an AbstractJavaScriptComponent that specifies 2 javascript files. I am serving these files using my own servlet.

The app url

https://myurl/

The javascript url

https://myurl/charts/js/Chart.bundle.js

My component

@JavaScript({ “https:charts/js/Chart.bundle.js”, “https:charts/js/ChartsWidget.js” })
public class ChartsWidget extends AbstractJavaScriptComponent {…}

This works well, as the undocumented http:url or https:url (where there is no leading / after the scheme) is resolved correctly relative to the service URL.


Problem

The problem is
my production machine is https and my dev machine is http
. So for now I need to manually change my @Javascript URLs when testing to http:, and the switch them to https: when deploying. It goes without saying that often I deploy without changing this back, and the http URL will not resolve.

The code for this logic seems to be in com.vaadin.shared.VaadinUriResolver. And to complicate things more, seems to be done on the client side. I can’t figure out how to patch the client compiler so I can create a custom sceme.

So my questions are:

  1. Can I specify a path relative to the service URL in the @Javascript annotation without specifying the sceme? It seems the scheme is what signals to use an external file in the first place.

  2. Any suggestions on patching the client compiler to use a custom scheme? Somethink like service:/charts.js, where service will become the service URL + the specified path.

Thanks in advance!

Hi, have you tried just omitting the protocol part?

Any URL without the scheme is treated as a relative or absolute classpath in the declared module. Furthermore, the app and vaadin schemes are hardcoded to the vaadin folder.

True. If the Servlet serving the js files is in the same app, you can do something like this:

@WebServlet(urlPatterns = "/servlet/*")
public static class CustomServlet extends HttpServlet { ... }
@JavaScript("../../servlet/script.js")
public class CustomComponent extends AbstractJavaScriptComponent { ... }

My endpoint is added dynamically by an OSGi bundle. Not in the same app is the whole point. My bundle provides both the javascript component and the javascript to the system; The app does not, and should not need to be aware of it.

My workaround is to run HTTPS on my local machine, but it’s too bad Vaadin does not offer this ability (to resolve external js files relative to the app instead of requiring it to be in the vaadin or themes folder.

On another note, my endpoint provides ‘last-modified’ headers along with the standard expires header. And it does this by reading it’s own jar and using the zip file system. A huge improvement from the standard vaadin stream based approach with class files.

The snipet of code I provided resolves the external file relative to the webapp context, so I would give it a try.

Great, I will give it a try. Thanks Alejandro.

I confirm that “…/…/” + “servlet/resource” resolves to both http://server/servlet/resource and https://server/servlet/resource. Thanks for the workaround Alejandro.

I do think that using parent paths is far from ideal, and would still request that the framework provides a scheme, or at least a defined constant. A little documentation would help too.

After a month, I have seen many differences of using https:resource vs …/…/resource.

Using the method suggested in this post results in less-then optimal headers related to caching, along with classloading issues introduced after swapping bundles in an OSGi environment. It’s much more flexible to expose an endpoint and use https:

So my production and development machine are now both https, and I am hardcoding the protocol in my annotations.

Anybody over at Vaadin want to explain why having a scheme that resolves the @Javascript annotation relative to both the protocol and host is evil and not implemented?

I’m guessing the issue honestly just never came up, or got lost in the shuffle. If you can spare the time, please write a ticket at
dev.vaadin.com
, so someone will have to take a look at it.

Best regards,
Olli

https://dev.vaadin.com/ticket/20465

Thanks!

-Olli