jmx mbean server throw InstanceAlreadyExistsException when change c3p0 version - java

What are the differences between c3p0-0.9.1.2 and c3p0-0.9.5 that mean that when I want to register an MBean with DynamicPooledDataSourceManagerMBean in 0.9.1.2 everything is okay, but when I use 0.9.5 then com.sun.jmx.mbeanserver.Repository throws an javax.management.InstanceAlreadyExistsException.
I use spring as my container so the bean definition for DynamicPooledDataSourceManagerMBean is like this:
<bean id="register" class="com.mchange.v2.c3p0.management.DynamicPooledDataSourceManagerMBean">
<constructor-arg index="0" ref="dataSource"/>
<constructor-arg index="1" value="my.pool.connection:type=c3p0,name=Main"/>
<constructor-arg index="2" ref="mbeanServer"/>
</bean>
which the dataSource ref definition is a com.mchange.v2.c3p0.ComboPooledDataSource and defined like this:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" lazy-init="true" >
and a lot of datasource config
and the mbeanSever is a Spring org.springframework.jmx.support.MBeanServerFactoryBean which is defined like this:
<bean name="mbeanServer"
class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
<property name="registerWithFactory" value="true"></property>
</bean>

The problem, as #SteveWaldman said, was I tried to register my datasources into MBean server which c3p0 registered them before. So what I should have done was nothing.
But there were some modification need to be done to what c3p0 registed.
c3p0 register datasource with a name like this:
com.mchange.v2.c3p0:type=PooledDataSource,identityToken=1hgeowz961y14x0ldebkgx|1‌​23f9b8,name=Main
I would like to avoid adding identityToken so as said here I create a c3p0.properties file and put this line into it:
com.mchange.v2.c3p0.management.ExcludeIdentityToken=true
That was pretty much everything I had to do for my case. Thanks to #StevenWaldman.

Related

Spring context initialization even on JNDI error

I have Spring configuration below. How I can make Spring content initialization even if DB_JNDI does not exist in Application server?
<jee:jndi-lookup id="friends.db" jndi-name="DB_JNDI"/>
<bean name="friendsDbDaoImpl" class="com.tims.db.friendsDbDaoImpl" init-method="init" >
<property name="dataSource" ref="friends.db" />
<property name="queryTimeout" value="${imos.db.friends.querytimeout}" />
</bean>
You can use Spring profiles. They were implemented with this kind of requirement (conditional configuration) in mind.

Create Freemarker Configuration bean in Spring, together with parameter

I am having trouble creating a "freemarker.template.Configuration" bean and setting global shared variables in this instance of the Configuration. Something like:
<bean id="conf" class="freemarker.template.Configuraton">
<property name="sharedVariable" >
**??**
</property>
</bean>
Is this possible?
I can't use FreeMarkerConfigurer instead of Configurer because I am using servlets (full stack of Spring MVC) as controllers in my project. Is there any way to convert a FreemarkerConfigurer into a Configurer?
The problem stems from that shared variables is not a JavaBean property... but, accidentally, Configuration has a setAllSharedVariables(TemplateHashModelEx) method, that's technically a property, so something like this should work (I haven't tried it and my Spring XML is rusty... tell me if there are typos in it):
<bean id="conf" class="freemarker.template.Configuraton">
<property name="allSharedVariables">
<bean class="freemarker.template.SimpleHash">
<constructor-arg>
<map>
<entry key='someVarName' value='someValue' />
<entry key='otherVarName' value-ref='valueBeanId' />
</map>
</constructor-arg>
</bean>
</property>
</bean>

SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization

I've got an app running on Tomcat 7, using Spring, Mybatis, and .. Mybatis-spring.
Here's the setup for the DB and transactions in servlet-context.xml:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDS" />
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:maps/*.xml" />
<property name="transactionFactory">
<bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>
</bean>
<mybatis:scan base-package="com.domain.dao.mappers" />
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
The error I'm getting when I run a method that uses the SqlSession is the following:
org.springframework.dao.TransientDataAccessResourceException: SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization
at org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:136)
What am I doing wrong?
My goal, really, is just to use transactions with this setup. I don't think I necessarilly need JTA. But if that's easy enough to setup on Tomcat, I'm willing to take a swing at it.
And I solved the problem myself. Really simple solution. In case anyone runs into the same issue, all I needed to do is remove the following from the sqlSessionFactory bean:
<property name="transactionFactory">
<bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>
I must have somehow entered it thinking I needed it, but apparently it's only needed if you're not using CMT (Container Managed Transactions).
You can solve this by changing the transaction factory to
<property name="transactionFactory">
<bean class="org.mybatis.spring.transaction.SpringManagedTransactionFactory" />
</property>

spring -- are beans in application context binded to PropertyPlaceholderConfigurer dynamically?

I want to know if beans in my application context are binded dynamically. Specifically, if I have
<bean id="mySpringRemoteService"
class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceInterface"
value="foo.bar.services.mySpringRemoteService" />
<property name="serviceUrl" value="${spring.remote.service.url}"/>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:some.properties"/>
</bean>
if i change the property for the service url in my properties file, will retrieving the bean later reflect this change?
Well, I think it is easy for you to have a try yourself.
The answer is No (Unless behavior of Spring changed in 3.x )
I believe you have to implement runtime update behavior for config files. Take a look in Apache Commons Configurations.

How to set dynamically a bean reference in Spring?

<bean id="Mybean" class="Bean">
<property name="config" ref="dev"/>
</bean>
<bean id="dev" class="Dev">
<property name="x" ref="Dev1">
<property name="y" ref="Dev2">
<property name="z" ref="Dev3">
</bean>
<bean id="stag" class="Dev">
<property name="x" ref="Stag1">
<property name="y" ref="Stag2">
<property name="z" ref="Stag3">
</bean>
In the above scenario, the config property in the bean MyBean change from environment to environment. At the time of dev, reference of config change to dev. And in staging, the reference change to stag. The problem comes at the time of checked in the spring file. We have to analyze everytime the reference of config before checked in. If the reference of config with the value of dev checked in, we might have to explain a lot of questions.
Is there any solution to solve to make it automate?
Note: Spring version is 2.0.1
Use the PropertyPlaceholderConfigurer from Spring, and remove an unused bean :
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>env.properties</value>
</property>
</bean>
<bean id="Mybean" class="Bean">
<property name="config" ref="config"/>
</bean>
<bean id="config" class="Config">
<property name="x" ref="${x}">
<property name="y" ref="${y}">
<property name="z" ref="${z}">
</bean>
and the env.properties file contains the following properties :
x=Dev1
y=Dev2
z=Dev3
or
x=Stag1
y=Stag2
z=Stag3
setup up the placeholder bean by specfiy, let spring know you want the placeholder
set up the config for the "my bean" by using the "${env}"
for example:
<beans>
<bean id="configBean" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"><value>env.properties</value></property>
</bean>
<bean id="Mybean" class="Bean">
<property name="config" ref="${env}"/>
</bean>
</beans>
and you need the add the env = dev key-value to the env.properties file
Assuming you meant Spring 3.1, rather than Spring 2.1 (which doesn't exist), then you can use the new "Environment Profiles" feature that was introduced in 3.1. This allows you to define a set of beans for each of your environments, and then select the "active" one at runtime.
See this SpringSource Blog Entry for examples.
You can do it using PropertyPlaceholderConfigurer or using #Profile
Also See
is-there-any-way-to-enable-or-disable-the-spring-bean-definition-in-applicationc
PropertyPlaceholderConfigurer example
PropertyPlaceholderConfigurer is the answer, yet I would imagine that you would like this to happen without the need to stay updating your properties file for each environment.
My suggestion would therefore be as follows
Use PropertyPlaceholderConfigurer, but do not create a properties file
By default, PropertyPlaceholderConfigurer first tries to find a value in a properties file, but if that fails, it will look for one in system properties
So all you need to do is to define both beans the same way that you are doing it, i.e. dev and stag.. which is a fine approach since you're clearly showing the different configurations... it would help if you also added some alias to show clearly the setting you want to use.
Next, pass in a system property defining what mode you are in... and ideally explicitly set PropertyPlaceholderConfigurer to use System properties.
So.. your config would look something like this
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
systemPropertiesMode="2"/>
<bean id="Mybean" class="Bean">
<property name="config" ref="${launch.mode}"/>
</bean>
<bean id="dev" name="dev_mode" class="Dev">
<property name="x" ref="Dev1">
<property name="y" ref="Dev2">
<property name="z" ref="Dev3">
</bean>
<bean id="stag" name="staging_mode" class="Dev">
<property name="x" ref="Stag1">
<property name="y" ref="Stag2">
<property name="z" ref="Stag3">
</bean>
You can then pass in the property upon startup in the following fashion
-D<property-name>=<value>
So in this case you'd use
-Dlaunch.mode=dev_mode
Or
-Dlaunch.mode=staging_mode
And you won't need to touch any of the configuration files.
Just a further note on systemPropertiesMode, accepted values are the following:
0 - never look in system properties
1 - use system properties as a fallback (i.e. if not found in properties files)
2 - system properties always override (the mode i'm suggesting)
Hope it helps :)
Note: This recommendation is only applicable to Spring < 3.1, since from 3.1 onward, the recommended approach is to use #Profile
Spring provides a mechanism called property placeholders. This way you can set certain properties in a database/properties file and spring will fill them in on startup.
The class to use for this is located here.

Categories

Resources