how to resolve my BeansException in spring - spring

i am new to spring technology.I am trying to create simple spring standalone application using j2ee container.
for that i added 4 jar files.
1)commons-loggins-1.3 jar
2)spring_bean_3.0.5
3)spring_core_3.0.0
4)Spring_context_3.0.2
i am tring to create application context instance in my client class.i am getting following error.
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The type org.springframework.beans.BeansException cannot be resolved. It is indirectly referenced from required .class files
The constructor ClassPathXmlApplicationContext(String) refers to the missing type BeansException
at test.Core_J2ee_Client.main(Core_J2ee_Client.java:12)
This is my code.
this is my client class.
package test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import beans.Test;
public class Core_J2ee_Client {
public static void main(String[] args) {
ConfigurableApplicationContext ap = new ClassPathXmlApplicationContext("resource/spring.xml");
}
}
This is my pojo class.
package beans;
public class Test {
public Test(){
System.out.println("this is test cons---");
}
public void hello(){
System.out.println("this is hello method");
}
}
This is my spring.xml file.
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="t" class="beans.Test">
</bean>
</beans>

Related

Intellij Spring: NoSuchBeanDefinitionException: No bean named 'accountDAO' available

This is driving me nuts. I have the following files, it is a very simple setup.
public class MainApp {
public static void main(String[] args) {
//read the spring config java class
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("Config.class");
//System.out.println("Bean names: " + Arrays.toString(context.getBeanNamesForType(AccountDAO.class)));
//get the bean from spring container
AccountDAO accountDAO = context.getBean("accountDAO", AccountDAO.class);
//call the business method
accountDAO.addAccount();
//close the spring context
context.close();
}
}
Config.java:
#Configuration
#ComponentScan("com.aop")
#EnableAspectJAutoProxy
public class Config {
}
LoggingAspectDemo.java:
#Aspect
#Component
public class LoggingAspectDemo {
//this is where we add all our related advices for the logging
//let's start with an #Before advice
#Before("execution(public void addAccount())")
public void beforeAddAccountAdvice() {
System.out.println("\n=======>>>> Executing #Before advice on method addAccount() <<<<========");
}
}
AccountDAO.java
#Component
public class AccountDAO {
public void addAccount() {
System.out.println(getClass() + ": Doing my Db work: Adding an account");
}
}
Everytime I run the MainApp.java, I get:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'accountDAO' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
All the files are under "com.aop" package so #ComponentScan should be scanning all the components. It looks simple enough but I can't get my hands around the problem, can anyone help me where I am going wrong?
You're invoking the constructor of AnnotationConfigApplicationContext with "Config.class" as String argument, but this constructor is actually for invoking with base packages i.e. the argument must be a package name.
Since you want to use it with the Configuration class, use the constructor which accepts Class instance instead i.e.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

Autowire working in unit test but not in main java class

I've a domain class that I want to auto-populate from external config. Here is my domain class:
#Data
#Configuration
#PropertySource("classpath:application.properties")
public class StudioVo {
#Value("${studio.code}")
private code;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Here is my context xml:
<bean class="org.springframework.batch.core.scope.StepScope" />
<bean id="ItemReader" class="com.sdm.studio.reader.StudioReader" scope="step">
<property name="studioVo" ref="StudioVo" />
</bean>
<bean id="StudioConfigVo" class="com.sdm.studio.domain.StudioVo" />
</bean>
Here is the class where I want to use the vo:
#Slf4j
#Data
public class StudioReader implements ItemReader<List<Studio>> {
private StudioVo studioVo;
public List<Studio> read() throws Exception {
System.out.println("getCode: " + studioVo.getCode()); //code is null here
return null;
}
}
However when I run it via unit test by autowiring, it runs fine. Like this:
#RunWith(SpringRunner.class)
#SpringBootTest
public class StudioTest {
#Autowired
private StudioVo studioVo;
#Test
public void testAutoPopulationOfStudio(){
System.out.println("getCode: "+ studioVo.getCode()); // works!
// Assert.assertTrue(studioVo.getCode().equals("102"));
}
}
Not sure what's going on here - I'm working with an old Spring Batch application wrapped in Spring Boot (so there is a mix of XML based and Java based config - and may be that is the cause of this issue). What am I missing?
In your StudioTest, you are autowiring StudioReader where as you missed the #Autowired in your StudioReader code, so add it as shown below:
#Slf4j
#Data
public class StudioReader implements ItemReader<List<Studio>> {
#Autowired //add this so that studioVo can be injected
private StudioVo studioVo;
//add other code
}
Please be certain to note that using #Autowire requires a chain of Spring-managed beans below it from wherever you are using it including the class in which you are using #Autowire. That is because Spring needs the precedent references to match up the object-reference hierarchy. I.e., in business logic layer ClassA, you want to #Autowire a field. ClassA itself needs to be a managed bean. Further, if the field you want to #Autowire holds an object that has referential dependencies to other objects (and most do), these also must be Spring-managed.
For example, the following will work:
package com.example.demo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MessageRunner {
private static SetterMessage setterMessage;
public static void main(String[] args) {
setterMessage = (SetterMessage) (new AnnotationConfigApplicationContext(DemoConfiguration.class)).getBean("setterMessage");
setterMessage.setMessage("Finally it works.");
p(setterMessage.getMessage());
}
private static void p(String s) {
System.out.println(s);
}
}
DemoConfiguration.java looks like this:
package com.example.demo;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan(basePackages = "com.example.demo")
public class DemoConfiguration {
}
SetterMessage.java, this:
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
#Service
#Scope("prototype")
public class SetterMessage {
private String message = null;
#Autowired
private SetterMessage2 setterMessage2;
public String getMessage(){
return message+setterMessage2.getSubMessage();
}
public void setMessage(String message) {
this.message = message;
setterMessage2.setSubMessage("("+message+")");
}
}
SetterMessage2.java:
package com.example.demo;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
#Service
#Scope("prototype")
public class SetterMessage2 {
private String subMsg = "";
public void setSubMessage(String msg) {
subMsg = msg;
}
public String getSubMessage() {
return subMsg;
}
}
Note that SetterMessage2.java is annotated as a Component (#Service) but no field in it is autowired. That is because it's the end of the object reference chain. But because it is a Component, it can be autowired into SetterMessage.java. However look at MessageRunner.java's main() method and field declarations. Note that the class field SetterMessage is NOT autowired. If it were annotated as #Autowired, main() would fail at runtime, throwing an NPE with the reference to setterMessage in main(). This is because MessageRunner.java is not marked as some kind of component. So we need to grab a valid instance of MessageSetter from the application context and use it.
To emphasize, the following version of MessageRunner.java's main() method WILL FAIL, throwing an NPE, if MessageRunner.java looked like this:
...
public class MessageRunner {
#Autowired // <-- This will not do the job for us
private static SetterMessage setterMessage;
public static void main(String[] args) {
setterMessage.setMessage("Finally it works."); // NPE here on ref to setterMessage
p(setterMessage.getMessage());
}
...
This is a real gotchya for people new to Spring. In fact, I'd place it among the Top Five Spring Newbie Discouragers and a really evil, pernicious detail that has caused new Spring programmers countless hours in aggravation and Google searches. So I do hope that noting this phenom here will save at least some newbies time and high blood pressure spikes.
Note: If you go to create the above classes in your IDE, bear in mind these were developed with Spring Boot enabled.

Getting JAX-WS WebServices working in Spring Boot

I have some legacy JAX-WS #WebService annotated classes. I am trying to get this working in spring-boot. Been looking at https://jax-ws-commons.java.net/spring/ as a reference as well as http://docs.spring.io/spring/docs/current/spring-framework-reference/html/remoting.html.
My #SpringBootAnnotated class
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class SpringBootBooter extends SpringBootServletInitializer {
#Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean reg = new ServletRegistrationBean(new WSSpringServlet(),"/myws");
reg.setLoadOnStartup(1);
return reg;
}
public static void main(String args[]) throws Exception {
SpringApplication.run(new Object[] {
SpringBootBooter.class,
new ClassPathResource("myLegacyAppContextWithWSBean.xml")
}, args);
}
#Override
public void onStartup(final ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.addListener(new WSServletContextListener());
}
}
My XML config for the WS implementation class
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://jax-ws.dev.java.net/spring/core
http://jax-ws.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet
http://jax-ws.java.net/spring/servlet.xsd">
<wss:binding url="/myws">
<wss:service>
<ws:service bean="#mywsbean" />
</wss:service>
</wss:binding>
<bean id="mywsbean" class="com.items.MyWsBean">
</bean>
</beans>
When everything boots up, I go to localhost:8080/myws and just get back "404 Not Found: Invalid Request".
Just not sure what I am missing, its like something is not parsing those wss:binding XML declarations to tie together these servlet requests to the bean, and I am not sure how to do this in spring-boot.
This appears in logs when I first hit that mapped URI
Jul 15, 2015 9:40:18 AM com.sun.xml.ws.transport.http.servlet.WSServletDelegate <init>
INFO: WSSERVLET14: JAX-WS servlet initializing
thanks
Your solution appears rather complex. You can get a JAX-WS service running with Spring Boot, using only
These Gradle dependencies:
dependencies {
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-jersey"
}
This configuration class (Groovy):
import org.glassfish.jersey.server.ResourceConfig
import org.springframework.stereotype.Component
#Component
class JerseyConfig extends ResourceConfig {
JerseyConfig() {
register(MyResource)
}
}
This resource class:
import org.springframework.stereotype.Component
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.core.Context
import javax.ws.rs.core.MediaType
#Component
#Path("/foo")
class MyResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Map bar() {
return ["hello":"world"]
}
}
and this:
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
#SpringBootApplication
class DemoJaxWSService {
static void main(String[] args) {
SpringApplication.run DemoJaxWSService, args
}
}
Your endpoint will be available at localhost:8080/foo

No unique bean of type is defined: expected single bean but found 0:

I have one spring based standalone project (PTSJMSProxy). I refer http://sahits.ch/blog/?p=2326
In the PTSJMSProxy I have followings.
1) SimpleWriterService.java
package com.test;
import org.springframework.stereotype.Service;
#Service
public class SimpleWriterService {
public void sayHello() {
System.out.println("Hello Spring DI service!");
}
}
2) ComponentConsumer.java
package com.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class ComponentConsumer {
#Autowired
private SimpleWriterService service;
public void consume() {
service.sayHello();
}
}
3) ProxyJMSClient.java
package com.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ProxyJMSClient {
// I commented some portions,but working fine
// Example #Autowired and also in the constructure
// #Autowired
private ComponentConsumer consumer;
public ProxyJMSClient() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// AutowireCapableBeanFactory acbFactory =
// context.getAutowireCapableBeanFactory();
// acbFactory.autowireBean(this);
consumer = context.getBean(ComponentConsumer.class);
}
public void callMyJMSClient() {
this.consumer.consume();
}
}
4) Test.java
package com.test;
public class Test {
public static void main(String[] args) {
(new ProxyJMSClient()).callMyJMSClient();
}
}
5) applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<tx:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.test" />
</beans>
Now when I invoke Test.java from eclipse Run As -Java Application I get the expected out put.
Output - Hello Spring DI service!
=============================================================================
Now I created the Jar with Eclipse export as Jar. Jar Name -PTSJMSProxy.jar
===============================================================================
My objective is to use this jar from a non spring java project
===============================================================================
I created another java project in eclipse "TestProxy"
In that project I add all the required Spring Jar and PTSJMSProxy.jar
Created TestJMSProxy.java class
package com.proxy.test;
import com.wiley.fts.ProxyJMSClient;
public class TestJMSProxy {
public static void main(String[] args) {
(new ProxyJMSClient()).callMyJMSClient();
}
}
When I run - I get following exceptions
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.test.ComponentConsumer] is defined: expected single bean but found 0:
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:269)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)
at com.wiley.fts.ProxyJMSClient.<init>(ProxyJMSClient.java:19)
at com.proxy.test.TestJMSProxyJar.main(TestJMSProxyJar.java:8)
How can I resolve this
NOTE: -
PTSJMSProxy is a spring based project - which has its own applicationContext.xml (Refer point no -5)
TestProxy is a NON Spring Java project - where I use PTSJMSProxy Jar
PTSJMSProxy Jar folder structure
PTSJMSProxy jar contains com,META-INF and applicationContext.xml under same level
The problem is resolved.
This is due to the loading problem of spring configuration xml file.
Code
String fileUrl = PTSJMSProxyClient.class.getClassLoader()
.getResource(SPRING_JMS_CFG_FILE).toString();
LOG.info("Spring jmsContext.xml file path :" +fileUrl);
xmlApplicationContext = new ClassPathXmlApplicationContext(fileUrl);
AutowireCapableBeanFactory acbFactory = xmlApplicationContext
.getAutowireCapableBeanFactory();
acbFactory.autowireBean(this);
client = xmlApplicationContext.getBean(MessageSenderImpl.class);
Sometime it also happens when you define basePackages wrongly inside #ComponentScan annotation like:
#ComponentScan("com.whodesire.model", "com.whodesire.util")
here the above one will considered as single package, if there are multiple packages to scan within your project, then you must mention packages like String[]
#ComponentScan( { "com.whodesire.model" , "com.whodesire.util" } )

How should aspect weaving be limited to classes referenced by aop:advisor pointcuts?

I'm trying to trace execution of an app running on ServiceMix 3.2 which uses spring 2.5 under the hood. I'm using CGLIB (advising classes, not interfaces) and I would like to direct tracing using pointcuts. I therefore configured spring to perform load-time weaving in one of my service unit xbean.xml files like so:
<bean id="debugInterceptor"
class="org.springframework.aop.interceptor.SimpleTraceInterceptor"/>
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="debugInterceptor"
pointcut="within(my.package.AClass)" order="1"/>
</aop:config>
Classes get advised, but it isn't limited to what I specified in the pointcut, i.e. methods of classes other than my.package.AClass get advised and, for reasons not important here, break class loading.
I tried defining the pointcut this way, but it made no difference:
<aop:advisor advice-ref="debugInterceptor"
pointcut="execution(* my.package.AClass.*(..))" order="1"/>
In general, I would like to advise my.package..* classes except my.package.no_aop.*, but I don't seem to be making progress.
Why does CGLIB process classes outside of my.package.AClass? How do I prevent it? Would switching to Spring AOP (as opposed to AspectJ) make a difference?
I did it using Spring 3.0.x and #AspectJ annotations, but it should be analogous using 2.5 and XML.
Class A from package my.pkg, that needs to be adviced:
package my.pkg;
public class ClassA {
public void doFromClassA() {
System.out.println("Hello from A!");
}
}
Class B from package my.pkg.noaop, that needs not to be adviced:
package my.pkg.noaop;
public class ClassB {
public void doFromClassB() {
System.out.println("Hello from B!");
}
}
The aspect:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
#Aspect
public class AopTestAspect {
#Around("within(my.pkg..*) && !within(my.pkg.noaop..*)")
public void advice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("Hello from adviced!");
pjp.proceed();
}
}
The configuration (let me know if You need XML version):
import my.pkg.ClassA;
import my.pkg.noaop.ClassB;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class AopTestConfig {
#Bean
public ClassA classA() {
return new ClassA();
}
#Bean
public ClassB classB() {
return new ClassB();
}
#Bean
public AopTestAspect aspect() {
return new AopTestAspect();
}
#Bean
public AnnotationAwareAspectJAutoProxyCreator autoProxyCreator() {
AnnotationAwareAspectJAutoProxyCreator autoProxyCreator = new AnnotationAwareAspectJAutoProxyCreator();
autoProxyCreator.setProxyTargetClass(true);
return autoProxyCreator;
}
}
The test:
import my.pkg.ClassA;
import my.pkg.noaop.ClassB;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AopTest {
#Test
public void test() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(AopTestConfig.class);
applicationContext.refresh();
ClassA a = BeanFactoryUtils.beanOfType(applicationContext, ClassA.class);
ClassB b = BeanFactoryUtils.beanOfType(applicationContext, ClassB.class);
a.doFromClassA();
b.doFromClassB();
}
}
And the output from the test:
Hello from adviced!
Hello from A!
Hello from B!
As You can see only the ClassA got adviced.
Conclusion
The key is the pointcut experssion:
within(my.pkg..*) && !within(my.pkg.noaop..*)

Resources