How I can use FlexyPool with HikariCPFactory? - java

I want measure metrics on my datasource comparing HikariCP and C3pO.
I don’t understand how I can use FlexyPool in my project.
I have Tomcat context.xml and HikariCP:
<Resource name="jdbc/dictionaryDB"
auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver"
jdbcUrl="jdbc:postgresql://localhost:5432/deversdb"
username="user"
password="pass"
maxActive="8"
maxIdle="4"/>
Please help me, i’am very newbie in connection pooling theme. What I must to do with this https://github.com/vladmihalcea/flexy-pool/wiki/HikariCP-Configuration ?

Since you already have a DataSource that is provided via JNDI, you could try to use the Java EE installation mode.
For this, you need a flexy-pool.properties configuration file on your classpath root, which must contain the following properties:
flexy.pool.data.source.unique.name=some-unique-name
flexy.pool.data.source.jndi.name=jdbc/dictionaryDB
flexy.pool.metrics.reporter.jmx.auto.start=true
As dependencies, you need:
<dependency>
<groupId>com.vladmihalcea.flexy-pool</groupId>
<artifactId>flexy-java-ee</artifactId>
<version>${flexy-pool.version}</version>
</dependency>

Related

Different resources from context.xml for maven profiles

I have an application running on a tomcat 8 which is working fine. Now I want to build the application for a development, a test and a production environment where the application connects to different database servers and I would like to select which resource to use by a maven property set in the different profiles.
So in my context.xml I have defined my data sources looking like this for each DB server.
<Resource name="jdbc/db-dev" auth="Container"
type="javax.sql.DataSource" maxTotal="1000" maxIdle="30"
maxWaitMillis="10000" username="user" password="password"
driverClassName="org.mariadb.jdbc.Driver"
url="jdbc:mariadb://x.x.x.x:3306/dbname;" />
<Resource name="jdbc/db-test" auth="Container"
type="javax.sql.DataSource" maxTotal="1000" maxIdle="30"
maxWaitMillis="10000" username="user" password="password"
driverClassName="org.mariadb.jdbc.Driver"
url="jdbc:mariadb://x.x.x.x:3306/dbname;" />
And in my web.xml
<resource-ref>
<description>DB Connection</description>
<res-ref-name>${db.context}</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
And in my pom.xml
<profile>
<id>dev</id>
<properties>
<db.context>jdbc/db-dev</db.context>
</properties>
</profile>
And in Java
try {
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup(ENV);
DataSource ds = (DataSource) envContext.lookup("jdbc/db"); // jdbc/db-??? is the issue
return ds.getConnection();
} catch (NamingException e) {
throw new SQLException(e);
}
And there's the problem, in Java I have a fixed string value pointing to only one resource. I know I could create a properties file during build, but for only that one value it seems a little to much. Is there a way to have the resource-ref point to different resources from the context xml while having only one reference name?
Another method I found was to have different resource files which I can include and exclude probably per profile, haven't got into it that much yet but maybe there is a far more easy solution which I just don't see right now.
I would prefer to have the same binaries (i.e. WAR in this case) for every environments in order to follow "Build one, deploy often" CI/CD principle. The environment dependent configurations will then be injected in some ways such as through environment variables ,JVM options when starting the application or external configuration file etc.
From this , Tomcat supports using ${xxxx} for variable substitution in their configuration file :
Tomcat configuration files are formatted as schemaless XML; elements
and attributes are case-sensitive. Apache Ant-style variable
substitution is supported; a system property with the name propname
may be used in a configuration file using the syntax ${propname}. All
system properties are available including those set using the -D
syntax, those automatically made available by the JVM and those
configured in the $CATALINA_BASE/conf/catalina.properties file.
So, context.xml will probably looks likes:
<Resource name="jdbc/db" auth="Container"
type="javax.sql.DataSource" maxTotal="1000" maxIdle="30"
maxWaitMillis="10000" username="${DB_USER}" password="${DB_PASSWORD}"
driverClassName="org.mariadb.jdbc.Driver"
url="jdbc:mariadb://${DB_HOST}/dbname;" />
Then configure ${DB_USER} , ${DB_PASSWORD} and ${DB_HOST} as an environment variables or JVM options when starting tomcat etc....

DBCP Datasource invalid Tomcat 8, MySQL, Ubuntu 16.04

I've been fighting with this for a while now... I built a new server and am upgrading an app for current versions. Works fine now in Eclipse. But I can't get the new server right.
Using Tomcat 8.5.8, Ubuntu 16.04 server, OpenJDK 1.8.0_111, mysql-connector-5.1.40, mysql-server 5.7
I'm using the generic Tomcat downloaded in /opt/tomcat and the mysql-connector-java.jar is in /opt/tomcat/lib - and not in the app's lib. Works as a server just fine but I can't seem to connect to the database. However, in Eclipse it does on my dev box.
I have updated the Context resource as per the new Tomcat 8 docs. See below - taken mostly from the docs. At least it's not the same as what I had for Tomcat 7. That generated tons of warnings.
I understand the DBCP implementation changed. And I am pretty sure I am using the new one. I suspect I have the wrong version of a jar somewhere. But it should be pretty vanilla as it's a clean install.
Previously I tried offical Ubuntu Tomcat 8 as installed by apt. But that did the same thing. And had many more strange warnings due to the package seemingly missing stuff.
Any help will be most appreciated.
What I get is this:
24-Nov-2016 16:14:36.870 SEVERE [http-nio-8080-exec-1] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [jsp] in context with path [] threw exception [javax.servlet.ServletException: javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.lang.NullPointerException"] with root cause
javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.lang.NullPointerException"
at org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.getConnection(QueryTagSupport.java:285)
at org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.doStartTag(QueryTagSupport.java:168)
at org.apache.jsp.index_jsp._jspx_meth_sql_005fquery_005f0(index_jsp.java:269)
at org.apache.jsp.index_jsp._jspx_meth_c_005fif_005f0(index_jsp.java:231)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:159)
Based on this:
<Context docBase="app" path="/" reloadable="true" crossContext="true">
<Resource name="jdbc/appdb" username="root" password="password"
url="jdbc:mysql://127.0.0.1:3306/app?autoReconnect=true&zeroDateTimeBehavior=convertToNull&jdbcCompliantTruncation=false&useOldAliasMetadataBehavior=true&useSSL=false"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100"
minIdle="10"
maxWait="10000"
initialSize="10"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="60000"
jmxEnabled="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
driverClassName="com.mysql.jdbc.Driver"
/>
</Context>

Loading JDBCRealm driver jar from WEB-INF/lib instead of tomcat/lib

I'm having a similar issue here:
Configuring jdbcRealm in context.xml
Example configuration - My realm is nested in the context because I want it to be specific to the web application.
<Context>
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="9"
connectionName="username"
connectionPassword="password"
connectionURL="url"
driverName="com.ibm.db2.jcc.DB2Driver"
roleNameCol="PERMISSION"
userCredCol="PASSWORD"
userNameCol="USERID"
userRoleTable="ROLESTABLE"
userTable="USERSTABLE"/>
</Context>
The solution was to put the driver jar into tomcat/lib folder. If I put the db2 driver jar in that folder it works.
However, I would like to load the jar from the application/WEB-INF/lib so that I don't have to make changes to the Tomcat installation. The jar is there, but the authenticator can't seem to locate it.
Thanks!
After tinkering around, I found a solution. The DB is resourced and the realm references that resource instead of specifying the JDBCRealm itself. The following context.xml goes in the META-INF folder of the web app.
<Context>
<Resource name="jdbc/DBNAME"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.commons.dbcp.BasicDataSourceFactory"
maxActive="25"
maxWait="30000"
username="USERNAME"
password="PASSWORD"
driverClassName="DRIVER"
url="URL"
removeAbandoned="true"
logAbandoned="true"
validationQuery="select * from test"
testOnBorrow="true"
testWhileIdle="true"
timeBetweenEvictionRunsMillis="1800000"
/>
<Realm className="org.apache.catalina.realm.DataSourceRealm"
dataSourceName="jdbc/DBNAME"
localDataSource="true"
roleNameCol="PERMISSION"
userCredCol="PASSWORD"
userNameCol="USERID"
userRoleTable="ROLESTABLE"
userTable="USERSTABLE"/>
</Context>
Thanks!

not able to deploy, context file broken

i used tomcat 7 and netbeans 7.4
when i start my web application i get
Cannot deploy the module. The context.xml file seems to be broken. Check whether it is well-formed and valid.
The module has not been deployed.
it's my context.xml file
<?xml version='1.0' encoding='utf-8'?>
<Context>
<Resource name="jdbc/shareDS" auth="Container" type="javax.sql.DataSource"
maxActive="50" maxIdle="10" maxWait="100000"
username="${db.user}" password="${db.password}" driverClassName="com.mysql.jdbc.Driver"
url="${db.url}"
timeBetweenEvictionRunsMillis="1800000" autoReconnect="true"
removeAbandoned="true" removeAbandonedTimeout="300" logAbandoned="true"/>
</Context>
when i try to validate my context file, i get
Cannot find the declaration of element 'Context'. [19]
any idea?
Figured it out. The Netbeans deployment process wants you to add 1 simple parameter to the Context tag, namely: path. It needs to know what path the application will be on.
For example, this was my (opening) Context tag:
<Context antiJARLocking="true" path="/sas/">
My application is deployed at the /sas/ context root.
And now, Netbeans deploys my application without any further errors.
FYI: the antiJARLocking is something I put in to avoid locking of JAR's. It's not mandatory.
For more information on the antiJARLocking, refer to the documentation over at: http://tomcat.apache.org/tomcat-7.0-doc/config/context.html

Issue with JNDI resource with Tomcat 6 on Linux with WAR file

I'm fairly new to Tomcat and Java web development and am banging my head against a wall with an issue im experiencing.
I have a web application that works fine on my local box (windows xp), I have Tomcat 6 installed with the WAR file deployed to the webapps folder and within the c:/apache-tomcat-6.0.18/conf/Catalina/localhost/ directory i have the "myApp.xml".
The myApp.xml contains the following:
<Context path="/myApp" docBase="/myApp.war" debug="1" reloadable="true" cookies="true">
<Resource name="jdbc/sql-connection" scope="Shareable" type="javax.sql.DataSource" auth="Container" username="test" password="test" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverClassName="net.sourceforge.jtds.jdbc.Driver" url="jdbc:jtds:sqlserver://xxxx:xxxx;appName=myApp" removeAbandoned="true" logAbandoned="true" />
</Context>
Then within my web app i have the following info within my applicationContext file
<bean id="myDatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/sql-connection</value>
</property>
</bean>
Now i've gone from it all working fine on my local box to deploying it on a Linux box, however when I deploy it on there, with exactly the same setup just tomcat is running from "opt/apache-tomcat-6.0.18". Every time I try to start Tomcat on the box it will unpack the WAR file but wont start it, and gives me the following error whenever i try to start it through the manager:
Error creating bean with name 'myDatasource' defined in file [/opt/apache-tomcat-6.0.18/webapps/myApp/WEB-INF/classes/applicationContext.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
Ive tried looking all over the internet for an answer but nothing seems to have the exact same issue, and the names seem to match between the tomcat config file and the web app.
First of all, Tomcat doesn't understand myApp.xml (unless you explicitly points it to it, which I don't know how). Tomcat works based on context, which can be configured for your web application. Tomcat allows only deployment of Web Aplication Archive (WAR) file.
To create a context for your application, create a context.xml (all small caps, case-sensitive) file inside your Web application META-INF folder.
Your reference guide to configuring context can be found on Tomcat 6 Config/Context. You will see that attribute debug is deprecated.
The JNDI Resources HOW-TO for Tomcat 6 is also available.
Once you have created your context.xml inside your META-INF folder, paste the following code (taken from your example) below:
<Context path="/myApp" docBase="/myApp.war" reloadable="true" cookies="true">
<Resource name="jdbc/sql-connection" type="javax.sql.DataSource" auth="Container" username="test" password="test" driverClassName="net.sourceforge.jtds.jdbc.Driver" url="jdbc:jtds:sqlserver://xxxx:xxxx;appName=myApp" removeAbandoned="true" logAbandoned="true" />
</Context>
(By default, Tomcat uses PoolableDataSource for Connection Pooling).
Once you're done, config your <resource-env-ref> in your WEB-INF/web.xml. That will allow you to create Shareable scope. Please refer to the link provided on Tomcat 6 JNDI, HOW-TO.
I hope this helps you.

Categories

Resources