Spring's Java Based configuration not working for me - spring

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>

Related

Manipulation of Spring Bean property

I want to change a property of a bean. I want to change it only once for performance (better when reading from XML), not in every bean instance instantiation. What is the best way to do it in Spring?
For elaborating and giving a concrete example:
Below is the datasource bean declaration in databaseContext.xml.
I want to decrypt ${jdbc.password} whose value is ENC(....) with JASYPT.
I could not do it with Jaspt Spring integration since Jaspt not compliant yet with Spring5 and not with Jasypt Hibernate integration since using a different datasource other than Hibernate.
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="connectionTestQuery" value="SELECT 1 from dual" />
<property name="dataSourceClassName" value="oracle.jdbc.pool.OracleDataSource" />
<property name="maximumPoolSize" value="10" />
<property name="idleTimeout" value="30000" />
<property name="dataSourceProperties">
<props>
<prop key="url">${jdbc.url}</prop>
<prop key="user">${jdbc.user}</prop>
<prop key="password">${jdbc.password}</prop>
</props>
</property>
</bean>
This helped me a lot:
Spring property placeholder decrypt resolved property
Just want to add some small correction and extra notes about some findings:
In the link above it is written "location", but it must be "locations" as written below, where it resides at applicationContext.xml
<bean class="com.dummy.util.EncryptationAwarePropertySourcesPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:database.properties</value>
<value>classpath*:hibernate.properties</value>
</list>
</property>
</bean>
"PropertyPlaceholderConfigurer" is deprecated. But it still works. If you try to use the newly proposed class "PropertySourcesPlaceholderConfigurer", it has a bug that it does not call "convertPropertyValue" method as noted here: https://github.com/spring-projects/spring-framework/issues/13568. A workaround noted by the way there.
public class EncryptationAwarePropertySourcesPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
#Override
protected String convertPropertyValue(String originalValue) {
if (originalValue != null && originalValue.startsWith("ENC(")) {
return decrypt(originalValue);
}
return originalValue;
}
.
.
}

Bean property 'sessionFactoy' is not writable or has an invalid setter method

Working on spring+hibernate+maven code.
here's my StockDaoImpl class..
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.mkyong.stock.dao.StockDao;
import com.mkyong.stock.model.Stock;
public class StockDaoImpl extends HibernateDaoSupport implements StockDao{
public void save(Stock stock){
getHibernateTemplate().save(stock);
}
...
My sessionfactory defined in an xml..
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibenate.dialect">org.hibernate.dialect.DerbyDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>/Hibernate/Stock.hbm.xml</value>
</list>
</property>
</bean>
I get the following error in console..Bean property 'sessionFactoy' is not writable or has an invalid setter method...
I tried writing a setter function for sessionfactory in StockDaoImpl...But I get an error saying 'setSessionFactory() in HibernateDaoSupport cannot be overridden'.
Can anyone pls tell me how to resolve the issue..

spring DefaultMessageListenerContainer and websphere MQ - failed to connect Queue Manager

This is my first time to post question on stackoverflow. I tried as much formatting for code/question and try to as much clear as i can do. apologize and explain if there's any err. recorrect in my next question.
I am newbie in try implementing service through soap over jms using websphereMq and spring JMS functionality.
I have make sure below things
binding file generated without any error encounter
Status of queue manager and Queue are up and running.
I encounter below error while try putting message into websphereMQ
com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2058' ('MQRC_Q_MGR_NAME_ERROR')
I have done homework regarding this error. This error may occurs due to unavailability of Queue manager but i see QM is up and running. where i am doing wrong? How can i resolved this error to put message successfully to webspherMQ using spring functionlity?
TestClass
public class JmsTransportWebServiceIntegrationTest {
private static final String expectedResponseContent = "<tns:placeOrderResponse xmlns:tns=\"http://www.packtpub.com/liverestaurant/OrderService/schema\"><tns:refNumber>order-xxxx_yyyy_1234</tns:refNumber></tns:placeOrderResponse>";
#Autowired
private WebServiceTemplate webServiceTemplate;
public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) {
this.webServiceTemplate = webServiceTemplate;
}
#Test
public void testSendReceive() throws Exception {
InputStream is = new JmsTransportWebServiceIntegrationTest().getClass().getResourceAsStream("placeOrderRequest.xml");
StreamSource source = new StreamSource(is);
StringResult result = new StringResult();
webServiceTemplate.sendSourceAndReceiveToResult(source, result);
XMLAssert.assertXMLEqual("Invalid content received", expectedResponseContent, result.toString());
} }
applicationContext.xml
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<map>
<entry key="java.naming.factory.initial"
value="com.sun.jndi.fscontext.RefFSContextFactory"/>
<entry key="java.naming.provider.url" value="file:C:/JNDI-Directory" />
</map>
</property>
</bean>
<bean id="ibm-mq-jms-qcf" class= "org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>jms/mdpSampleQCF</value>
</property>
</bean>
<!-- Bean for JMS Destination -->
<bean id="ibm-mq-queue" class= "org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>jms/mdpSampleQueue</value>
</property>
</bean>
<bean id="listenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="1" />
<property name="connectionFactory" ref="ibm-mq-jms-qcf" />
<property name="destination" ref="ibm-mq-queue" />
<property name="messageListener">
<bean class="org.springframework.ws.transport.jms.WebServiceMessageListener">
<property name="messageFactory" ref="messageFactory"/>
<property name="messageReceiver" ref="messageDispatcher"/>
</bean>
</property>
</bean>
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory"/>
<property name="messageSender">
<bean class="org.springframework.ws.transport.jms.JmsMessageSender">
<property name="connectionFactory" ref="ibm-mq-jms-qcf"/>
</bean>
</property>
<property name="defaultUri" value="jms:mdpSampleQueue?deliveryMode=NON_PERSISTENT"/>
</bean>
<bean id="messageDispatcher" class="org.springframework.ws.soap.server.SoapMessageDispatcher">
<property name="endpointMappings">
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="defaultEndpoint">
<bean class="com.packtpub.liverestaurant.service.endpoint.SimplePayloadEndpoint">
<property name="orderService">
<bean class="com.packtpub.liverestaurant.service.OrderServiceImpl"/>
</property>
</bean>
</property>
</bean>
</property>
</bean
I know this is quite old question, but maybe my answer will help someone in future.
I'm using WebSphere MQ 7.5 now and in installation there are also some Java classes. One that helped me a lot is called MQIVP.java in my installation in c:\Program Files (x86)\IBM\WebSphere MQ\tools\wmqjava\samples. Very good to test setting with this class first. From source of that class we can find that 2058 stands for:
Reason: 2058 - Queue manager name not valid or not known.
Action: Amend the queue manager name and retry.
Simply pressing enter at the queue manager name prompt will
connect to the default queue manager.

How to exposeTransactionAware on a 2nd sessionFactory in hibernate4 + spring?

The test below was working in my application with Hibernate3. When I upgraded it to hibernate4, it started failing.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(inheritLocations=false,locations={
"/hibernate/spring-SF-tests.xml",
"/hibernate/spring-transaction.xml",
"/hibernate/testBeans.xml"
,"/hibernate/spring-audit.xml",
"/hibernate/iwrs-mail-beans-test.xml",
"/hibernate/fake-audit-meaning.xml"
})
#TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
public class CodeAuditIntegrationTest extends CodeIntegrationTest {
#Autowired
private SessionFactory auditFactory;
#Before
public void cleanAudit(){
auditFactory.getCurrentSession().createQuery("delete from AuditLogRecord").executeUpdate();
}
#Test
public void clinicalTrialAssociationTest() {
super.clinicalTrialAssociationTest();
}
}
Which is failing with:
org.hibernate.HibernateException: No Session found for current thread
at
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:881)
I have 2 different session factories in my app: sessionFactory and auditFactory. Both are configured in spring (see [1]).
The problem is that in an hibernate4 configuration the property exposeTransactionAwareSessionFactory was removed. I had that set to true for my auditFactory. I believe removing this property makes the injected auditFactory not being able to pick up the session in the transaction (as txManger is configured for sessionFactory), therefore yielding the error.
Questions:
how can I make the auditFactory have transactions managed by spring on this test?
Is that what was happening with the exposeTransactionAwareSessionFactory property in hibernate 3?
The only alternative I see is to wrap all the code that uses auditFactory in a Helper class annotated with #Transactional(otherTxManager). I did try that, but I got a couple of additional problems there:
I needed to use a separate DataSource (else I'd get [2])
Using 2 separate datasources I'll get a similar error on my Cucumber tests, now related with the transactionManager [3]
[1] The relavant XML configuration:
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="sessionFactory" scope="singleton"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2dll}</prop>
<prop key="hibernate.hbm2ddl.import_files">${hibernate.sql_scripts}</prop>
</props>
</property>
<property name="packagesToScan">...</property>
<property name="annotatedPackages">...</property>
<property name="mappingLocations">...</property>
<property name="dataSource" ref="c3p0DataSource" />
<property name="entityInterceptor" ref="auditInterceptor" />
</bean>
<bean id="auditFactory" scope="singleton"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="exposeTransactionAwareSessionFactory"> -->needs to be removed in hibernate4!
<value>true</value>
</property>
<property name="mappingLocations">...</property>
<property name="packagesToScan">...</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2dll}</prop>
</props>
</property>
<property name="dataSource" ref="c3p0DataSource" />
</bean>
[2] Problem with using the same dataSource for the two factories:
org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! HibernateTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single HibernateTransactionManager for all transactions on a single DataSource, no matter whether Hibernate or JDBC access.
at org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:329)
[3] Problem in cucumber tests due to declaring 2 transaction managers:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single bean but found 2: txAudit,txManager

Spring Velocity Exception while loading applicatonContext

We use spring, velocity for email piece of code in our application and i got below exception. Any idea to solve this.
"org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.springframework.ui.velocity.VelocityEngineFactoryBean' to required type
'org.apache.velocity.app.VelocityEngine' for property 'velocityEngine'; nested exception is java.lang.IllegalStateException: Cannot convert value of type
[org.springframework.ui.velocity.VelocityEngineFactoryBean] to required type [org.apache.velocity.app.VelocityEngine] for property 'velocityEngine': no matching editors or conversion strategy found "
Following is my context configuration.
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="xxxx.US"/>
<property name="port" value="25"/>
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">false</prop>
<prop key="mail.smtp.starttls.enable">false</prop>
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<value>
resource.loader=class
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
</value>
</property>
</bean>
<bean id="emailUtil" class="com.example.MailUtil">
<property name="mailSender" ref="mailSender" />
<property name="velocityEngine" ref="velocityEngine" />
</bean>
You do not need to reference the velocityEngine in your emailUtil bean. Everything else about your spring config is correct.
I grabbed the following code from my app to show you how we are able to use velocity templates.
private String generateMessageFromTemplate(User user, VelocityTemplateEnum velocityTemplateEnum) {
VelocityContext context = new VelocityContext();
context.put("user", user);
StringWriter stringWriter = new StringWriter();
String template = velocityTemplateDao.findById(velocityTemplateEnum.name()).getTemplate();
Velocity.evaluate(context, stringWriter, velocityTemplateEnum.name(), template);
return stringWriter.getBuffer().toString();
}
I have a similar setup only I autowire in the VelocityEngine and that's working for me. Is autowiring an option for you? Also, can you add the code for your MailUtil class? Maybe something isn't 100% right with the velocityEngine field/setter?

Resources