org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Multiple 'property' definitions - spring

I'm new to Spring and trying to get familiar with the concepts. My purpose is to create multiple instances of the below-mentioned class.
Item.java
public class Item {
private int itemID;
private String itemName;
public int getItemID() {
return itemID;
}
public void setItemID(int itemID) {
this.itemID = itemID;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
#Override
public String toString() {
return itemName;
}
}
In the config.xml I'm trying to set the property values in a below-mentioned way.
<bean name="item" class="com.manasa.spring.springcore.task1.Item">
<property name="itemID">
<value>1</value>
</property>
<property name="itemName">
<value>Sandisk Pendrive</value>
</property>
<property name="itemID">
<value>2</value>
</property>
<property name="itemName">
<value>Dell Keyboard</value>
</property>
</bean>
<bean name="cart" class="com.manasa.spring.springcore.task1.ShoppingCart"
p:id="1">
<property name="items">
<map>
<entry key-ref="item">
<value>2</value>
</entry>
<entry key-ref="item">
<value>1</value>
</entry>
</map>
</property>
</bean>
By doing so, I am facing this issue:
> Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unexpected failure during bean definition parsing
Offending resource: class path resource [com/manasa/spring/springcore/task1/mapconfig.xml]
Bean 'item'; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Multiple 'property' definitions for property 'itemID'
Offending resource: class path resource [com/manasa/spring/springcore/task1/mapconfig.xml]
Bean 'item'
-> Property 'itemID'
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:70)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:308)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseBeanDefinitionElement(BeanDefinitionParserDelegate.java:562)
Could anyone please suggest on how to achieve this?

I guess the problem is here :
<property name="itemID">
<value>1</value>
</property>
<property name="itemName">
<value>Sandisk Pendrive</value>
</property>
<property name="itemID">
<value>2</value>
</property>
<property name="itemName">
<value>Dell Keyboard</value>
</property>
I don't think it is allowed to set values for the same properties several times. When Spring parses this config it actually calls setXXX (appropriate setter) and you are not allowed to reassign values for properties in XML config.
So you need to remove duplicates. Result :
<bean name="item" class="com.manasa.spring.springcore.task1.Item">
<property name="itemID">
<value>1</value>
</property>
<property name="itemName">
<value>Sandisk Pendrive</value>
</property>
</bean>
And if you need several instances (more Item objects) you need to create more beans (add more <bean> ... </bean> sections). E.g.
<bean id="someOtherInstance" name="someOtherInstance" class="com.manasa.spring.springcore.task1.Item">
<property name="itemID">
<value>123</value>
</property>
<property name="itemName">
<value>Some Other Value</value>
</property>
</bean>
Remember that you need to give them different ids (names) so Spring could distinguish.

Related

Java based approach for injecting list of spring beans

I am trying to get rid of my XML beans definition file. I would like to know how can i convert the following XML configuration to Java code.
<bean id="CustomerBean" class="com.java2s.common.Customer">
<property name="lists">
<bean class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="targetListClass">
<value>java.util.ArrayList</value>
</property>
<property name="sourceList">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</property>
</bean>
</property>
</bean>
I am especially interested in knowing how to convert a list, Set, Map and properties XML configurations to Java code.
And if in a list if i have defined the beans in order like
<bean p:order="1000"
How i can manage the same ordering in java code.
A <list> corresponds to java.util.List, <map> corresponds to java.util.Map, <props> corresponds to java.util.Properties and so on.
To set the order, use the org.springframework.core.annotation.Order annotation on your bean or let it implement org.springframework.core.Ordered.
The equivalent of your XML configuration is something like:
#Bean
public Customer CustomerBean() {
Customer customer = new Customer();
List<String> lists = new ArraysList<>();
lists.add("1");
lists.add("2");
lists.add("3");
customer.setLists(lists);
return customer;
}
Note that the name of the method will be the name of the bean.

Spring's Java Based configuration not working for me

I am new to Spring programming and currently struggling with Spring 3.1's Java Based Configuraion" I have created following Configuration class
#Configuration
#ImportResource("classpath:/resources/jdbc.properties")
public class AppConfig {
#Autowired
Environment env;
private #Value("${jdbc.url}")
String url;
private #Value("${jdbc.username}")
String username;
private #Value("${jdbc.password}")
String password;
#Bean
public DataSource dataSource() {
System.out.println("Creating data Source.");
return new DriverManagerDataSource(url, username, password);
}
#Bean
public SessionFactory sessionFactory () throws Exception {
return new AnnotationSessionFactoryBuilder().setDataSource(dataSource()).setPackagesToScan("com.argusoft.loginmodule.domain").buildSessionFactory();
}
}
now when I try to run the project I get following error.
OUTPUT
SEVERE: Exception while loading the app :
java.lang.IllegalStateException: ContainerBase.addChild: start:
org.apache.catalina.LifecycleException:
java.lang.IllegalArgumentException: javax.servlet.ServletException:
java.lang.NoClassDefFoundError:
org/springframework/core/env/EnvironmentCapable
stuck into it, Cant solve it..... I am following Spring Source Blog.
please also suggest some good tutorial in which Spring's latest Java based configuration is explained by easy to understand examples...
Thanks in advance,
From the perspective of the exception:
java.lang.NoClassDefFoundError: org/springframework/core/env/EnvironmentCapable
This question is equals to the question: Spring class EnvironmentCapable
So the correct answer might be:
I think that need use version 3.1.0 - in package
org.springframework.core-3.1.0.M2.jar this class presents.
given by user810430 here: original answer.
you can puth configuration like this
inside application context:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/configuration.properties</value>
</list>
</property>
</bean>
<import resource="db-config.xml" />
and
db-config.xml is:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>${jdbc.driver.className}</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" autowire="byName">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="packagesToScan" value="com.huawei.sa.album" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- uncomment this for first time run-->
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<tx:annotation-driven />
</beans>

Is there a shorter version of how you use MethodInvokingFactoryBean in cfg file?

Currently it is used as shown below...wondering if there is a shorter version (similar to the util namespace)
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref bean="transformation" />
</property>
<property name="targetMethod">
<value>addTransformers</value>
</property>
<property name="arguments">
<list>
<ref bean="customTransformers" />
</list>
</property>
</bean>
You can write it a bit shorter by using Spring P-Namespace
You're using very verbose syntax, you can make it shorter just by being more concise:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="transformation"/>
<property name="targetMethod" value="addTransformers"/>
<property name="arguments">
<list>
<ref bean="customTransformers" />
</list>
</property>
</bean>
Aside from that, and maybe using the p: syntax mentioned by #Ralph, I'm not aware of a namespace-based shortcut.
Another approach using #Configuration but for setting a System property, you can adapt though:
#Bean
public Properties retrieveSystemProperties(){
return System.getProperties();
}
private Properties systemProperties;
public Properties getSystemProperties() {
return systemProperties;
}
#Resource(name="retrieveSystemProperties")
public void setSystemProperties(Properties systemProperties) {
this.systemProperties = systemProperties;
}
#Bean
public MethodInvokingFactoryBean methodInvokingFactoryBean() {
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setStaticMethod("java.lang.System.setProperties");
systemProperties.setProperty("http.keepAlive", "false");
methodInvokingFactoryBean.setArguments(new Object[]{systemProperties});
return methodInvokingFactoryBean;
}
If you don't have any parameters, you can do this:
<bean id="mybean" factory-instance="otherBean" factory-method="getMyBean"/>

How to get formatted xml output from jaxb in spring?

I am using Jaxb2Marshaller as a view property for ContentNegotiatingViewResolver. I am able to get the xml repsonse. How do I format (pretty print) it?
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
</map>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
</list>
</property>
</bean>
</constructor-arg>
</bean>
</list>
</property>
</bean>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list> .... </list>
</property>
<property name="marshallerProperties">
<map>
<entry>
<key>
<util:constant static-field="javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT" />
</key>
<value type="java.lang.Boolean">true</value>
</entry>
</map>
</property>
</bean>
Try setting this property on your marshaller object:
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE )
Here is the full Javadoc for the Marshaller interface. Check out the Field Summary section.
Was looking for this and thought I'd share the code equivalent
#Bean
public Marshaller jaxbMarshaller() {
Map<String, Object> props = new HashMap<String, Object>();
props.put(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
Jaxb2Marshaller m = new Jaxb2Marshaller();
m.setMarshallerProperties(props);
m.setPackagesToScan("com.example.xml");
return m;
}
Ritesh's answer didn't work for me. I had to do the following:
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list> ... </list>
</property>
<property name="marshallerProperties">
<map>
<entry key="jaxb.formatted.output">
<value type="boolean">true</value>
</entry>
</map>
</property>
</bean>
Another way to achieve the purpose use stringwriter class.
public class geoClientSpringWS extends WebServiceGatewaySupport
{
public GetGeoIPResponse getGeoIPResponse(String inputval) throws JAXBException
{
String endpointuri="http://Kondle-PC:8088/mockGeoIPServiceSoap";
GetGeoIP requestobj= new GetGeoIP();
requestobj.setIPAddress(inputval);
Jaxb2Marshaller marshaller= new Jaxb2Marshaller();
StringWriter textwriter= new StringWriter();
JAXBContext jaxbContext = JAXBContext.newInstance(GetGeoIP.class);
jaxbContext.createMarshaller().marshal(requestobj, textwriter);
String textwriteroutput=textwriter.toString();
System.out.println("response : " + textwriteroutput);
GetGeoIPResponse responseobj=(GetGeoIPResponse) getWebServiceTemplate().marshalSendAndReceive(endpointuri, requestobj);
return responseobj;
}
}
Use jaxb.formatted.output instead of javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT as
Map<String,Object> map = new HashMap<String,Object>();
map.put("jaxb.formatted.output", true);
jaxb2Marshaller.setMarshallerProperties(map);

Help with spring-json using annotated controllers

I've scourged the internet for an example that would use both spring-json and annotated controllers, I'm new to spring so I've had no luck adapting the configuration on spring-json's samples (it uses SimpleController et. al.)
Currently I have a controller with 2 mappings, one lists results in html (and works), the other should render json for some ajax calls but when I access the url it returns a 404 and asks for /myapp/jsp/jsonView.jsp. The code on the show method does execute and it even validates the presence of the id param, so it seems that the problem is that it doesn't know how render, as far as I know that's what the viewResolver bean does.
Thanks in advance for any help :)
Here's what I've got:
#Controller
public class ItemController {
//This one works
#RequestMapping(value = "/items", method = RequestMethod.GET)
public ModelMap list() {
ModelMap map = new ModelMap();
map.addAttribute("item", "value");
return map;
}
//This one returns 404, asks for jsonView.jsp
#RequestMapping(value = "/items.json", method = RequestMethod.GET)
public ModelAndView show(#RequestParam(value = "id", required = true) String id) {
Map model = new HashMap();
model.put("firstname", "Peter");
model.put("secondname", "Schmitt");
return new ModelAndView("jsonView", model);
}
}
on myapp-servlet.xml:
<bean name="viewResolver" class="org.springframework.web.servlet.view.XmlViewResolver"/>
on views.xml:
<beans>
<bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView">
<property name="encoding">
<value>UTF-8</value>
</property>
<property name="contentType">
<value>application/json</value>
</property>
<property name="jsonWriter">
<ref bean="sojoJsonWriter"/>
</property>
<property name="jsonErrors">
<list>
<ref bean="statusError"/>
<ref bean="modelflagError"/>
</list>
</property>
</bean>
<bean name="sojoJsonWriter" class="org.springframework.web.servlet.view.json.writer.sojo.SojoJsonStringWriter">
<property name="convertAllMapValues">
<value>true</value>
</property>
</bean>
<bean name="statusError" class="org.springframework.web.servlet.view.json.error.HttpStatusError">
<property name="errorCode">
<value>311</value>
</property>
</bean>
<bean name="modelflagError" class="org.springframework.web.servlet.view.json.error.ModelFlagError">
<property name="name">
<value>failure</value>
</property>
<property name="value">
<value>true</value>
</property>
</bean>
web.xml:
<servlet>
<servlet-name>myapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myapp</servlet-name>
<url-pattern>/myapp/*</url-pattern>
</servlet-mapping>
There could be another alternative: Are you able to upgrade to spring 3 (it has release state now)? There is a fantastic ContentNegotiationResolver which helps a lot when it comes to content-negotatioon and view-resolving.
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
...
If now appending .json to your URL path or using respective 'Accept' HTTP header, passed object (see model.put(...)) is serialized accordingly. For json spring 3 is using jackson by default.
The problem was with the view resolver on the servlet.xml, added a p:order attribute so it would load before the InternalResourceViewResolver
<bean name="viewResolver" class="org.springframework.web.servlet.view.XmlViewResolver" p:order="1"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/jsp/"p:suffix=".jsp" p:order="10"/>

Resources