spring dependencies in my project hierarchy - java

The whole day I am working on that problem.
I have a workspace with this structur:
cmn-lib (common basic algorithms) # Java
cmn-server (common server based logic) # Java
cmn-dao (database interface) # Java
qz-tomcat (tomcat project) # Java
qz-client (client) # Android
cmn-server as well as cmn-dao using Spring(The tests runs without problems).
the spring configuration of cmn-server-spring.xml includes the common-dao-spring.xml(Becouse some Handler classes needs Dao support).
This is the cmn-server-spring.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" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<import resource="cmn-dao-spring.xml" />
<bean id="scoreHandler" class="de.bc.qz.handler.score.ScoreHandler"
autowire="byName">
</bean>
</beans>
now I want to include all those librarys into qz-tomcat.
The problem is that exception:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from relative location [cmn-dao-spring.xml]
Offending resource: URL [jar:file:/C:/Users/BC/qz/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/quiz-tomcat/WEB-INF/lib/cmn-server.jar!/cmn-serv-spring.xml]; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from URL [jar:file:/C:/Users/BC/qz/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/quiz-tomcat/WEB-INF/lib/cmn-server.jar!/cmn-dao-spring.xml]; nested exception is java.io.FileNotFoundException: JAR entry cmn-dao-spring.xml not found in C:\Users\BC\qz\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\quiz-tomcat\WEB-INF\lib\cmn-server.jar
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:76)
It occurs when I start my local tomcat.
cmn-server and cmn-dao are included as JAR with help of "Web Deployment Assembly".
However... My webapp brokes during SpringBeanAutowiringSupport:
#WebServlet("/ScoreServlet")
public class ScoreServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Autowired
ScoreHandler mScoreHandler;
#Autowired
TransferAdapter mTransferAdapter;
ScoreCreator mScoreCreator;
public void init(ServletConfig config) throws ServletException {
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
config.getServletContext());
}
Is something wrong in my cmn-server.jar?
I think the main problem is that line in the exception:
IOException parsing XML document from URL [jar:file:/C:/Users/BC/qz/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/quiz-tomcat/WEB-INF/lib/cmn-server.jar!/cmn-dao-spring.xml
There is no common-dao-spring.xml in my cmn-server.jar. I have added the project cmn-dao to cmn-server via Java Build Path->Project->Add->cmn-dao
That configuration seems to be fine for JUnit tests but not for the deployed Jar-File.
Knows anybody how to fix that problem.
Thanks for each help.

You should keep your Spring configuration files in the jars they belong to, and it's not a bad idea to use the standard META-INF/spring location. What you want to do is tell Spring to look for the configuration file on the classpath:
<import resource="classpath:[/META-INF/spring]/cmn-dao.xml" />
Also, note that you apparently have a mismatch in your naming, which may be the only problem actually breaking your runtime: You constantly switch back and forth between cmn and common and having or not having spring at the end. Pick one convention and use it.

Related

How do I resolve “Element bean is not allowed here” when configuring the XML file?

I was creating a simple Java project by importing 4 major jar packages of Spring(beans, core, context and expression, all are ver 5.2.6). However, IDEA kept indicating that "element bean is not allowed here" even though I checked repeatedly that the dependencies are placed correctly in the module section and restarted the IDE. The configuration is as follows:
<?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.xsd">
<!--Creating User Object-->
<bean id = "user" class = "com.zhouss.User"><bean/> #bean is where it reports error
</beans>
And here's a snapshot of the dependency jars:
I'm a complete newbie on Spring, how do I resolve the issue?
As it turned out, it was a problem with the particular version of IDEA (2020.3, mac), I have updated to the latest version of 2022.1, mac and the error simply disappears by themselves.
I found very little info online when I tried to resolve this problem, so I find it necessary to write down my findings.

"Cannot initialize context because there is already a root app..." when a Jetty auto-restart occurs after a change in the code Spring Vaadin?

I am experiencing the following issue on a Spring application with Vaadin when I run it with Jetty:
I have Jetty configured in a way that it scans the project working directory and if it sees changes made in the code, it restarts the server automatically (like Tomcat does too).
What I noticed is that if I make even a small change in the code and then Jetty fires automatically a restart, the following exception is thrown:
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
I know that this exception is thrown when there is more than one ContextLoaderListener as both ContextLoaderListeners try to load the same root ApplicationContext (therefore causing the exception), as explained here, also:
Why this Spring application with java-based configuration don't work properly
The point is that I do not have another ContextLoaderListener registered (or at least, I think so, as I cannot be sure cause I am using Spring together with Vaadin via the Vaadin Spring addon -> https://vaadin.com/directory#addon/vaadin-spring as a Maven dependency, and the addon is not yet officially STABLE).
One thing I am sure of is that the only listener I have in my code is the following:
package com.app.config;
import javax.servlet.annotation.WebListener;
import org.springframework.web.context.ContextLoaderListener;
#WebListener
public class AppContextLoaderListener extends ContextLoaderListener {
}
So I thought "Maybe there's a problem with the addon?". But then I tried to reproduce the issue using Tomcat instead of Jetty (started Tomcat, ran the application on Tomcat with Run on Server, modified some arbitrary code, waited that Tomcat republished the changes automatically) but the exception is never thrown with Tomcat.
So it might be Jetty related? Does anyone experienced something similar too?
Where is the issue?
This is the applicationContext.xml file I use (I post it for completeness):
<?xml version="1.0" encoding="UTF-8"?>
<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/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<bean class="com.app.config.AppConfig" />
<context:component-scan base-package="com.app" />
</beans>
EDIT: here is the full stacktrace of the exception:
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:277)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:764)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:406)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:756)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:242)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1221)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:699)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:454)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at runjettyrun.scanner.RJRFileChangeListener.filesChanged(RJRFileChangeListener.java:155)
at org.eclipse.jetty.util.Scanner.reportBulkChanges(Scanner.java:680)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:546)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:398)
at org.eclipse.jetty.util.Scanner$1.run(Scanner.java:348)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
You are using run-jetty-run, that doesn't do reload/restart the same way as you are expecting.
Note: run-jetty-run is not a jetty tool or project, its a 3rd party tool with no committers in common with core jetty.
Either use the jetty-distribution, or jetty-maven-plugin, or jetty-runner and you'll have better luck, mostly because the context reload is done properly, through the DeploymentManager (which run-jetty-run doesn't use).

Spring At least one base package must be specified exception

When I'm compiling my project it gives this error and stop compiling
org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from ServletContext resource
[/WEB-INF/application-context.xml]; nested exception is
java.lang.IllegalArgumentException: At least one base package must be
specified
Why this exception happen and How I solve it.
As per Spring Doc
Spring provides the capability of automatically detecting 'stereotyped' classes and registering corresponding BeanDefinitions with the ApplicationContext. To autodetect these classes and register the corresponding beans requires the inclusion of the following element in XML where 'basePackage' would be a common parent package for the two classes (or alternatively a comma-separated list could be specified that included the parent package of each class).
Hence your application-context should look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<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/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.example"/>
</beans>
to enable your package to get scanned via component-scan you should annotate your java class with respective annotation as per the requirement. Like #Controllers or #Service etc.
See the full details here.
<context:component-scan base-package="Your package">
</context:component-scan>
try adding this in you configuration file
From my comments above
The reason could be you have annotation driven context configuration enabled (<context:annotation-config></context:annotation-config>) in you application context, but you have to provided any base package to scan for spring beans.
Add the root package of your application as the base package to scan for bean definitions
<context:component-scan base-package="<your-app-base-package>"/>

Can't find applicationContext.xml from jar in classpath

I have Maven project with Spring. I have backend project as jar in the classpath(added as maven dependency). The backend project is with Spring again and has it's own applicationContext.xml. In the frontend project I have applicationContext.xml and I want to access the application context from tha backend like this:
<import resource="classpath:applicationContext.xml" />
but i got:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from URL location [classpath:applicationContext.xml]
Offending resource: ServletContext resource [/WEB-INF/appContext.xml]; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
Also tried:
<import resource="classpath*:applicationContext.xml" />
and
<import resource="classpath:/applicationContext.xml" />
If I understand correctly, you want the front end to access the applicationContext.xml of the back end project. Then classpath* is the right statement, and you should make sure namespaces of both configuration files are the same.
For example, this case won't work
Front end:
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
Back end:
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

Autowiring a Spring 3.1 standalone application returning "No unique bean of type [x.x.x.x] is defined" exception

I am writing a standalone application (not web based) which will be run from the command prompt using the command:
java -jar myapplication.jar
I developed the application on eclipse as a Maven project so Eclipse retrieves all the dependant libraries. If i right click the main class and select "Run As ">"Java Application" it works fine.
Now the problem I have is I need to deploy the application as a single jar file. To do this, I used Eclipse to export the application as a "Runnable Jar" (i.e via the "export command"). This generated the jar file. I looked into the jar file and all the classes and the dependent jar files are in the jar file.
The Spring application context file is also in the jar file in the top level folder. The "inside" of the jar file looks like this:
- com
- myapp
- service
- MyAppService.class
- dao
- MyAppDataDao.class
- MyMainClass.class
- META-INF
- org
- application-context-components.xml
- log4j.properties
- [several jar files for spring, log4j, velocity etc)
I tried running the jar file using the following command and it gave me this error:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.myapp.MyMainClass] is defined: expected single bean but found 0:
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:257)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1012)
at com.myapp.MyMainClass.init(MyMainClass.java:44)
at com.myapp.MyMainClass.main(MyMainClass.java:65)
... 5 more
The file com.myapp.MyMainClass is in the jar file with the correct name. The classes in the package are autowired. I think that i must have missed something in the annotations or maybe something in the application context file. The structure of the classes and the annotations used is shown below:
MyMainClass
#Component
public class MyMainClass{
#Autowired
MyAppService myAppService;
public static void main(String args[]){
try{
context = new ClassPathXmlApplicationContext(properties.get("app.context"));
MyMainClass mymainClass = context.getBean(MyMainClass.class);
mymainClass.myAppService.getData()....
....
}catch(Exception e){
throw new CWAException(fname + ":" + e);
}
}
}
The app.context property returns the name of the application context file.
MyAppService
#Service
public class MyAppService{
#Autowired
MyAppDataDao myAppDataDao;
---
---
---
}
MyAppDataDao
#Repository("myAppDataDao;")
public class MyAppDataDao {
getData(){
}
---
---
---
}
The application context 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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="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">
<!-- Auto scan the components -->
<context:component-scan base-package="com.myapp" />
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"
p:resourceLoaderPath="file://C:\template"
p:preferFileSystemAccess="true"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:#x.x.x.x:x</value></property>
<property name="username"><value>xxx</value></property>
<property name="password"><value>xxx</value></property>
</bean>
</beans>
Looking at the error I would guess that the Autowiring is not kicking in but I cant figure out where in the configuration I got it wrong. The application is in the packaged jar file and I am loading the file using ClassPathXmlApplicationContext so it should find it. I also don't understand why it works on eclipse but not after it has been exported.
Any ideas?
The class PathMatchingResourcePatternResolver in Spring3.0 atleast does not search for the classes marked with autowiring annotation inside jars.
Add the directory in which the jar is present to the classpath.
It will detect the classes and load as beans.

Categories

Resources