There is one question asking how and where the js file “resources/sap-ui-core.js” is loaded when you run your ui5 application locally ( for example using tomcat )?

In my sample project mymap, there is no folder named resources and thus no sap-ui-core.js either.

/wp-content/uploads/2014/12/clipboard1_600939.png

However, in the runtime, you could indeed observe the folder resources and the sap-ui-core.js inside it via Chrome development tool, tab “Sources”:


/wp-content/uploads/2014/12/clipboard2_600940.png

In order to figure out what happens in the runtime, let’s have a look at the web.xml under folder WEB-INF in the project.

There is a ResourceServlet defined. Actually it is the responsibility of this servlet delivered by SAP, which returns the content of resouces like js, css and other type in the runtime. So now if I would like to investigate on this servlet, how could I get its source code?

/wp-content/uploads/2014/12/clipboard3_600959.png

How to get source code of ResourceServlet

Suppose you have already an working Tomcat instance.  Right click your UI5 project, choose Export->War file, and manually copy that exported war file to the webapps folder of your tomcat instance folder. In my case the folder is : C:\myProgram\tomcat-7.0.54\webapps.

Now start your tomcat via bat file, in my case: “C:\myProgram\tomcat-7.0.54\bin\startup.bat”:

You should see one information message that the war file is deployed:

/wp-content/uploads/2014/12/clipboard4_600960.png

Now go back to your webapps folder, you should have a folder mymap which is automatically unzipped from war file by Tomcat.


/wp-content/uploads/2014/12/clipboard5_600961.png

Now just search by keyword “Resource”, and unzip the first hit jar file.

/wp-content/uploads/2014/12/clipboard6_600962.png

After that you could find three .class file in the unzipped folder, in my case they are:

“C:\myProgram\tomcat-7.0.54\webapps\mymap\WEB-INF\lib\com.sap.ui5.resource_1.24.1\com\sap\ui5\resource\ResourceServlet.class”

“C:\myProgram\tomcat-7.0.54\webapps\mymap\WEB-INF\lib\com.sap.ui5.resource_1.24.1\com\sap\ui5\resource\impl\ServletResource.class”

“C:\myProgram\tomcat-7.0.54\webapps\mymap\WEB-INF\lib\com.sap.ui5.resource_1.24.1\com\sap\ui5\resource\impl\ServletResourceLocator.class”

The last step, google “jd-gui” and download it. It allows you to directly review source code of a .class file.

/wp-content/uploads/2014/12/clipboard7_600963.png

/wp-content/uploads/2014/12/clipboard8_600964.png

Since now we have source code at hand, we could do further investigation on this servlet.

More investigation on ResourceServlet

The main job of resource handling is wrapped in method serveResource of class ResourceServlet. We could find at least 2 useful hint from this method.

1. use dev mode to figure out where the resource is loaded

/wp-content/uploads/2014/12/clipboard9_600965.png

From line 616 and 617, we get to know if the current application runs under Dev mode, it is supported to print out the url of the found resource in http response header.

Just switch on Dev mode by making following settings in web.xml:

/wp-content/uploads/2014/12/clipboard10_600966.png

after that you could observe the x-sap-ResourcUrl attribute for sap-ui-core.js in Chrome Metwork tab, which shows where Tomcat loads this js file in the runtime.


/wp-content/uploads/2014/12/clipboard10_600966.png

You could directly browse your application resource by appending “/resources/” to your application url, in my case it is: http://localhost:8080/mymap/resources/

/wp-content/uploads/2014/12/clipboard11_600969.png

You might already notice the “CLASSPATH”, what does it mean?

The constructor of ServletResource which extends base class Resource has one parameter source, which indicates whether this resource is loaded locally or remotely ( configured through parameter com.sap.ui5.resource.REMOTE_LOCATION ):

/wp-content/uploads/2014/12/clipboard12_600970.png

in class ServletResourceLocator which implements interface ResourceLocator, the instance for found ServletResource is initialized with corresponding source category, “CLASSPATH” or “REMOTE”, according to different approaches how they are actually loaded:

/wp-content/uploads/2014/12/clipboard13_600971.png

And ResourceServlet will print out this property for each found resource between a pair of “[ ]”:

/wp-content/uploads/2014/12/clipboard14_600972.png

this is the reason why you could see lots of CLASSPATH in tomcat output:

/wp-content/uploads/2014/12/clipboard15_600973.png

2. understand HTTP 304 status

For example, why I get a HTTP 304 Not Modified for this file?

/wp-content/uploads/2014/12/clipboard16_600975.png

The answer is in line 625 of ResourceServlet class:

/wp-content/uploads/2014/12/clipboard17_600976.png

In this example, the second condition after && is always true, since I never make any modifications on this standard library js file:



/wp-content/uploads/2014/12/clipboard18_600977.png

So we only need to evaluate the result of CacheControlFilter.hasNoCacheHeader(request). The source code of this method is listed below:


/wp-content/uploads/2014/12/clipboard19_600978.png

In my example since there is no such Cache-Control in request header, this method will return false and finally leads to a 304 status code.

/wp-content/uploads/2014/12/clipboard20_600979.png


So now if we click the checkbox “Disable cache” in Chrome, we then get a HTTP 200 status code instead, since this checkbox adds a Cache-Control header with value “no-cache”:

/wp-content/uploads/2014/12/clipboard21_600980.png

With the approach introduced in this blog, you could also explore another servlet by yourself, which you could also find and configure it in web.xml: com.sap.ui5.proxy.SimpleProxyServlet.


Enjoy learning 🙂

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Andreas Kunz

    Nice analysis! 🙂

    To give the overall context, the idea behind the ResourceServlet came from a time when the Java platform was by far the main focus and it was supposed to enable the usage of JAR files for packaging – its main purpose is locating resources in those files.

    Other purposes were added, but are not relevant anymore, like a theme fallback: when an image is requested from a theme folder, but it does not exist in this theme, the ResourceServlet looked/looks for the same image in the “base” theme, serving it without causing a 404 request. I’m not sure, whether it actually happens, but the same could be done for translation file locale fallback.

    Other platforms like ABAP, XS Engine (where it was favored not to add server-side logic in UI5) and plain web servers still have to be supported, so the ResourceServlet is a purely optional component. It’s also not contained in the OpenUI5 delivery. Relevant functionality like the proxy you mentioned is being added to the OpenUI5 grunt build/server instead.

    Regards

    Andreas

    (0) 
    1. Jerry Wang Post author

      Hello Andreas,

      Thanks a lot for your nice complement, which makes me understand the story behind this Servlet more holistically 🙂

      Best regards,

      Jerry

      (0) 
  2. Martin Richter

    Hi there,

    a very nice blog post: It shows how to deal with problems like this in a good how-to-manner!

    BTW: The source code for the servlet can be found on github here:

      openui5/ResourceServlet.java at master · SAP/openui5 · GitHub

    Yours,

    M

    PS: In case the master branch does not contain this file anymore somewhen in the future, here is a link to the current version:

      openui5/ResourceServlet.java at 5ecad53b87aa4dba74b18b1d86b0cf7948ab1258 · SAP/openui5 · GitHub

    (0) 
    1. Jerry Wang Post author

      Hi Martin,

      Thanks a lot for your comment, especially the useful information about github location 🙂

      Best regards,

      Jerry

      (0) 

Leave a Reply