I'm migrating an application from OC4J to WebLogic 12c and the Spring beans are giving an error I can't figure out how to solve. My question is what can be the cause of this error.
I have the following bean for the JNDI lookup:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${datasource.jndiname}" />
<property name="lookupOnStartup">
<value>false</value>
</property>
<property name="proxyInterface">
<value>javax.sql.DataSource</value>
</property>
</bean>
The value ${datasource.jndiname} is expected to come from a config.properties file with the following line:
server.database.datasource=${datasource.jndiname}
And the value of server.database.datasource comes from a config.filter file with the line:
server.database.datasource=jdbc/DATASOURCE
This works fine with OC4J and it also works when I replace the ${datasource.jndiname} to its value jdbc/DATASOURCE in WebLogic, but it gives me the following error if I keep the reference (and I need to keep it):
JndiObjectTargetSource failed to obtain new target object; nested exception is javax.naming.NameNotFoundException: While trying to lookup '${datasource.jndiname}' didn't find subcontext '${datasource'. Resolved ''; remaining name '${datasource/jndiname}'
After some research, I found a property for the bean that fixed the error. Setting the property resourceRef to false makes the reference ${datasource.jndiname} work as expected.
In the final code shown below I also added a JndiTemplate.
<bean id="dsJndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.provider.url">t3://localhost:7001</prop>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${datasource.jndiname}" />
<property name="resourceRef" value="false"/>
<property name="lookupOnStartup" value="false"/>
<property name="proxyInterface" value="javax.sql.DataSource"/>
<property name="jndiTemplate">
<ref local="dsJndiTemplate" />
</property>
</bean>
Related
Im trying to established connection with JMS using Apache Camel, the server is using JNP protocal but always ends with an exceptions.
Need help here, am i missing or doing some thing wrong here.
Technology Stack.
JBoss Fuse 6.3
Apache Camel (for integration)
Blueprint:
<bean id="remoteJndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.provider.url">jnp://X.X.X.X:1099</prop>
<prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
</props>
</property>
</bean>
<bean id="remoteConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean" init-method="afterPropertiesSet">
<property name="jndiTemplate" ref="remoteJndiTemplate"/>
<property name="jndiName" value="ConnectionFactory" />
<property name="lookupOnStartup" value="false" />
<property name="proxyInterface" value="javax.jms.ConnectionFactory" />
</bean>
<bean id="jmsInConnectionFactory" factory-ref="remoteConnectionFactory" factory-method="getObject" />
<bean id="jmsComponent" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration">
<bean class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="jmsInConnectionFactory"/>
</bean>
</property>
</bean>
Exception:
org.osgi.service.blueprint.container.ComponentDefinitionException: Error setting property: PropertyDescriptor <name: expectedType, getter: class org.springframework.jndi.JndiObjectLocator.getExpectedType(), setter: [class org.springframework.jndi.JndiObjectLocator.setExpectedType(class java.lang.Class)]
at org.apache.aries.blueprint.container.BeanRecipe.setProperty(BeanRecipe.java:963)[23:org.apache.aries.blueprint.core:1.4.5]
Caused by: java.lang.Exception: Unable to convert
at org.apache.aries.blueprint.container.AggregateConverter.convertFromString(AggregateConverter.java:252)[23:org.apache.aries.blueprint.core:1.4.5]
Caused by: java.lang.ClassNotFoundException: javax.jms.QueueConnectionFactory not found by IDC-mnp-npg [294]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1556)[org.apache.felix.framework-4.4.1.jar:]
Looks like you're missing the JMS API jar on your classpath based on root caused-by of your exception:
Caused by: java.lang.ClassNotFoundException: javax.jms.QueueConnectionFactory not found by IDC-mnp-npg
I am trying to configure LocalContainerEntityManagerFactoryBean without persisten.xml file.
this is my dataSource - it works for Hibernate SessionFactory - so, it is ok.
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
this is my LocalContainerEntityManagerFactoryBean
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="application.models" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
An exception that i am getting:
...Could not instantiate bean class [org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter]: Constructor threw exception; nested exception is java.lang.IllegalStateException: Failed to determine Hibernate PersistenceProvider
I read documentation, and i know that LocalContainerEntityManagerFactoryBean has such property, and similar style of creating LocalContainerEntityManagerFactoryBean works in Spring in Action 3 and here: http://softwarecave.org/2014/03/15/using-jpa-and-jta-with-spring/
Maybe You have an idea what i am doing wrong or at least what spring want tell me via this exception ?
Thanks in advance,
Cheers :)
P.S to be clear, Failed to determine Hibernate PersistenceProvider doesn't mean that spring expect persistence.xml - this should be error like: No persistence units parsed from {classpath*:META-INF/persistence.xml}
RESOLVED:
thanks JB Nizet - if You will have similar problem add:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.6.Final</version>
</dependency>
to pom.xml
Below code works for me.
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
With hibernate = 4.3.5.Final
spring=4.1.4.RELEASE
I need to concatenate the string value of a spring bean, to an existing string, and then set it as an attribute of another bean:
<bean id="inet" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass"><value>java.net.InetAddress</value></property>
<property name="targetMethod"><value>getLocalHost</value></property>
</bean>
<bean id="host" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="inet"/></property>
<property name="targetMethod"><value>getHostName</value></property>
</bean>
At this point, I have the hostname, in the 'host' bean. I now need to concatenate it and pass it to the publishedEndpointUrl attribute. Something like this:
<jaxws:endpoint
id="foo"
publishedEndpointUrl= "http://" + host + "/Foo"
implementor="com.example.v1.foo"
address="/v1/Foo"/>
How is this done using spring xml configuration?
You could use Spring-EL and factory-method:
<bean id="localhost" class="java.net.InetAddress" factory-method="getLocalHost" />
<bean id="publishedUrl" class="java.lang.String">
<constructor-arg value="#{'http://' + localhost.hostName + '/Foo'}" />
</bean>
<jaxws:endpoint
...
publishedEndpointUrl="#publishedUrl"
...
EDIT:
The jaxws:endpoint tag appears to be able to reference bean values by using the #beanId notation but does not like Spring-EL. So by constructing a String bean, we get around this and it still looks fairly neat.
You need to look at PropertyPlaceholderConfigurer. This allows you define global properties, which can either come from a properties file, or in your case, you can define a default value, in which case it's just a global property. The following will work:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName">
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
<property name="properties">
<props>
<prop key="driver">jdbc.oracle.Driver</prop>
<prop key="dbname">fred</prop>
</props>
</property>
<property name="locations">
<list>
<value>file:properties/application.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>${driver}</value></property>
<property name="url"><value>jdbc:${dbname}</value></property>
</bean>
This means that you have default values for ${driver} and ${dbname}, which are used to define the data source. These values can be overridden in the application.properties file, or even as a -D option on the command line.
As jaxws:* namespace does not like Spring EL, an alternative could be to declare an EndpointImpl bean, instead of the jaxws:endpoint object.
It is some more work, but as pointed out in http://cxf.apache.org/docs/jax-ws-configuration.html, it is the actual implementation used by the namespace declaration.
You can mix propertyplaceholder vars and Spring EL:
<bean id="dataSource" class="xx.xxx.xxxxx.datasource.DataSourceWrapper" destroy-method="close">
<property name="dataSourceClassName" value="${db.dataSourceClassName}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="maximumPoolSize" value="${db.maxConnections}" />
<property name="connectionTimeout" value="${db.connectionTimeout}" />
<property name="dataSourceProperties">
<props>
<prop key="databaseName">${db.databaseName}</prop>
<prop key="serverName">${db.serverName}#{':'}${db.port}</prop>
</props>
</property>
Look at ${db.serverName}#{':'}${db.port} concat.
I have simple application with following folder structure:
ProjFolder
|-----src
|----------packagename
|---------------{sourcefiles}
|----------META-INF
|---------------{beans.xml}
|---------------{hibernate.cfg.xml}
|---------------{EntityMapping.hbm.xml}
here is the part of beans.xml Spring config file:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:./META-INF/jdbc.properties" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:./META-INF/hibernate.cfg.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>classpath:./META-INF/EntityMapping.hbm.xml</value>
</list>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
when i start my unit tests i getting following exception:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'wrapperClass' defined in class path resource
[META-INF/beans.xml]: Cannot resolve reference to bean 'wrapperClassField'
while setting constructor argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'xmlBooksource' defined in class path resource
[META-INF/beans.xml]: Cannot resolve reference to bean
'sessionFactory' while setting bean property 'sessionFactory'; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'sessionFactory' defined in class path
resource [META-INF/beans.xml]: Invocation of init method failed;
nested exception is java.io.FileNotFoundException: class path resource
[classpath:/META-INF/EntityMapping.hbm.xml] cannot be opened because it does not exist
The same exception is thrown when i type
<property name="mappingResources">
<list>
<value>EntityMapping.hbm.xml</value>
</list>
</property>
Why spring cant find this file and how i must fill its location to make this code work?
Thanks in advance.
Have you tried removing the classpath: prefix? In looking at the Hibernate code, the mappingResources setter expects passes the strings to new ClassPathResource(String). This expects classpath resources already. The string then gets passed to ClassLoader.getResourceAsStream(String). None of this code would strip the "classpath:" prefix from the front of the resource string.
I'm not sure the error message is consistent with the beans.xml content you posted.
In the error you have
[classpath:/META-INF/EntityMapping.hbm.xml]
which isn't the same as
classpath:./META-INF/EntityMapping.hbm.xml
Notice the missing "." at the beginning in the error.
The second beans.xml configuration, should probably produce a different error message with:
[classpath:EntityMapping.hbm.xml]
This would be searching for the file in the root of your compiled application (jar, war, exploded, what have you).
I have successfully configure Hibernate 4 with Spring 3.1. My applicationContext.xml file is inside web-inf folder and has the following hibernate cofiguration:
<!-- Session Factory Declaration -->
<bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="DataSource" />
<!--
<property name="annotatedClasses">
<list>
<value>iltaf.models.Levels</value>
</list>
</property>
-->
<property name="mappingLocations" value="classpath:iltaf/models/*.hbm.xml" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>
<!-- Transaction Manager is defined -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory"/>
</bean>
</beans>
and I have separate hibernate.cfg.xml file inside my src folder. I am using Eclipse Juno Java EE version.
i have a spring datasource which looks like this:
<bean id="dataSource1" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database1.url}" />
<property name="username" value="${database1.username}" />
<property name="password" value="${database1.password}" />
</bean>
i need to make this available on jndi or jee. some related things:
<bean id="dataSourceJNDI1" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/dataSource1"/>
<property name="beanClassLoader" ref="dataSource1"></property>
</bean>
or maybe :
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/database1" />
not sure how to get the jndi or jee working with the dbcp. any help would be appreciated.
thanks in advance.
ps: guys this is a special needl. so i have to do it like this. please dont post unnecessary advices saying why i should use tomcat server as datasource. i am aware of setting datasource that way. i repeat again this is a special need. also please dont provide me java code solutions, not required.
ps: those who dont know how to do it, please do not occupy the space of this post saying its not possible. if you dont know the answer no need to post and junk the post.
You would need to bind the DataSource to the JNDI tree. You would need to supply the parameters for connecting to the local JNDI tree. JndiTemplate can do this. Some of the JNDI environment properties probably won't be necessary for a local InitialContext. I think "java.naming.factory.initial" is the only required. The other are for connecting to an out of process JNDI server:
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.provider.url">${jndi.provider.url}</prop>
<prop key="java.naming.factory.initial">${jndi.factory.initial}</prop>
<prop key="java.naming.security.principal">${jndi.security.principal}</prop>
<prop key="java.naming.security.credentials">${jndi.security.credentials}</prop>
</props>
</property>
</bean>
<bean factory-bean="jndiTemplate" factory-method="bind">
<constructor-arg type="java.lang.String" value="java:com/env/DataSoure"/>
<constructor-arg type="java.lang.Object" ref="dataSource"/>
</bean>
If you are performing a JNDI lookup in the same Spring context, you will either need to have the JNDI bean depends-on this lookup bean or make the JNDI lookup lazy so that it will perform the lookup on first use.
Since you are using jndi you have to declare the datasource as a jndi source.
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/database1" />
<bean id="dataSource1" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="dataSource" ref="dataSource" />
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database1.url}" />
<property name="username" value="${database1.username}" />
<property name="password" value="${database1.password}" />
</bean>
That should work assuming your bean definition for dataSource1 is correct.