Start the H2 database in server mode via Spring - spring

I'm trying to start the H2 database in server mode (I want it to run in a different process) via Spring.
Currently I'm using java Runnable.exec to start the h2 database (using the command: "java -cp h2.jar org.h2.tools.Server")
I know that there is a way to do it via Spring. I tried to add the following to the spring configuration, but it didn't work (it didn't start the H2 database):
<bean id="org.h2.tools.Server" class="org.h2.tools.Server"
factory-method="createTcpServer" init-method="start" destroy-method="stop">
<constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,8043" />
</bean>
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server"
factory-method="createWebServer" init-method="start">
<constructor-arg value="-web,-webAllowOthers,true,-webPort,8082" />
</bean>
I would appreciate any help/ideas

Do you happen to have:
<beans default-lazy-init="true" ...
in your Spring configuration files?

Recently I had to do the same configuration to make unit test and check data, this works for me (Spring 3.1.4). Then you just have to connect with jdbc:h2:tcp://localhost:8043/mem:test and make sure to put a while(true){} at the end of your test.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.h2.Driver"/>
<!--property name="url" value="jdbc:h2:mem:;TRACE_LEVEL_FIlE=4"/-->
<property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean class="org.h2.tools.Server" factory-method="createTcpServer" init-method="start" destroy-method="stop">
<constructor-arg>
<array>
<value>-tcp</value>
<value>-tcpAllowOthers</value>
<value>-tcpPort</value>
<value>8043</value>
</array>
</constructor-arg>
</bean>

Are you sure the createTcpServer method in the Server class is really called? Have you tried setting up a breakpoint there?
H2 tutorial claims this how you can create and start the server programmatically:
import org.h2.tools.Server;
...
// start the TCP Server
Server server = Server.createTcpServer(args).start();
...
// stop the TCP Server
server.stop();
Your Spring definition seems to mimick the same initialization. But you can always try doing it manually - maybe it's some fault in Spring configuration.
EDIT:
I've tried your configuration and it works for me. What makes you think the server is not started? It doesn't print out anything on stdout, however the process listens at the 8043 port. So it seems pretty OK.

Related

How to make JNDI look up optional in Spring

Is there anyway where we can make the JNDI lookup optional in spring appllicationcontext xml configuration.
I want to deploy the same application which has JNDI setting(Data base connection) on two different environments. In one environment we need DB connection and another environment we don't need the DB connection. Could you please suggest if there is a away we can achieve this without modifying the applicationcontext.xml(I mean without commenting out the JNDI configuration and other related bean injection for DB connection).
Use profiles, something like:
<beans profile="prod">
<jee:jndi-lookup id="dbDataSource" jndi-name="jdbc/DatabaseName"expected-type="javax.sql.DataSource" />
</beans>
<beans profile="dev,default">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" 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}"/>
<property name="connectionCachingEnabled" value="true"/>
</bean>type="javax.sql.DataSource" />
</beans>
Then when you start you app say which profile with system argument:
-Dspring.profiles.actibe=prod
The default profile will be dev.

Cloudbees, Tomcat, and Spring: "Cannot create JDBC driver of class '' for connect URL 'null'"

I'm trying to deploy my Spring MVC webapp (Hibernate and JPA) to a Tomcat 7 ClickStack in Cloudbees, but cannot seem to configure the database connection properly. I've tried following multiple tutorials (which offer many solutions), none of which have worked. If someone could take a look at my config files below and let me know if they see anything wrong it would be greatly appreciated.
The error:
java.lang.NullPointerException
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
First, I bound my database to my app using the cloudbees cli so that I don't have to declare it in cloudbees-web.xml:
bees app:bind -a myapp/app -db mydatabase
application - myapp/app bound to cb-db:myapp/mydatabase as mydatabase
(I have also tried unbinding the database and defining it in cloudbees-web.xml and also in context.xml without success)
spring-data.xml:
<jee:jndi-lookup id="datasource" jndi-name="jdbc/mydatabase"
lookup-on-startup="false" proxy-interface="javax.sql.DataSource"
cache="true" resource-ref="true" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="hibernate-jpa"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="showSql" value="false"/>
<property name="generateDdl" value="true"/>
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
web.xml:
<resource-ref>
<res-ref-name>jdbc/mydatabase</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
I have removed all references to connectors from my Maven files and all jars from the lib folder. Searching for the error message shows that it usually has to do with the driver not being found... but since the database is supplied by the container, why do I have to worry about that?
-- EDIT: Working META-INF/context.xml file --
Note that the com.cloudbees.jdbc.Driver referenced in a lot of the docs didn't work (threw a classnotfound exception), so I had to package the mysql-connector-java.jar file in the lib folder. Also, for now I just hardcoded the url, username, and password instead of setting it up to use the system properties.
<Context>
<Loader delegate="true"/>
<Resource
name="jdbc/mydatabase"
auth="Container"
type="javax.sql.DataSource"
maxActive="5"
maxIdle="2"
username="USERNAME"
maxWait="5000"
driverClassName="com.mysql.jdbc.Driver"
password="PASSWORD"
url="jdbc:mysql://MY_EC2_DB_URL:3306/mydatabase"/>
</Context>
I was facing the same issue and finally managed to "properly" configure the datasource !
I'm using a PropertyPlaceholderConfigurer as follows :
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="database" value="MYSQL" />
<property name="generateDdl" value="false" />
</bean>
<context:property-placeholder system-properties-mode="FALLBACK" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${dt4j.driver}" />
<property name="url" value="${dt4j.url}" />
<property name="username" value="${dt4j.username}" />
<property name="password" value="${dt4j.password}" />
</bean>
"FALLBACK" indicates placeholders should be resolved against any local properties and then against system properties.
Finally, I just need to add system properties (-Dprop=value) or add them in the Cloudbees deployer plugin to make it work.
There must be a better way but the main goal is achieved : the data source configuration is not hardcoded in the project !
Unfortunately at this point in time, the JNDI DB setup is not done for you in the tomcat7 stack.
When you bind the database to your app - it injects some system properties:
MYSQL_PASSWORD_MYDB
MYSQL_URL_MYDB
MYSQL_USERNAME_MYDB
(MYDB as it is the name of your db resource). You can then refer to them in your code/config.
For tomcat 7, you can put in /META-INF/context.xml into your app which will set up the JNDI data source (see http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html)

Passing encrypted properties to spring context

I never seen this but I wondering if somebody has come across. Having a web server which access a database. I want to pass the database password encrypted and have spring context decrypting it before setting the datasource. I know the spring security can do some of this like using a salt file in the web server, etc.
The challenge here is that I don't want to give a clear user,password,url to the web server team. Just an encrypted password and have spring decrypted before using it.
Is there something like this already? I know I could code something but is it already done?
Thanks
By using an org.jasypt.properties.EncryptableProperties object, an application would be able to correctly read and use a .properties file like this:
datasource.driver=com.mysql.jdbc.Driver
datasource.url=jdbc:mysql://localhost/reportsdb
datasource.username=reportsUser
datasource.password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm)
Note that the database password is encrypted (in fact, any other property could also be encrypted, be it related with database configuration or not).
More information :
http://www.jasypt.org/encrypting-configuration.html
I actually found exactly what I was looking for in this thread:
How to use encrypted password in apache BasicDataSource?
Here are the details from jasyp http://www.jasypt.org/spring3.html
This problem and solution to it is explained here..(link)
db.Properties.
#driverClassName=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:#localhost:1521:XE
#username=ITEM_INVENTORY
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ITEM_INVENTORY?zeroDateTimeBehavior=convertToNull
username=root
Encrypt db.Properties
##password=cGFzc3dvcmQ=
password=cm9vdA==
The spring beans configuration for the datasource would look like this
(here you may use only password part)
spring-beans.xml
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="db#[driverClassName]" />
<property name="url" value="db#[url]" />
<property name="username" value="db#[username]" />
<property name="password" value="encryptedDb#[password]" />
</bean>
<bean id="dbPropertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
<property name="placeholderPrefix" value="db#[" />
<property name="placeholderSuffix" value="]" />
</bean>
<bean id="encryptedDbPropertyPlaceholder" class="com.inventory.api.util.DecryptPropertyConfigurer">
<property name="locations">
<list>
<value>classpath:encryped_db.properties</value>
</list>
</property>
<property name="placeholderPrefix" value="encryptedDb#[" />
<property name="placeholderSuffix" value="]" />
</bean>
And so on.. please refer given link for more information..

Setting properties in Spring

Is there a way to change the properties of a file? I'm trying to run selenium tests in parallel, with Spring and Jetty, so I'm trying to configure the url of the database, the port of the jettyserver and the port of the selenium server. So that I'm able to initialize two or more servers where the tests can run on.
My server.properties file contains this:
jdbc.url=jdbc:hsqldb:hsql://localhost/bibliothouris_scenario
jetty.port=8081
seleniumServer.port=4444
I can read those properties with a PropertyPlaceholderConfigurer, and I need the database URL, jettyport and seleniumserver port to be flexible.
I have declared them like this:
In my applicationContext.xml:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:server.properties</value>
</property>
</bean>
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
In the serverContext.xml file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:server.properties</value>
</property>
</bean>
<bean class="com.~companyName~.bibliothouris.jetty.JettyServer" init-method="start" destroy-method="stop">
<constructor-arg value="${jetty.port}" />
<constructor-arg ref="dataSource" />
</bean>
<bean class="org.openqa.selenium.server.SeleniumServer" init-method="start" destroy-method="stop">
<constructor-arg>
<bean class="org.openqa.selenium.server.RemoteControlConfiguration">
<property name="port" value="${seleniumServer.port}" />
<property name="singleWindow" value="true" />
<property name="timeoutInSeconds" value="10" />
</bean>
</constructor-arg>
</bean>
<bean class="com.thoughtworks.selenium.DefaultSelenium" init-method="start" destroy-method="stop" lazy-init="true">
<constructor-arg>
<bean class="com.thoughtworks.selenium.HttpCommandProcessor">
<constructor-arg value="localhost" />
<constructor-arg value="${seleniumServer.port}" />
<constructor-arg value="*firefox c:/~companyname~/firefox/firefox.exe" />
<constructor-arg value="http://localhost:${jetty.port}" />
</bean>
</constructor-arg>
</bean>
When I change the data in server.properties the selenium tests run on the right servers with the right ports, without failures.
So now I'm looking for a method to change the properties in the server.properties file.
Kind regards and thanks in advance
I solved this by having a flag in my build process (I'm using Maven) that chose which property file to include in the final war. This way you can include different artifacts (different property files) with different properties without having to mess with the low level property support of Spring.
If you do need to do this is Spring only, I would recommend going for a Java based configuration, where you can get and set the properties by in code not in XML.
Is there a way to change the
properties of a file?
No, but you could solve this in the following ways.
Split the properties into jdbc.properties (for applicationContext.xml) and test.properties (for serverContext.xml)
override server.properties via a src/test/resources resource
use system properties in addition to server.properties (use PropertyPlaceholderConfigurer.setSystemPropertiesMode for this)
Thanks for the help guys, without your info, I couldn't find my own solution. Here it is:
try {
Properties props = new Properties();
FileInputStream fileInputStream = new FileInputStream(
"C:\\~CompanyName~\\workspace\\bibliothouris\\infrastructure\\src\\main\\resources\\server.properties");
props.load(fileInputStream);
fileInputStream.close();
props.setProperty("seleniumServer.port", "4445");
FileOutputStream fileOutputStream = new FileOutputStream(
"C:\\~CompanyName~\\workspace\\bibliothouris\\infrastructure\\src\\main\\resources\\server.properties");
props.store(fileOutputStream, "");
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
I've wrote this piece of code in a testclass, now I have to create a method of it, which takes a few arguments (the URL, jettyport and seleniumport). And I have to change the path to a relative one.
Thanks for the help!

how to make connection pool in spring application using BasicDataSource

I have created the application in which I need to configure the connection pool.In which I am configuring the connection pooling in the spring_Config file. using the Basicdatasource.
but there is some problem to create the connection pool. Please tell me how to create the connection pooling in spring application using BasicDatasource.
I tried this one code in spring config ;-
bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
com.mysql.jdbc.Driver
jdbc:mysql:/revup?noAccessToProcedureBodies=true
jdbc:mysql://localhost:3306/revup?noAccessToProcedureBodies=true</value>-->
</value>-->
</value>-->
<property name="poolPreparedStatements">
<value>true</value>
</property>
<property name="initialSize">
<value>2</value>
</property>
<property name="maxActive">
<value>15</value>
</property>
Is there any modification of code please tell me. thanks in advance.
Here's a working example:
<bean id="dataSourceApache" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/coffee_shop" />
<property name="username" value="john" />
<property name="password" value="secret" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
If you're using Eclipse, you should also download support for XML configuration syntax. It really helps you alot.
SpringSource Tool Suite has all the SpringSource support bundled ready for use.
Else, you can see all the fields that's possible to set in the Java documentation.

Resources