Spring 3.1: Getting the <mvc:resources To Work - java

I'm new to Spring. I'm learning Spring 3.1. I'm using the book "Spring In Action, 3rd ed.. I'm having trouble getting static resources found. The book doesn't say much about it so I was wondering if I could get some help.
The name of my application is "abc"
The URL is something like "https://blah.blah.blah/abc
I'm running "abc" on WebLogic 9.2
I'm deploying "abc" as "abc.war"
The directory structure inside of my "abc.war" is
WEB-INF
classes
lib
web.xml
webLogic.xml
abc-servlet.xml
css
images
js
jsp
META-INF
In my web.xml I have my dispatcher servlet defined like this:
<servlet>
<servlet-name>abc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>abc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
.....and this is the content of my abc-servlet.xml file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="org.company.abc.controllers" />
<mvc:resources mapping = "/**" location = "/"/>
<mvc:annotation-driven/>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value = "/jsp/"/>
<property name = "suffix" value = ".jsp"/>
</bean>
</beans>
I've tried putting my static resources under a "resources" directory off of the root of my webapp, but that didn't make any difference ( I changed the tag to <mvc:resources mapping = "/resources/**" location = "/resources"/> when I did that ).
Basically, the abc webapp isn't finding any of the static resources.
It thinks the picture "header.png" is at
- htts://blah.blah.blah/images/header.png
So the image comes up blank, though when I paste this URL into a browser, I can get the image
- htts://blah.blah.blah/**abc**/images/header.png
I haven't found a way to get Spring to stick a "abc" into that url though.
I'm a brand new white belt with Spring, so baby talk in helping me figure this out with suggestions will not be taken as an insult :)
Thanks in advance for any help
Steve

I tried my stuff in Tomcat 6 and all worked well ( this is not the first time something was harder in WebLogic, FWIW ).
I Google around and found this
http://forum.springsource.org/showthread.php?102166-mvc-resources-and-war-on-Weblogic/page2
explaining that WebLogic and Spring 3.* have unresolved issues.
Being a newbie to Spring and WebLogic I didn't understand most of it.
I did notice that all of my static stuff would map to
https:/blah.blah.blah/abc/images/myimage.png
But Spring would think it was
https:/blah.blah.blah/images/myimage.png
So,
I set my mvc tag to <mvc:resources mapping = "/resources/**" location = "/resources"/>
Then in my new files that use spring I changed the paths to ../abc/images/myimage.png
It all works. The legacy files are still finding the static resources off of the root in the war with the paths in the legacy code AND the new Spring files ( I'm gradually converting abc from a Servlet webapp to a Spring webapp ) find them as ell.
Its a hack and its crude, but it gets me going for now

Related

Problem configuring Jolokia server and agent

I have a Spring Boot Java application that among other things uses Apache Camel to do a little route interception and data modification. We have a separate "camel routes" file (camelRoutes.xml) that defines the camel routes that will be used. There is also a bit of configuration in that file that, as best I understand, configures a Jolokia MBean server and Jolokia agent.
There is something about the Jolokia config XML that the system is not happy with. I've done some very quick Googling and it seems like it's specified properly (see section 9.3.2 in https://jolokia.org/reference/html/jmx.html). The problem manifest itself in various ways. When the file is open in the XML editor in eclipse, the corresponding XML is highlighted with an error (although it provides no information about what it thinks is wrong). More importantly, when I attempt to run the application, it fails with cascading exceptions, basically pointing to a problem in the config file.
Excerpts from camelRoutes.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jolokia="http://www.jolokia.org/jolokia-spring/schema/config"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.jolokia.org/jolokia-spring/schema/config http://www.jolokia.org/jolokia-spring/schema/config/jolokia-config.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
...
<context:mbean-export server="jolokiaServer" />
<jolokia:mbean-server id="jolokiaServer" />
<jolokia:agent lookupConfig="false"
systemPropertiesMode="never">
<jolokia:config autoStart="true" host="0.0.0.0"
port="${jolokia.port:8778}"
agentDescription="${jolokia.agentName:jolokia}" />
</jolokia:agent>
Errors are displayed in eclipse for the line where the jolokia:mbean-server and jolokia:agent are defined.
Small section of the exception trace when application is executed:
Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 85 in XML document from file [C:\Users\JO24447\workspace\RST_Service_Base\rust-service-base-rest\target\classes\rst_camel\camelRoutes.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 85; columnNumber: 45; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'jolokia:mbean-server'.
Any ideas what could be wrong?
In my case the cause was that I used the Maven assembly plugin which did not merge the spring.schemas files. I switched to the shader plugin and schema validation worked.

Load spring xml config dynamically

At the startup time of a spring app, I want to scan a path on the computer, find the jar files and build a spring application context from an xml config files inside them. Every thing is OK to add jar file to the classpath and making an ApplicationContext. But I can't find any beans from new context. All of needed dependencies are available in the jar files in the specific path on computer (via a maven copier plugin) expect those dependencies which are in the base spring project (for example spring dependency itself).
The code is (In Kotlin language):
var loader = URLClassLoader(arrayOf(entry.toFile().toURL()), Thread.currentThread().contextClassLoader)
...
val context = ClassPathXmlApplicationContext("classpath*:/$name")//name is xml file. I'm sure the address in classpath is right. context is not creating when the address in wrong. for example: classpath://$name
val services = context.getBeanNamesForType(IService::class.java)//services is empty
I have tried many other ways to load the xml but none of them was successful. for example:
val beans = DefaultListableBeanFactory(applicationContext)
val reader = XmlBeanDefinitionReader(beans)
reader.beanClassLoader = loader
reader.resourceLoader = resourceLoader
reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD)
jarFile.getInputStream(jarEntry).use {
reader.loadBeanDefinitions(EncodedResource(InputStreamResource(it)))
}
beans.preInstantiateSingletons()
the xml inside jar file looks like this:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="classpath*:/xxx-logic-context.xml"/>
<context:annotation-config/>
<context:component-scan base-package="aa.bbb.ccc.server"/>
</beans>
It's really interesting: When I define regular Beans instead using package scaning feature, I can get the bean in a sort of code
Great answer from #talex guided me. I fixed it by setting the current class loader:
val loader = URLClassLoader(arrayOf(entry.toFile().toURL()), Thread.currentThread().contextClassLoader)
Thread.currentThread().contextClassLoader = loader

Spring Batch Job Scope Unavailable

It seems like the Spring Batch 3.0.6 release points to the 2.2 schema by default.
In the spring.schemas file there is this definition
http\://www.springframework.org/schema/batch/spring-batch.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.2.xsd
And when I add this namespace to my spring file, I then get the scope="step" option (in my IDE, although IntelliJ has been pretty reliable matching runtime issues)
...
xmlns:batch="http://www.springframework.org/schema/batch"
...
But everything seems to claim that scope="job" is invalid.
Is it the spring.schemas file doing this? Why would the 3.xx iteration point back to the 2.2 schemas?
I can't seem to get a declaration like xmlns:batch="http://www.springframework.org/schema/batch/spring-batch-3.0.xsd" to work. Surprisingly that totally invalidates the batch namespace. Even though the spring.schemas file points to 3.xx like so
http\://www.springframework.org/schema/batch/spring-batch-3.0.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-3.0.xsd
If I do this:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
...
</beans>
I can then get the scope="step" to be valid, and everything seems to point to batch-3.0, but scope="job" is still invalid.
Does anyone have a clean example of importing batch & using a job scope declaration on a bean?
Thanks!

Wildfly looking in wrong directory

I recently startet working with JBoss' Wildfly 8.1 and the activiti framework.
I created two projects, one with my bpmn.xml file and the classes for the Service Tasks:
Process:
-src/main/
-impl.java
-src/resources/
-diagrams
-myprocess.bpmn.xml
-config
-activiti-context.xml
The other one holds the servlet
WebTest:
-src/main
-testServlet.java
-lib
-process.jar
in my servlet i implemented the init method to get the Activiti processEngine:
#Override
public void init() throws ServletException{
super.init();
engine = ProcessEngines.getDefaultProcessEngine();
}
I build the Webtest.war file and deploy it to
D:/path/to/workingdir/wildfly-8.1.0.Final/**standalone/deployments**/Webtest.war
Then i start up Widlfly using the provided standalone.bat, it starts up correctly and deploys to the context /Webtest, so far so good.
if i now access localhos:8080/Webtest/servlet i get the Exception:
org.activiti.engine.ActivitiException: couldn't initialize process engine from spring configuration resource vfs:/D:/path/to/workingdir/wildfly-8.1.0.Final/bin/content/TEST-1.war/WEB-INF/lib/process.jar/activiti-context.xml: null
the error with :null at the end implies that the file could not be accessed. of course it cannot, there is no bin/content!
my question now is: where does Widlfly get the idea to look at bin/content? it obviously was able to find the config file on itself, i never told spring or activiti to look in the process.jar, so the app finds the configuration in the classpath alright... then it proceeds to reading the file from an entirely different location that does not exist?
I dont know if this is of interesst, but here is my activiti-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"/>
</beans>
thanks for any help or hints!

spring-beans.xsd does not define "local". Why?

Almost every spring project uses spring-beans.xsd (refers to it to be more precise). However, if you look at the file, http://www.springframework.org/schema/beans/spring-beans.xsd, you'll see that it is version 3.2 and doesn't have a definition for the attribute "local".
What's even more interesting, is that http://www.springframework.org/schema/beans/spring-beans-3.2.xsd does actually define "local".
Also since the file is pulled out of the jar (org/springframework/beans/factory/xml/spring-beans-3.2.xsd) due to spring.schema, I don't think any project will have compile or runtime issues.
Eclipse's xml validator on the other hand, I think, uses only the internet link and shows an xml error, more specifically :
"cvc-complex-type.3.2.2: Attribute 'local' is not allowed to appear in element 'ref'"
Is this is a bug?
Edit:
As per request, this is my spring header:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">
Edit 2: here is where I'm using local
<bean id="bar"
class="org.springframework.batch.item.support.CompositeItemWriter">
<property name="delegates">
<list>
<ref local="foo" />
</list>
</property>
</bean>
<bean id="foo" class="java.lang.String" />
You should try to use <ref bean="someBean"/> instead.
As stated here: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/
The local attribute on the ref element is no longer supported in the 4.0 beans xsd since it does not provide value over a regular bean reference anymore. Simply change your existing ref local references to ref bean when upgrading to the 4.0 schema.
As you might know Spring 3.x is not fully compatible with java 8, so you either use unsupported and outdated Java 7 with Spring 3.x, or upgrade both Spring and JDK. I would strongly recommend the latest
The http://www.springframework.org/schema/beans/spring-beans.xsd actually points to the 4.0 XSD, which does NOT have local. Additionally, There are bugs in eclipse with spring integration that could be the issue. INT-1353
Additionally, there /was/ a configuration option for eclipse to specify loading XSDs from Classpath, but I'm not 100% sure this works or even exists anymore. There is a screenshot of that here: https://stackoverflow.com/a/2896051/1958771
~ sheenobu -> curl -s http://www.springframework.org/schema/beans/spring-beans.xsd | md5
0483a5565138fe9f79c5fbe38c7c5969
~ sheenobu -> curl -s http://www.springframework.org/schema/beans/spring-beans-3.2.xsd | md5
1562baeab9550e2149e9608dbb3bbadd
~ sheenobu -> curl -s http://www.springframework.org/schema/beans/spring-beans-4.0.xsd | md5
0483a5565138fe9f79c5fbe38c7c5969
Spring (and Eclipse) will use whichever xsd you declared in the schemaLocation regardless of the one in the jar file. This is actually validation done by the XML parser that Spring uses underneath it all.
If you want to use the local attribute of ref, you will need to declare a schemaLocation that points to a schema that has the local attribute. Note that if you do do this, the generated context will need to be parseable by the BeanDefinitionParser that exists in your Spring jar.
I have solved the problem with using older http://www.springframework.org/schema/beans/spring-beans-3.2.xsd in xsi:schemaLocation. (As my project is "older" as well)

Categories