I have trying to test HikariCP as jndi datasource, but i cannot find the way to add it as jndi datasource in weblogic.
If it's possible can you provide the configuration or if not can you add this feature ?
I hope this helps you.
I saw this article a bit ago on the subject:
https://github.com/brettwooldridge/HikariCP/wiki/JNDI-DataSource-Factory-(Tomcat,-etc.)
It describes several issues about JNDI connections to weblogic with hicaricp. One of the major issues is Connection Pooling which is static.
Examples are all over in the Article in GITHUB, but one of the main examples I re-pasted below from there:
HikariCP includes a JNDI DataSource factory that can be used with Tomcat or other containers.
Example (Tomcat) configurations:
Driver-based:
<Resource name="jdbc/OracleHikari" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
connectionTimeout="300000"
jdbcUrl="jdbc:oracle:thin:#orcl_server:1521:orcl"
dataSource.implicitCachingEnabled="true"
dataSource.user="user"
dataSource.password="pwd" />
DataSource-based:
<Resource name="jdbc/OracleHikari" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
connectionTimeout="300000"
dataSourceClassName="oracle.jdbc.pool.OracleDataSource"
dataSource.implicitCachingEnabled="true"
dataSource.user="user"
dataSource.password="pwd"
dataSource.url="jdbc:oracle:thin:#orcl_server:1521:orcl"/>
A MariaDB example:
<Context>
<Resource name="jdbc/myDs" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
connectionTimeout="300000"
dataSourceClassName="org.mariadb.jdbc.MySQLDataSource"
dataSource.serverName="localhost"
dataSource.port="3306"
dataSource.databaseName="myDatabase"
dataSource.user="username"
dataSource.password="password"
/>
</Context>
Hope this works for you.
If not, please provide more info.
Thanks.
Related
I'm working on Spring boot Application along with liquibase version 3.5.3, in which I need to configure two different JNDI data source for liquibase task and application execution.
I have created two different JNDI data source in tomcat server.xml file
<Resource name="JDBC/DSAdmin"
global="jdbc/DSAdmin"
auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
jdbcUrl="jdbc:mysql://localhost:3306/dbname"
username="admin"
password="admin"
minimumIdle="5" maximumPoolSize="50" connectionTimeout="300000" maxLifetime="1800000" />
and
<Resource name="jdbc/DS"
global="jdbc/DS"
auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
jdbcUrl="jdbc:mysql://localhost:3306/database"
username="root"
password="root"
minimumIdle="5" maximumPoolSize="50" connectionTimeout="300000" maxLifetime="1800000" />
I need to run the liquibase task using the jdbc/DSAdmin connection pool and application using the jdbc/DS connection pool.
But liquibase version 3.5.3 doesn't provide any property to specify data source by using tomcat server resource.
In application.properties file, I have configured spring.datasource.jndi-name = java:comp/env/jdbc/DSAdmin
Similarly I want to configure liquibase.datasoure=java:comp/env/jdbc/DS
this is my context.xml file
<ResourceLink name="jdbc/DS"
global="jdbc/DS"
auth="Container"
type="javax.sql.DataSource" />
<ResourceLink name="jdbc/DSAdmin"
global="jdbc/DSAdmin"
auth="Container"
type="javax.sql.DataSource" />
I have a sample Spring application for registering the student. I even created a SQLDB Service using Bluemix. I am unable to bind the service in the spring application in Jpacontext.xml.
If someone could please help me in providing the syntax how to call that would really help me.
The following entries in server.xml enabled me to connect my Spring application to SQLDB Service instance running in Bluemix.
I kept db2jcc4.jar and db2jcc_license_cu.jar in shared/db2 folder.
Please look at the credentials for SQLDB instance in Bluemix to get the database instance name, username, password and host ip address.
<jdbcDriver id="DB2JDBCDriver" libraryRef="DB2"/>
<library id="DB2" name="DB2 Shared Library">
<fileset dir="${shared.resource.dir}/db2" includes="*.jar"/>
</library>
<dataSource id='MyDataSource' beginTranForVendorAPIs="false" jdbcDriverRef="DB2JDBCDriver" jndiName="jdbc/MyDataSource" type="javax.sql.DataSource">
<properties.db2.jcc id='MyDataSource-props' currentLockTimeout="10s"
databaseName='<Database instance name>'
password='<password>'
portNumber='50000'
serverName='<host ip address>'
user='<username>'/>
<connectionManager connectionTimeout="10s" maxConnectionsPerThread="10" maxPoolSize="25" minPoolSize="5"/>
</dataSource>
Hope this helps !
I agree, I think we need more information to be of any real value, however, it may be helpful to begin by reviewing the link below which discusses the SQLDB service
https://www.ng.bluemix.net/docs/services/SQLDB/index.html#cli
and the following link which discusses how to bind to a service in Bluemix.
https://www.ng.bluemix.net/docs/services/reqnsi.html#config
If you still have problems after reviewing this material, then please provide a code snippet and the errors you're encountering.
You may refer to sqldb as JNDI resource. See more details on this here:
https://developer.ibm.com/answers/questions/178223/how-to-connect-to-db2-with-spring/
Taken from the link, example:
datasource-config.xml
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/[some-jndi-name-from-server.xml]" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
<bean id="namedParameterJdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:WEB-INF/datasource-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
basically what you need is JNDI name to refer, from server.xml path in your application:
Dashboard -> Your application -> Logs and Files -> app -> .liberty -> usr -> servers -> defaultServer -> server.xml
Than it's possible to refer to your "dataSource" bean in application.
In mule I have many applications running on the same container that access a jdbc connector with the same connection string/user/password set.
Of course any app has configured the same global connector in its xml configuration file, so there is code duplication.
Is there a way to define only once per container the connection and access it from any app?
I would try this: have one app create the datasource and store it in JNDI and have the other apps pick it up from JNDI.
Since there is no strong guarantee of app start ordering, it's possible that one app that needs the JNDI datasource would start too soon. You would need to configure Spring to be able to perform the JNDI lookup again in case of failure and configure a threaded retry policy on the Mule JDBC connector.
Also you will need to install the datasource and database JARs in lib/user so all apps could use them.
Just create a spring bean for your JDBC connector in xml some where in your system and have all your applications load it in your apps:
<spring:import resource="JDBC-beans.xml" />
and the xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<!-- Initialization for data source -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<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="password"/>
</bean>
</beans>
I have solved this kind of problem using a Domain project, where I inserted all database configurations that have been used by other projects.
How can I create JDBCResources, -Pools and Security Realms in a Glassfish 3.1 Server from within my Application, if they are not already created? I am writing an application that relies on this resources, however I don't want to configure the server manually every time the application is deployed on a different server.
Doing this with a shell script feels like a workaround.
Glassfish provides a REST interface. You can create a new security (authentication) realm in a certain configuration (say, server-config in a DAS on localhost, admin port 4848) with a POST to:
http://localhost:4848/management/domain/configs/config/server-config/security-service/auth-realm
Do a GET to that resource to see the parameters.
You can use the same interface to create connection pools.
Ok, I found a solution for half of the Question.
I created a file called glassfish-resources.xml in my WEB-INF folder and added the following content to it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool
name="java:app/jdbc/BeerUserPool"
res-type="javax.sql.DataSource"
datasource-classname="org.postgresql.ds.PGSimpleDataSource"
pool-resize-quantity="2"
max-pool-size="32"
steady-pool-size="0"
statement-timeout-in-seconds="30">
<property name="User" value="USERNAME"></property>
<property name="Password" value="PASSWORD"></property>
<property name="PortNumber" value="12345678"></property>
<property name="dataBaseName" value="DATABASE_NAME"></property>
<property name="ServerName" value="yourDBUrl.com"></property>
<property name="Ssl" value="false"></property>
<property name="ProtocolVersion" value="0"></property>
</jdbc-connection-pool>
<jdbc-resource
pool-name="java:app/jdbc/BeerUserPool"
jndi-name="java:app/jdbc/BeerUser"></jdbc-resource>
<
</resources>
Addingt the java:app/ to the names is important, without it it won't work correctly. This connection pool is also only application scoped and gets destroyed after the application is undebloyed (except you add an additional argument).
This pool can now be accessed with JPA with the following persistence.xml.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="jsf-jpa-war" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:app/jdbc/BeerUser</jta-data-source>
<properties>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
</persistence>
However I found no soultion how I can define the security realms in the same way.
I am not able to find ecbDB JTA data source in the unit test.
For RESOURCE_LOCAL the same persistence.xml works. Only within an EJB container it fails to locate a JTA data source.
I get the following exception when the unit test is executed..
SEVERE: Exception while invoking class org.glassfish.persistence.jpa.JPADeployer prepare method
java.lang.RuntimeException: javax.naming.NamingException: Lookup failed for 'ecbDB' in SerialContext [Root exception is javax.naming.NameNotFoundException: ecbDB not found]
at org.glassfish.persistence.jpa.PersistenceUnitInfoImpl.<init>(PersistenceUnitInfoImpl.java:111)
Here is persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="ecbPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>ecbDB</jta-data-source>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
<property
name="javax.persistence.jdbc.driver"
value="org.apache.derby.jdbc.EmbeddedDriver" />
<property
name="javax.persistence.jdbc.url"
value="jdbc:derby:target/ecbDB;create=true" />
<!-- EclipseLink 2.0 properties -->
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="sql-script" />
<!-- <property name="eclipselink.ddl-generation.output-mode" value="database"
/> -->
<property name="eclipselink.application-location" value="./target/ddl" />
<property name="eclipselink.create-ddl-jdbc-file-name"
value="create.sql" />
<property name="eclipselink.drop-ddl-jdbc-file-name" value="drop.sql" />
<property name="eclipselink.logging.level" value="ALL" />
<property name="eclipselink.logging.file" value="./target/eclipselink.logs" />
</properties>
</persistence-unit>
</persistence>
Here is a step-by-step description I have used to set up JTA based connection with EclipseLink.
First, make sure that:
GlassFish server is up and running
asadmin list-domains
Apache Derby server is up and running
NetworkServerControl.bat sysinfo -h localhost -p 1527
Next, create JDBC Connection Pool and JDBC Resource
create JDBC Connection Pool that uses org.apache.derby.jdbc.EmbeddedDataSource
asadmin create-jdbc-connection-pool
--datasourceclassname org.apache.derby.jdbc.EmbeddedDataSource
--restype javax.sql.XADataSource
--property databaseName=ecbDB:serverName=localhost:portNumber=1527:password=APP: user=APP:connectionAttributes=\;create\=true EmbeddedPool
create JDBC Resource
asadmin create-jdbc-resource --connectionpoolid EmbeddedPool jdbc/EmbeddedResource
If you take a look at GlassFish Administration Console (localhost:4848) you will notice new nodes:
Resources > JDBC > JDBC Connection Pools > EmbeddedPool
Resources > JDBC > JDBC Resources > jdbc/EmbeddedResource
As you can see jdbc/EmbeddedResource has been assigned to EmbeddedPool.
Then, create a minimal version of persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="ecbPU">
<jta-data-source>jdbc/EmbeddedResource</jta-data-source>
<properties>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
</persistence>
Use stateless/stateful session beans as components to manage persistence operations (as far as I know this is the preferred strategy for Java EE applications):
public interface ECBService {
}
#Stateless
public class ECBServiceBean implements ECBService {
#PersistenceContext(unitName = "ecbPU")
protected EntityManager em;
}
Use setter injection to assign environment naming context dependency into a field (useful in case of unit testing):
public class ECBServlet extends HttpServlet {
private ECBService service;
#EJB
public void setECBService(EcbService service) {
this.service = service;
}
}
Finally, deployment produces the following:
INFO: EclipseLink, version: Eclipse Persistence Services - 2.5.0.v20130507
FINE: Detected database platform: org.eclipse.persistence.platform.database.JavaDBPlatform
CONFIG: connecting(DatabaseLogin(
platform=>DatabasePlatform
user name=> ""
connector=>JNDIConnector datasource name=>null
))
CONFIG: Connected: jdbc:derby:ecbDB
User: APP
Database: Apache Derby Version: 10.10.1.1 - (1458268)
Driver: Apache Derby Embedded JDBC Driver Version: 10.10.1.1 - (1458268)
CONFIG: connecting(DatabaseLogin(
platform=>JavaDBPlatform
user name=> ""
connector=>JNDIConnector datasource name=>null
))
CONFIG: Connected: jdbc:derby:ecbDB
User: APP
Database: Apache Derby Version: 10.10.1.1 - (1458268)
Driver: Apache Derby Embedded JDBC Driver Version: 10.10.1.1 - (1458268)
I hope it helps.
First make sure your derby configuration have a suitable JDBC resource (with the shell command "asadmin list-jdbc-resources"). If not, make one with "asadmin create-jdbc-resource". For help type "asadmin list-commands".
Are you running this under embedded Glassfish? If so the problem you are is seeing is because he has a JTA datasource ecbDB is not defined in your domain.xml. In that case Kaster's answer is on the right track and you should create your embedded connection pool and associated JDBC resource. You can use the asadmin command or Glassfish web admin GUI. At that point you should also remove the two javax.persistence.jdbc properties from your persistence.xml because those settings will be convered by your connection pool resource settings.