Spring Resource servlet - resources in classpath (JAR) not found - java

we had to configure the resource servlet of Spring in our app. It is a multi-module Maven project and consists of a WAR-file containing several jars with the Java app itself and UI modules with static content.
The static content (js and css) inside the jars is located under "META-INF/resources" and as well packaged like that. So from this point of view this is correct.
We introduced following in our coding (XML-based config):
<mvc:resources mapping="/resources/**" location="classpath:/META-INF/resources/,/" cache-period="2419200">
<mvc:resource-chain resource-cache="true">
<mvc:resolvers>
<mvc:version-resolver>
<mvc:content-version-strategy patterns="/**"/>
</mvc:version-resolver>
</mvc:resolvers>
</mvc:resource-chain>
</mvc:resources>
It doesn´t work. The js and css files cannot be found in the classpath. I checked the local tomcat installation and the corresponding jars with the UI modules. These are located in WEB-INF/lib of the webapp´s directory.
If we copy the files into the webapp´s dir of tomcat they can be found and everything works correctly.
Any suggestions? Is this a possible bug in spring?
Thanks in advance!

Related

How to load spring beans for multiple jar file in a war based application

I have a war based spring web application project which internally has multiple jar files. I am using maven setup to build jars and war file. Each jar file has a set of beans that needs to be loaded and i am not able to do so.
In each of the jar file i have defined a beans.xml file . But the beans are not getting loaded automatically. I have tried loading the beans.xml file from:
a) src/main/resources
b) src/main/resources/META-INF
c) src/main/resources/META-INF/spring
It doesnt work.
My Question: How to prepare the application context for such scenarios? War based app with multiple jars.
If your are packaging your application as a webapp one, then you can simply add a file named yourservletname-servlet.xml and include all resources from your jar files using the <import /> element.
Spring, behind the scenes, will scan the file mentioned above by default including all beans declared in the files imported.
Here is how your servletname-servlet.xml should look like (xml namespace and schemas declaration are ommited for brevity sake):
<beans>
<import resource="classpath:/META-INF/beans.xml"/>
</beans>
I suggest the use of the META-INF as your context config files location.
This will scan all bean declaration files named beans.xml under META-INF folder under the root of your classpath, which assumes that those files must be under src/main/resources/META-INF/ in your project structure when using Maven as your build tool (so they can get copied directely under jar_root_path/META-INF/).
Otherwise, if you are not using the default -servlet.xml file, you can specify a custom application context descriptor using the contextConfigLocation as follows:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>application-context.xml</param-value>
</context-param>
Try simple
import resource="classpath*:/META-INF/beans.xml"/
Where each jar contains beans.xml file under META-INF folder.It will scan each jar and load beans.xml file and creates beans based on these XMLs files.
You mention beans.xml, is this a CDI project or a standard Spring project ?
Using maven, everything under src/main/resources gets packaged at the top level of your JAR. So if you had a file in src/main/resources/META-INF/beans.xml, then you should load it using "/META-INF/beans.xml" or define it in your spring context as "classpath:/META-INF/beans.xml".

GWT: Loading an Applet inside an application

I am trying to integrate an existing applet packaged as jar file in an existing GWT application built with maven.
Now I am not being able to figure out, why the applet class is not being found. A ClassNotFoundException is being thrown when I try to load the applet, saying that the applet class cannot be found.
The GWT Maven project has several modules and the applet I want to integrate is in its own Maven module.
The applet jar file is being signed and packaged as in the final war file for the GWT app by the maven build process.
When I deploy the war file in a Tomcat server I have the following structure under the webapps folder:
webapps
my_gwt_app
WEB-INF
classes
deploy
lib
signed_applet.jar
other_application_dependency.jar
views
web.xml
Here is the HTML result which is being generated by my GWT presenter:
<applet code="com.example.MyApplet.class" archive="/my_gwt_app/WEB-INF/lib/signed_applet.jar" width="1000" height="800" id="my-applet">
<param name="permissions" value="all-permissions">
</applet>
Could someone tell me what I am doing wrong?
Thanks!
Nothing in the lib or classes directory is available to be served to clients that visit the site. It will be necessary to move the Jar to another place on the server.
In addition to that:
The following path is simply wrong.
archive="/my_gwt_app/WEB-INF/lib/signed_applet.jar"
WEB-INF would typically be the 'root' of the site.
<param name="permissions" value="all-permissions">
Whatever you are trying to achieve there, it will not add permissions to the applet.
I added the "applet" folder under the root folder (http://dev-server.com:8080/my_gwt_app/ not under WEB-INF) and called the URL "http://dev-server.com:8080/my_gwt_app/applet/signed_applet.jar" in the browser. The jar could be found.
But when I configure my applet like
<applet id="my-applet" width="1000" height="800"
code="com.example.MyApplet.class"" archive="../applet/signed_applet.jar">
</applet>
I still getting the ClassNotFoundException.
My problem was the jar file path configuration.
I put it in the my_gwt_app/gwt_module/applet directory and configured the applet with this jar path.
Now it works fine.

Trying to get mvc resources to serve my static resources

I'm developing locally using both jetty and tomcat.
My images, css, javascript files are in:
/src/main/webapp/assets
where the folder assets has:
/src/main/webapp//assets/images
/src/main/webapp//assets/css
/src/main/webapp//assets/images/
My spring config file has:
<mvc:resources mapping="/assets/**" location="/" />
I'm confused as to what both mapping and location mean?
I think mapping means that that spring will only try and serve the static files if it has the url with the pattern like:
www.example.com/assets/
What does location do?
My html currently has:
src="/assets/images/logo.gif"
I've tried playing with the location value, and I don't get to render the image for some reason.
Can someone clear this up for me?
If your project structure has /src/main/webapp/assets/images, then you want to use:
<mvc:resources mapping="/assets/**" location="/assets/" />
and then in your JSP reference files as
src="${pageContext.request.contextPath}/assets/images/logo.gif"
Its more common to have a project structure like /src/main/webapp/images|css|js and then use:
<mvc:resources mapping="/assets/**" location="/" />
but still keeping URLs as ${pageContext.request.contextPath}/assets/images/logo.gif

Where does ESAPI.properties go in a Java Google AppEngine project

My project is working on the development server. It works in both the following cases:
With the .esapi directory in the source path, so that it ends up in WEB-INF/classes
With the .esapi directory in the lib root, so that it ends up in WEB-INF/lib
However, it doesn't work when deployed to Google (using either of the above 2 strategies).
I get usual messages about not being able to find the ESAPI. properties file when I first try to use ESAPI once deployed to Google.
Attempting to load ESAPI.properties via file I/O.
Attempting to load ESAPI.properties as resource file via file I/O.
Not found in 'org.owasp.esapi.resources' directory or file not readable: /base/data/home/ap
Not found in SystemResource Directory/resourceDirectory: .esapi/ESAPI.properties
Loading ESAPI.properties via file I/O failed. Exception was: java.io.FileNotFoundException
Attempting to load ESAPI.properties via the classpath.
ESAPI.properties could not be loaded by any means. Fail. Exception was: java.security.Acces
ESAPI does appear to include changes to support AppEngine http://goo.gl/rD8dz
Update
The issue is that line 603 of org.owasp.esapi.reference.DefaultSecurityConfiguration calls ClassLoader.getSystemClassLoader() which is illegal in Google Appengine. This causes the exception above (sorry it's cropped).
There are three ClassLoaders loaded into an array upfront, before the code tries to get the resources.
ClassLoader[] loaders = new ClassLoader[] {
Thread.currentThread().getContextClassLoader(),
ClassLoader.getSystemClassLoader(),
getClass().getClassLoader()
};
String[] classLoaderNames = {
"current thread context class loader",
"system class loader",
"class loader for DefaultSecurityConfiguration class"
};
I've hacked in my own copy of DefaultSecurityConfiguration where I've removed the SystemClassLoader (and corresponding classLoaderName) from the loadConfigurationFromClasspath method.
ClassLoader[] loaders = new ClassLoader[] {
Thread.currentThread().getContextClassLoader(),
getClass().getClassLoader()
};
String[] classLoaderNames = {
"current thread context class loader",
"class loader for DefaultSecurityConfiguration class"
};
Ironically it's because they've made the code easy to read/extent (IMHO) by looping through Classloaders that this approach fails. I'm tempted to submit a patch with an inner class to delay the call to getSystemClassLoader (which you can't do on AppEngine).
It's interesting that this works as it's only possible because the esapi jar is not sealed.
I'd have thought a security library jar should be sealed. Maybe I'm using the wrong one!
Update
I'm using the esapi jar via maven, this has been repackaged and isn't signed. Not ideal, but it's no less secure than the other 40 open source jars I'm getting from maven!
Your solution of overriding the DefaultSecurityConfiguration class with your own implementation is precisely the correct way to address the problem. This is precisely the reason that it is designed this way. There are some other inherent problems with using ESAPI on Google App-Engine tho, primarily with regards to encryption/hashing. This issue has been "partially" resolved according to comments on this thread (http://code.google.com/p/googleappengine/issues/detail?id=1612) but there are still serious limitation on using encryption in GAE.
I just successfully integrated ESAPI 2.1.0 on a Google App Engine Project and I did not even use Maven for it.
Put the ESAPI.properties & validation.properties in the directory [gae-project]/war/ESAPI/.
Thus, the full path of the ESAPI.properties will be
[gae-project]/war/ESAPI/ESAPI.properties
Putting it under the war/ ensures that the files will be uploaded to Google.
Edit your appengine-web.xml, add the following lines inside the <appengine-web-app> root node
...
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />
<property name="org.owasp.esapi.resources" value="ESAPI" />
</system-properties>
<static-files>
<exclude path="/ESAPI**properties" />
</static-files>
...
that will allow App Engine to recognize .properties files as project files.
for a more detailed discussion you can also read ESAPI for Google App Engine Integration Tutorial
You can put the files in META-INF/ directory and then change the org.owasp.esapi.resources system property to META-INF/ in appengine-web.xml as follows:
<system-properties>
<property name="org.owasp.esapi.resources" value="META-INF/" />
</system-properties>
Because DefaultSecurityConfiguration seeks configuration files first in the Resource Directory then in the classpath.
The following steps worked for me.
Extract the jar
create one folder .esapi
download ESAPI.properties
create the jar.
Use it,it won't complain about missing properties file anymore.
In our project the file resides in the WEB-INF/classes folder. We do not use a .esapi sub-folder.
Esapi version=2.0.1
Deployed in jboss though.

Spring WebContent Resources - Access outside ServletContext

I have a Spring Web MVC application that I'd like to serve a large, partially generated file.
I've added that file to my WebContent directory and all works fine there. However, I'd also like to access that file from my various build/deploy scripts, which read and parse the file.
My current approach is to keep a copy of the file under the src directory as well as the WebContent directory. When serving the file from the web, it uses WebContent.
When serving the file for the build scripts, it uses the following spring config:
<bean id="ringCodeData" class="com.myapp.data.RingCodeData">
<property name="rulesInputFile" value="classpath:resources/rules_copy.xml" />
<!-- <property name="rulesInputFile" value="classpath:../WebContent/rules.xml" /> -->
<!-- <property name="rulesInputFile" value="file:/WebContent/rules.xml" /> -->
</bean>
As you can see, I've tried several different approaches to get the two to refer to the same file (without resorting to copies).
File paths don't seem to work since they're based on the current directory, that changes based on whether I call a given utility class from Eclipse or from the build scripts.
How can I get these to refer to the same file?
The only other thought I have at the moment is to try to setup Spring MVC to stream the file from the classpath directory.
Your best bet is likely placing it in /WEB-INF/classes (or, if you're using an IDE, just the project's src/source folder) and use <jsp:include> to include it.
<jsp:include page="/WEB-INF/classes/resources/rules_copy.xml" />

Categories