Storing web content in a JAR file - java

Is it possible to store web content (such as JSPs, HTML, images, CSS etc) in a JAR file?
I've been looking at various options at modularising our web applications and this is one possibility.
We are currently using JSF and Facelets for our view technology - I'm thinking it may be possible to write some form of custom view resolver which would examine the classpath rather than a filesystem directory, but I'm not sure this would work.
Any ideas would be appreciated! :)
Update: I should probably clarify. How do you get the web container (such as Tomcat) to load resources from a JAR file? For example, I deploy a .war file with my web application. If I access /index.jsp, the container will try to look in the web content directory for a file named index.jsp.
Is there an easy way to configure your own resource loader using Tomcat or the like so that it searches the classpath as well as the filesystem?

If you are using Maven to build your webapp, you can build a WAR of your resources and overlay that WAR onto your webapp WAR at build time.
The resource WAR containing all of your JSPs, images, CSS, etc. is referred to as an "overlay," and is simply a dependency in your target webapp with the type set to "war."
When you package your webapp, the resource WAR will only copy over non-conflicting files. So, if you have a unique index.jsp in your project, and would like to use that instead of the index.jsp in the overlay, just include it in your target webapp, and Maven will not copy over that resource.
More info on the Maven War plugin page about overlays.

Yes, it is possible to store files e.g. properties, xml, xslt, image etc; in a JAR (or WAR) file and pull them at runtime.
To load a resource from your deployment jar, use the following code.
this.getClass().getClassLoader().getResourceAsStream( filename ) ;
In a maven project, folders & files placed in resources are included in the jar. The filename is relative to the root of jar file, so "./filename.xml" would match the file filename.xml placed in "/src/java/resources".

Absolutely. Heck, you can store content directly in a WAR file, which is basically a JAR file with a few extra bits. Yes, you may need to write a custom resolver to use ClassLoader.getResourceAsStream, but basically as you're given the ability to generate the content however you like, fetching it from a jar file seems perfectly reasonable. You'll probably want to make sure it only fetches a very specific set of extensions though :)

You can also use the weblets project (see https://weblets.dev.java.net/).
You store some resources in a JAR library (such as images, css, javascript...) and you write a really simple weblet-config.xml. Then in the JSF page, you can refer them directly with this syntax:
<h:graphicImage src="weblet://some-name/images/someimage.jpg" .../>

A tag file is like a JSP fragment that can be placed in a jar. Using tag files, could help you, but I have never tried to use images, CSS, etc. in a jar.

In Core JavaServer Faces, 3rd edition, under "Packaging Composite Components in JARs" on p. 382, it talks about packaging composite components in JAR files.
"All you have to do is put your composite component, and its artifacts, such as JavaScript, stylesheets, or properties files, under a META-INF directory in the JAR, as shown in Figure 9-14."
components.jar
+-- META-INF
+-- resources
+-- css
| +-- styles.css
+-- images
| +-- back.png
+-- util
+-- icon.xhtml
+-- login.js
+-- login.properties
I'm not sure how easily these resources can be accessed directly from other applications as opposed to the contained composite components.

Related

Which Folder do i put my frontend files in Spring boot. Is it Src/main/resource or Src/main

Im confused on where to put all my Front-end files like HTML and CSS as Well JS and it frontend framekwork stuff like react. Do i put it in the resource folder or the scr/main and create a folder call "webApp" and host all my HTML files there?
Does it matter which I use?
You can put it in the src/main/resource folder by default. Also you can follow those approachs:
Generate a project with JHipster and see the content.
Do a research on github with the key word "fullstack spring boot", you will find many examples and differents types of project organization
Use Docker Compose to deploy your Front End (on NodeJS) and your Back End (as a Spring Boot application) in differents images
src/main/resource or some organised order structure module wie inside src/main/resource is good practice and easy to find by IDEs and WARs unpacking / loading paths.

Acessing resource of a maven dependency in a wicket application

I have two maven projects.
components: Contains wicket components. All of these wicket components rely on a single stylesheet called component.css. The stylesheet is generated by the libsass-maven-plugin and output to the projet.build.directory. (Directly into the target folder) This project is packaged as a jar.
web-app: This is the project for the (wicket) web application packaged as a war.
My problem is, that I just can't find a way to include the componet.css as a external resource in my web-app project.
I tried to include it into the webapp folder using the maven-war-plugin and loading it as a <link> inside the html, but that didn't work, because components isn't a war project.
Then I tried to use new CssResourceReference(SomeClass.class, "/component.css") to let wicket generate the <link> element, but I get an error that the access to (static) package resource is denied.
My last possible solution was to create a class inside components and generate the component.css relative to that class. But somehow even this isn't working.
Then I tried to use new CssResourceReference(SomeClass.class, "/component.css") to let wicket generate the element, but I get an error that the access to (static) package resource is denied.
This should work. Wicket's default settings allow .css static files to be served [1]. Do you use a custom IPackageResourceGuard that disables .css ?
https://github.com/apache/wicket/blob/master/wicket-core/src/main/java/org/apache/wicket/markup/html/PackageResourceGuard.java

Building a properties file to the top level of a WAR file, Spring-MVC/Maven

I need to include a file into my war. Currently, in non Web applications the file in question is added to the top level directory, the class that uses it searches for this file at this level.
I need to use Maven, or somehow in the web app to include this file at the top level of the war file. My current directory structure is as follows:
Project
|--Src/Main/Java
|--Package
|--X.class
|--WebContent
|-- META-INF
|-- resources
|-- WEB-INF
|--POM.XML
|--FileToInclude.Properties
The diagram above shows the X.class in my spring application, it uses the FileToInclude.properties file, and it must be at the top level. Any ideas?
This structure would work on a normal project, just not when its a web application and the certain files get built.
thanks
You can include that file in any directory that is part of the classpath.
If you need to include it inside the war you need to add in the WEB-INF/classes directory.
If you like to add it externally you can add it to any directory that is part of the classpath when your war is loaded by the application server. Generally is possible to specify to the application server which directories use as part of the classpath

Sharing customTags.tld between projects

I have created two projects 'webutils' and 'website'
In website I have created custom tag library and customTags.tld file for tag reference.
In my jsp's i am using this
<%# taglib uri="/WEB-INF/tags/customTags.tld" prefix="tt"%>
It works fine. and i am able to use
<tt:mytag/>
NOW problem is i want to move my tag library into webutils project. Moving only java package with java-files works, but i want to move customTags.tld file to webutils too. When i do that it does not work. I cannot refer .tld files.
let me know if more clarification on problem is required, as I am assuming lots of things.
I am using gradle & spring-boot.
Forgot to mention few things, 'website' depends on 'webutils'. And I am using gradle.
If you want to redistribute your tag files or implement your custom
tags with tag handlers written in Java, you must declare the tags in a
tag library descriptor (TLD). A tag library descriptor is an XML
document that contains information about a library as a whole and
about each tag contained in the library. TLDs are used by a web
container to validate the tags and by JSP page development tools.
Tag library descriptor file names must have the extension .tld and
must be packaged in the /WEB-INF/ directory or subdirectory of the WAR
file or in the /META-INF/ directory or subdirectory of a tag library
packaged in a JAR. If a tag is implemented as a tag file and is
packaged in /WEB-INF/tags/ or a subdirectory, a TLD will be generated
automatically by the web container, though you can provide one if you
wish.
http://docs.oracle.com/javaee/1.4/tutorial/doc/JSPTags6.html
So, if using Maven, for example, place the .tld under
src/main/resources/META-INF

Where to store static files like html/css/javascript in a jetty project?

I have a maven project that I run using jetty:
$ mvn run:jetty
Where in my project should I be storing my static files like HTML, CSS, Javascript, images?
My layout is using a simple web app arch type:
/src/main/java/webapp/web-inf/views/
Should I just create a folder there named e.g. 'assets' ?
And then my view pages will reference the /assets folder somehow? I'm confused as to what path I will use in my html pages to reference an image like:
/assets/images/logo.png
This isn't so much a Jetty question as it is a general Java webapp question. If you plan to serve them out directly (like *.css, *.css, images, etc), put them somewhere above WEB-INF but below your docroot. Java WebApps are all the following basic directory structure.
<docroot>
+WEB-INF/
+lib/
+classes/
Anything in <docroot> is reachable directly through straight up http. Anything WEB-INF and below is not. A really simple webapp with one page (index.jsp), one image in an images directory, and its configuration file (web.xml) would look like this.
index.jsp
images/bob.jpg
WEB-INF/
web.xml
lib/
classes/
In index.jsp you could reference bob.jpg like...
<img src="images/bob.jpg"/>
This is really a Maven question rather than a Jetty question.
Typically you would put your images (etc) in the maven webapp directory - i.e. source/main/webapp/ (not under web-inf)
How you structure things underneath that is up to you, but it will mostly depend on how much content you are expecting to put in, and how you think it is best to organise it.
source/main/webapp/assets/images is fine, but so is source/main/webapp/images or source/main/webapp/static/.
Then, within your HTML, you reference the images using whatever path you put in beneath the webapp bit.
The general answer is - the root of your web application is webapp. Dynamic resources (as JSP pages or Freemarker templates) would better off be in a web-inf/ subfolder (they are accessible through classloader but not from a direct browser request).

Categories