Maven Dependency & Spring - Overwrite application context from dependency war - spring

I manage to add dependency ProjectWeb project into SchedulerWeb project. Successful run the web that has been develop in ProjectWeb project through SchedulerWeb package.
However, i cannot inject bean in SchedulerWeb project. When I start instance of SchedulerWeb, it not scan SchedulerWeb annotation.
ProjectWeb
- src/main/java.....
- src/main/resource
- applicationContext.xml
- <context:component-scan base-package="com.myprojectWEB.service" />
SchedulerWeb
- src/main/java.../scheduler
- mainScheduler.java
- src/main/resource
- applicationContext.xml
- <context:component-scan base-package="com.myprojectWEB.service" />
- <context:component-scan base-package="com.myprojectWEB.scheduler" />
in com.myprojectWEB.scheduler i create one class and the code is per below.
#Configuration
#EnableScheduling
public class Main {
#Scheduled(fixedDelay = 500)
public void executeEveryOneMin() {
System.out.println("Run Job " + new Date());
}
}
So how i want the SchedulerWeb will call their own applicationcontext.xml?
** i put the scheduler in projectWEB is working fine but not in SchedulerWeb.
Any advice?

Related

Context vs context - setting ignore-unresolvable="true" - PropertyPlaceholderConfigurer

Problem
I'm trying to set ignore-unresolvable="true".
I have found the answer https://stackoverflow.com/a/11773267/1688441 from the question how to define not mandatory property in spring? .
The example they show is:
<context:property-placeholder ignore-unresolvable="true" ... />
However, in the project I have inherited we have a project file called project.xml that contains Resource definitions with a Context tag.
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource />
<ResourceLink />
<Resource />
</Context>
Note: The resources have been removed
When I edit the Context tag to add ignore-resolvable everything breaks and not even my DataSource resource is read. Anyone have any ideas?
I tried the following:
<Context:property-placeholder ignore-unresolvable="true">
Possibly related:
spring PropertyPlaceholderConfigurer and context:property-placeholder
It turns out that in the specific project a class based configuration was being used instead of XML. I found the following class to which I added setIgnoreUnresolvablePlaceholders(false) in the method that returns PropertySourcesPlaceholderConfigurer:
#Configuration
#ComponentScan
#EnableWebMvc
#EnableAsync
#EnableScheduling
#PropertySource(value = {"classpath:appProp.properties"})
#Import({ExternalizeConfiguration.class, AppApplication.class,
AppPersistenceApplication.class, ConnectBoIntegrationApplication.class})
public class AppWebApplication extends WebMvcConfigurerAdapter {
...Other Code...
/**
* Bean required for Value annotation
*/
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer test = new PropertySourcesPlaceholderConfigurer();
test.setIgnoreUnresolvablePlaceholders(false);
return test;
}
}
So my understanding is that annotating this method as #Bean causes the method to execute whenever an object of type PropertySourcesPlaceholderConfigurer is auto-wired. In this way, we control which instance is used and what params are set on it.

Spring 3.1 Missing ServletContext

I am trying to write an integration test for my spring application. All my spring beans are defined in an xml file, so I am using profiles to parse them out.
Here is my test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = GenericXmlContextLoader.class, locations = {"classpath:/spring/spring-config.xml"})
#Profile("dev")
public class AccountDAOTest {
private EmbeddedDatabase database;
#Autowired
AccountDAO accountDAO;
#Before
public void setUp() {
System.setProperty("spring.profiles.active", "dev");
database = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).setName("memdb")
.addScript("classpath:resources/createAccount.sql").build();
Assert.assertNotNull(database);
}
#Test
public void testFind() throws Exception {
List<Account> accounts = accountDAO.findAll();
}
}
My spring-config.xml is just a standard configuration file
<beans>
<beans profile="prod" >
<context:annotation-config/>
<tx:annotation-driven transaction-manager="myTX" proxy-target-class="true"/>
<aop:aspectj-autoproxy/>
...
<beans profile="prod" >
<transaction managers, httprequests and such >
</beans>
<!-- end of production beans -->
<!-- the following are for local testing -->
<beans profile="dev" >
</beans>
<transaction managers and such >
<!-- end of local testing beans -->
</beans>
My spring version is 3.1.Release for spring-test, spring-transaction, spring.web.servlet, spring.web
As I am using servlet 2.5 I cannot use the newer Spring MVC configuration
When I try and run my test I get the following exception:
Caused by:
org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method [public org.springframework.web.servlet.HandlerMapping
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping()]
threw exception; nested exception is
java.lang.IllegalArgumentException: A ServletContext is required to
configure default servlet handling
Caused by: java.lang.IllegalArgumentException: A ServletContext is
required to configure default servlet handling
I can't figure out:
Why the servlet is required when I don't use it explicitly for tests
How to get the test servlet context loaded for xml without using spring mvc
Split the spring context config into root (non-web-related beans) and mvc (web-related beans) parts, or create a separate test config xml.

Autowiring the bean

I am new to spring and i have a question on autowiring the bean
So basically in my context file i have defined a bean called
<bean id="offerpricedao" class="com.impl.OfferPriceDAOImpl" >
<constructor-arg index="0" ref="offerpriceclass"></constructor-arg>
<constructor-arg index="1" ref="myrole"></constructor-arg>
<constructor-arg index="2"><null/></constructor-arg>
</bean>
And every other bean i have defined here which are referring ..
This code is in src main java..
and in src main test i have a testng test which loads this configuration file and in my test
i have some thing like this
#ContextConfiguration(locations = { "classpath:Context.xml" })
public class SetOfferPricesTest extends AbstractTestNGSpringContextTests {
#Autowired
IOfferPriceDAO test;
}
and this autowiring works fine ...
I thought we should have this in my configuration file for autowire work..
with out this how my autowiring is working..?
You might be having something like default-autowire="byName" in context xml. When you add #Autowired Spring finds the implementation of that interface and autowires it. In your case the implementation is com.impl.OfferPriceDAOImpl
Also the #ContextConfiguration annotation loads the context xml from the classpath
Above config and code is not enough to say how it works.
Since it Works,so the bean is defined some where in the Context.xml or in the xml files imported in context.xml.
And what dhanush said is also true.

Using #Repository-style exception translation from Spring Java configuration

If I want to declare a bean using Spring 3's Java-based configuration, I can do this:
#Configuration
public class MyConfiguration {
#Bean
public MyRepository myRepository() {
return new MyJpaRepository();
}
}
But, since I can't use the #Repository annotation in this context, how do get Spring to perform exception translation?
Declare your MyJpaRepository class as a repository:
#Repository
public class MyJpaRepository {
...
}
And make sure you have your annotations discoverable by setting up the component-scan element in your Spring configuration:
<context:component-scan base-package="org.example.repository"/>
Since you do not want your repository included in the annotation scan per your comments, filter it out either by excluding all #Repository annotations or your particular class(es) or package. There is an example of this in the documentation:
<context:component-scan base-package="org.example.repository">
<!-- use one or the other of these excludes, or both if you *really* want to -->
<context:exclude-filter type="regex" expression="*Repository"/>
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
The Spring 3.0 documentation describes this configuration in more detail in section 3.10.
By configuring your class as a Repository, it will be designated as one when you pull it out as a Bean in your Configuration class.

Spring #Scheduled is executing task twice when using annotations

I have made task using Spring #Scheduled annotation, but for some reason it is executing task twice. My Spring Framework version is 3.0.2.
#Service
public class ReportService {
#Scheduled(fixedDelay=1000 * 60 * 60* 24)
#Transactional
public void dailyReportTask()
{
... code here ...
}
}
Here is my 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:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<task:scheduler id="taskScheduler" />
<task:executor id="taskExecutor" pool-size="1" />
<task:annotation-driven executor="taskExecutor"
scheduler="taskScheduler" />
</beans>
it is happening because of context listener
Just remove
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
from web.xml it should work.
I had this same problem, and I eventually found out that the problem was occurring as a result of the beans being created in the root context as well as the servlet context.
So, to fix this, you need to separate the creation of the beans into the appropriate contexts.
This answer explains really well how to that and was what fixed my problem.
According to this post: http://www.vodori.com/blog/spring3scheduler.html
Spring 3.0.0 Release had a bug where
web apps with a task scheduler would
end up executing scheduled methods
twice. This has been resolved in
Spring 3.0.1.
There has been another bug reported which affects Version/s: 3.0.2
https://jira.springsource.org/browse/SPR-7216
Which should be fixed in Version/s: 3.0.3.
I just had this problem recently and it was caused by my app being deployed twice in Tomcat by eclipse. The problem was that I had renamed my application in eclipse but the "wb-module deploy-name" specified in the "org.eclipse.wst.common.component" .settings file still had the old name.
In the tomcat manager, I could see that I had 2 apps running with different names.
Where are you actually running it? Your PC? Single server? 2 x load-balanced app servers?
Could be it's running on (a) your PC and (b) your server, so it just looks like it's running twice, if you see what I mean: it's correctly running once, just on two distinct locations.
Check if you have any manual scheduler config in your configuration files (through Java/XML). I'ved the same problem, and I discover that my config was loading my scheduler class twice:
In Java:
package com.mywork.br.myschuedulerpackage;
{...}
#Configuration
#EnableScheduling
public class SchedulerConfiguration {
#Bean
public CTXDataImporterScheduler ctxDataImporterScheduler() {
return new CTXDataImporterScheduler();
}
}
In XML applicationContext.xml:
<context:component-scan base-package="com.mywork.br.myschuedulerpackage" />
And in my scheduler class, I had #Component annotation thats was catch by the component scan and loaded a second time causing the #scheduler methods being executed twice.
I removed the Java config and then is working well now!
To solve twice-working of #Scheduled method just delete ContextLoaderListener from you web.xml (if you use web.xml-based application):
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Or if you use WebApplicationInitializer-based application just delete a string that adds ContextLoaderListener:
package com.dropbox.shortener.config;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class DropboxShortenerWebApplicationInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
// (!) Delete the next string
// container.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(WebConfig.class);
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
setupCharEncodingFilter(container);
}
private void setupCharEncodingFilter(ServletContext container) {
container.setInitParameter("defaultHtmlEscape", "true");
FilterRegistration charEncodingFilterReg = container.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
charEncodingFilterReg.setInitParameter("encoding", "UTF-8");
charEncodingFilterReg.setInitParameter("forceEncoding", "true");
charEncodingFilterReg.addMappingForUrlPatterns(null, false, "/*");
}
}
Use #Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) on your bean
Disabling below will work.
<!-- <listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener> -->
One solution I would suggest is to do component scat like this
-In application context
<context:component-scan base-package="com.abc.cde.dao" />
In yourservlet-servlet.xml
<!-- package that had all the #Controller classes -->
I this way the servlet is only loaded if the web.xml is loaded
Similar can be done for task

Resources