Connect to Sql Server on liberty using mssql-jdbc - java

I'm trying to connect to a Sql Server database from a liberty server.
Doesn't work as I'm getting a 500 from the liberty server and the logs give me this error message: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: SQL Server did not return a response.
My xml:
<library id="sqlServerLib2" apiTypeVisibility="spec,ibm-api,api,third-party"
<fileset dir="${server.config.dir}/lib/global" includes="mssql-jdbc-6.1.0.jre8.jar"/>
</library>
<dataSource id="myDataSource" jndiName="jdbc/myDataSource">
<jdbcDriver libraryRef="sqlServerLib2"/>
<properties.microsoft.sqlserver
serverName="localhost"
portNumber="8080"
databaseName="my_db"
user="user"
password="password"/>
<connectionManager maxPoolSize="100" minPoolSize="0"/>
</dataSource>
I've looked at IBM's pages. Didn't give much help.
I've also googled the error message but people usually say that I should just update my driver to at least 4.2. I'm using 6.1, so that doesn't really apply.
What am I missing here?
Thanks.
EDIT:
I took a look at Microsoft's pages and found that i was using an incompatible jdbc-api version. I changed this from 4.0 to 4.1.
<featureManager>
<feature>jdbc-4.1</feature>
</featureManager>
I also defined the dataSource and connection pool classes in my datasource.
<jdbcDriver libraryRef="sqlserverLib2"
javax.sql.DataSource="com.microsoft.sqlserver.jdbc.SQLServerDataSource"
javax.sql.ConnectionPoolDataSource="com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource"/>
Now I'm getting a java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDataSource.
I tried using the mssql-jdbc-6.1.0.jre7.jar(java 7) instead. Then all of a sudden i worked. What am I doing wrong with the jre8 version of the driver?

The main error was that I used a version of the jdbc-api that was incompatible with the mssql-jdbc-6.1.0.jre8.jar driver. Changing to version 4.1 fixed it.
The classNotFoundException was just a blunder on my part(forgot to update the pom.xml)

In your example code snippet, you have incorrect syntax for specifying the JNDI name of the data source,
<dataSource id="myDataSource" jndi="jdbc/myDataSource">
This should instead be:
<dataSource id="myDataSource" jndiName="jdbc/myDataSource">

Related

How can I solve reading MQ messages resulting in error on commit/rollback?

While working on getting an MQ connection to work in Liberty, I'm encountering the following problem.
After a message is received, the following error occurs:
JMSCC0014: It is not valid to call the 'commit' method on a nontransacted session.
I've done some searching and found something about needing to use an XA version of the connection factory, but I don't know if that is indeed the solution and I haven't found any clear example of how to achieve that in the configuration I have.
Here is the relevant portion of the server.xml configuration:
<resourceAdapter id="mqJms" location="/etc/liberty/wmq/wmq.jmsra.rar"/>
<authData id="mqJms.auth" user="user" password="password"/>
<jmsQueueConnectionFactory jndiName="jms/queueConnectionFactory" connectionManagerRef="ConMgr4" containerAuthDataRef="mqJms.auth">
<properties.mqJms transportType="CLIENT"
hostName="server" port="1234"
channel="CHANNEL"/>
</jmsQueueConnectionFactory>
<connectionManager id="ConMgr4"
connectionTimeout="30s"
maxPoolSize="50" minPoolSize="1"
reapTime="60s" agedTimeout="0"/>
<jmsQueue id="jms/incomingRequestQueue" jndiName="jms/incomingRequestQueue">
<properties.mqJms baseQueueName="QUEUEIN"/>
</jmsQueue>
The queueConnectionFactory is retrieved through JNDI in the code.
Any help would be greatly appreciated.
The solution was eventually to not do a commit / rollback after receiving an MQ message, see here for more information: Websphere Liberty : JMS Sessions don't work.

IBM MQ How to tell if your JNDI Bindings are LDAP

I'm currently in the process of migrating an application from AIX to LINUX. One of the processes is to install and setup MQ.
I've gotten past setting up the Connection Factory and Activation Spec in my server.xml. My application is connecting to the MQ(which is on the same box). However, it's unable to find my local queue I've defined.
From my reading, it looks like I have to setup matching JMS objects in MQ. However, I cannot find anywhere on the AIX server where there is any configuration for that MQ's JMS.
I can't find a .bindings file anywhere which I believe would tell me that it's a local file. However, LDAP makes sense, because we connect to this MQ from other servers.
Sorry if this seems like a silly question or is easy, but I'm at a loss and cannot move forward with my project until I figure this issue out.
However, here is my server.xml for my connection information just in case anyone sees anything wrong.
<variable name="wmqJmsClient.rar.location" value="${shared.config.dir}/wmq/wmq.jmsra.rar"/>
<jmsQueueConnectionFactory connectionManagerRef="ConnMgr" id="QueueConnectionFactory" jndiName="jms/QueueConnectionFactory">
<properties.wmqJms channel="JAVA.CHANNEL" hostName="10.1.1.45" port="1517" queueManager="MY_QMGR" transportType="CLIENT" userName="appuser" />
</jmsQueueConnectionFactory>
<jmsConnectionFactory connectionManagerRef="ConnMgr" jndiName="jms/QueueConnFactory">
<properties.wmqJms channel="JAVA.CHANNEL" hostName="10.1.1.45" port="1517" queueManager="MY_QMGR" userName="appuser" />
</jmsConnectionFactory>
<connectionManager id="ConnMgr" maxPoolSize="2"/>
<jmsQueue id="Q1" jndiName="jms/Q1">
<properties.wmqJms baseQueueManagerName="MY_QMGR" baseQueueName="Q1"/>
</jmsQueue>
<jmsActivationSpec id="application/APPMessageBean">
<properties.wmqJms destinationRef="Q1" hostName="10.1.1.45" port="1517" queueManager="MY_QMGR" transportType="CLIENT" />
</jmsActivationSpec>
Error I'm getting, this is in the Liberty server console.log. I'm not getting any errors in the MQ AMQERR01.LOG
[ERROR ] J2CA8802E: The message endpoint activation failed for resource adapter wmqJms due to exception: com.ibm.mq.connector.DetailedResourceException: MQJCA0003: A JNDI naming exception was thrown. See the linked exception for details., error code: MQJCA0003 An attempt to look up a JMS destination in the JNDI namespace failed. Either the namespace cannot be accessed, or a destination with the supplied name is not bound in the namespace. See the linked exception for details of the failure. Check that the JNDI namespace is available, that a destination with the correct name is bound in the JNDI namespace, and that the value of the property called destination is correctly defined.
at com.ibm.mq.connector.services.JCAExceptionBuilder.buildException(JCAExceptionBuilder.java:169)
at com.ibm.mq.connector.services.JCAExceptionBuilder.buildException(JCAExceptionBuilder.java:135)
at com.ibm.mq.connector.DestinationBuilder.createDestination(DestinationBuilder.java:238)
at com.ibm.mq.connector.inbound.MessageEndpointDeployment.startDelivery(MessageEndpointDeployment.java:337)
at com.ibm.mq.connector.inbound.MessageEndpointDeployment.<init>(MessageEndpointDeployment.java:230)
at com.ibm.mq.connector.ResourceAdapterImpl.endpointActivation(ResourceAdapterImpl.java:556)
at com.ibm.ws.jca.service.EndpointActivationService.activateEndpoint(EndpointActivationService.java:524)
at [internal classes]
Caused by: javax.naming.NameNotFoundException: Q1
at com.ibm.ws.jndi.internal.ContextNode.lookup(ContextNode.java:218)
at [internal classes]
at javax.naming.InitialContext.lookup(InitialContext.java:423)
at com.ibm.mq.connector.DestinationBuilder.createDestination(DestinationBuilder.java:190)
... 5 more

How to get SSO SAML working on a Liberty Java Application

Could anyone help talk me through how to implement SSO for an application on Bluemix please?
I have a liberty for java application that within the application there is an IBM Admin link within the tool that can be selected and used to have SSO working here, but the version had expired and the creator of this app has since left so I am having to maintain this app and now fix/upgrade the SSO connection for the Admin user. I have re-binded SSO (the newer version) to the app, using SAML. I have been boarded/registered and have completed the details/uploaded the metadata file. Now I really need some advice/help in what can be done to actually get this working so when the IBM Admin selects the link to login, it takes them to the admin version of the tool rather than an error where the SSO is not present currently.
If any details are needed please let me know and will provide.
Server.xmal details:-
enter code here<server>
<featureManager>
<feature>jsf-2.0</feature>
<feature>jsp-2.2</feature>
<feature>servlet-3.0</feature>
<feature>ejbLite-3.1</feature>
<feature>cdi-1.0</feature>
<feature>jpa-2.0</feature>
<feature>jdbc-4.0</feature>
<feature>jndi-1.0</feature>
<feature>managedBeans-1.0</feature>
<feature>jaxrs-1.1</feature>
<feature>icap:managementConnector-1.0</feature>
<feature>appstate-1.0</feature>
<feature>cloudAutowiring-1.0</feature>
<feature>openidConnectClient-1.0</feature>
<feature>ssl-1.0</feature>
<feature>appSecurity-2.0</feature>
</featureManager>
<application name='myapp' location='myapp.war' type='war' context-root='/'/>
<httpEndpoint id='defaultHttpEndpoint' host='*' httpPort='${port}'/>
<webContainer trustHostHeaderPort='true' extractHostHeaderPort='true'/>
<include location='runtime-vars.xml'/>
<logging logDirectory='${application.log.dir}' consoleLogLevel='INFO'/>
<httpDispatcher enableWelcomePage='false'/>
<applicationMonitor dropinsEnabled='false' updateTrigger='mbean'/>
<config updateTrigger='mbean'/>
<appstate appName='myapp' markerPath='${home}/../.liberty.state'/>
<dataSource id='mysql-ClearDB MySQL Database-assessments' jdbcDriverRef='mysql-driver' jndiName='jdbc/ClearDB MySQL Database-assessments' transactional='true' type='javax.sql.ConnectionPoolDataSource'>
<properties id='mysql-ClearDB MySQL Database-assessments-props' databaseName='${cloud.services.ClearDB MySQL Database-assessments.connection.name}' user='${cloud.services.ClearDB MySQL Database-assessments.connection.user}' password='${cloud.services.ClearDB MySQL Database-assessments.connection.password}' portNumber='${cloud.services.ClearDB MySQL Database-assessments.connection.port}' serverName='${cloud.services.ClearDB MySQL Database-assessments.connection.host}'/>
<connectionManager id='mysql-ClearDB MySQL Database-assessments-conMgr' maxPoolSize='10'/>
</dataSource>
<jdbcDriver id='mysql-driver' javax.sql.XADataSource='org.mariadb.jdbc.MySQLDataSource' javax.sql.ConnectionPoolDataSource='org.mariadb.jdbc.MySQLDataSource' libraryRef='mysql-library'/>
<library id='mysql-library'>
<fileset id='mysql-fileset' dir='${server.config.dir}/lib'/>
</library>
<openidConnectClient id='${cloud.services.SSO-Assessments.connection.clientId}' clientId='${cloud.services.SSO-Assessments.connection.clientId}' clientSecret='${cloud.services.SSO-Assessments.connection.secret}' authorizationEndpointUrl='${cloud.services.SSO-Assessments.connection.authorizationEndpointUrl}' tokenEndpointUrl='${cloud.services.SSO-Assessments.connection.tokenEndpointUrl}' redirectToRPHostAndPort='https://AssessmentsSolution-Network.mybluemix.net:443' issuerIdentifier='${cloud.services.SSO-Assessments.connection.issuerIdentifier}' scope='${cloud.services.SSO-Assessments.connection.serverSupportedScope}' httpsRequired='true'/>
<keyStore id='defaultKeyStore' password='changeit' type='jks' location='${java.home}/lib/security/cacerts'/>

Java Hibernate with SQL Server 2012 not working?

I have a Java Hibernate project configuration which worked with SQL Server 2008 R2, now with a new OS 8.1 (from 7) and SQL Server 2012 (express), I'm unable to connect to SQL server.
Relevant configuration which is/should be syntactically correct since it worked with 2008 R2:
datasource.properties
jdbc.driverClassName=net.sourceforge.jtds.jdbc.Driver
jdbc.url=jdbc:jtds:sqlserver://localhost:1433/dbname;instance=SQLEXPRESS
jdbc.username=auser
jdbc.password=xyz
I've tried two dialects org.hibernate.dialect.SQLServerDialect worked in 2008 R2.
hibernate.hbm2ddl.auto=create-drop
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
#hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
hibernate.show_sql=true
springConfiguration.xml
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource">
<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>
SQL Server 2012 was installed with mixed mode authentication and SQL Server Management Studio has no problem connecting (with or without the instance name).
I've updated the SQL Server Network Configuration for SQLEXPRESS.
Protocols for SQLEXPRESS:
TCP/IP Enabled
As well as all of the TCP/IP Properties - TCP Port's to 1433.
I've tried disabling Windows Firewall just to test if it's in the way but it results in the same error.
I ended up adding Firewall rules and following some of the steps in this excellent configure SQL Express 2012 to accept remote connections article.
The error message:
Caused by: java.lang.AbstractMethodError
at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)
Your problem is jTDS does not support the way DBCP2 validates a connection by default (I'm assuming you use DBCP2 from <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource">). See the solution below.
Usually the error stacktrace is as shown:
Caused by: java.lang.AbstractMethodError
at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)
at org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.isValid(DelegatingConnection.java:913)
The problem, though, is not related to the SQL Server version, but to the DBCP (Tomcat) version used (or the Tomcat server version the project is deployed to).
Once I was using jTDS 1.3.1 and the project worked fine (and connected to SQLServer 2012 as well) under Tomcat7. When I changed to Tomcat 8, that error appeared.
The reason, as hinted in jTDS forums, is:
(Tomcat7 uses DBCP 1 and Tomcat 8 uses DBCP 2)
Unlike DBCP 1.x, DBCP 2 will call java.sql.Connection.isValid(int) to validate the connection
jTDS doesn't implement .isValid(), so jTDS driver won't work with DBCP 2, unless...
...unless you set the validationQuery parameter, which will make DBCP not call .isValid() to test the validity of the connection.
Workaround
So, the workaround is to set the validationQuery parameter, which will make DBCP2 not call .isValid() to test the validity of the connection. Here's how:
On Tomcat
Add validationQuery="select 1" to your Tomcat <Resource> tag for connection pool, which is usually in META-INF/context.xml of your app or conf/server.xml:
<Resource ... validationQuery="select 1" />
On Spring
When using DBCP2 through Spring, the solution is something around:
<bean id="..." ...>
...
<property name="validationQuery" value="select 1" />
</bean>
On Simple java Code
dataSource.setValidationQuery("select 1");
It appears that jTDS has some issues with SQL Server 2012 (update 2?) or something has changed in 2012/8.1 which previously worked in 2008 R2/7.
Using nearly the same configuration as above with a couple minor changes, I downloaded and changed the datasource.properties to use Microsoft JDBC Driver 4.0 for SQL Server.
jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://localhost:1433;
#jdbc.url=jdbc:sqlserver://localhost\dbname:1433;
I just put the sqljdbc4.jar in tomcat\lib\ to verify that the MS JDBC driver 4.0 works with SQL Server 2012 with all updates and it works perfectly. The dialect org.hibernate.dialect.SQLServerDialect worked in 2012 too.

JBoss JDBC warning - "Unable to fill pool"

We're getting this random warning from JBoss.. any idea why?
It happens at random times when there are no active threads. Everything works when any processing resumes.
13:49:31,764 WARN [JBossManagedConnectionPool] [ ] Unable to fill pool
org.jboss.resource.JBossResourceException: Could not create connection; - nested throwable: (java.sql.SQLException: Listener ref
used the connection with the following error:
ORA-12516, TNS:listener could not find available handler with matching protocol stack
The Connection descriptor used by the client was:
//localhost:1521/orcl
)
at org.jboss.resource.adapter.jdbc.xa.XAManagedConnectionFactory.createManagedConnection(XAManagedConnectionFactory.java
:144)
at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.createConnectionEventListener(InternalManagedConne
ctionPool.java:577)
at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.fillToMin(InternalManagedConnectionPool.java:524)
at org.jboss.resource.connectionmanager.PoolFiller.run(PoolFiller.java:74)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.SQLException: Listener refused the connection with the following error:
ORA-12516, TNS:listener could not find available handler with matching protocol stack
The Connection descriptor used by the client was:
//localhost:1521/orcl
Update: As per richj's post, here is the format of one of the four data sources we are using:
<xa-datasource>
<jndi-name>ABCOracleDS</jndi-name>
<track-connection-by-tx/>
<isSameRM-override-value>false</isSameRM-override-value>
<xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
<xa-datasource-property name="URL">jdbc:oracle:thin:#//localhost:1521/orcl</xa-datasource-property>
<xa-datasource-property name="User">myuser</xa-datasource-property>
<xa-datasource-property name="Password">mypw</xa-datasource-property>
<min-pool-size>20</min-pool-size>
<max-pool-size>200</max-pool-size>
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter
</exception-sorter-class-name>
<no-tx-separate-pools/>
<metadata>
<type-mapping>Oracle10g</type-mapping>
</metadata>
</xa-datasource>
The Connection descriptor used by the client was:
//localhost:1521/orcl
I think the problem is likely to be somewhere in the datasource definitions.
Do you have more than one datasource definition in your JBoss hot deploy directory?
Are your datasource definitions correct and complete - particularly the properties used to build the connection URL?
Update 1
I'm not sure about the slashes, I think maybe the URL:
jdbc:oracle:thin:#//localhost:1521/orcl
should look like this:
jdbc:oracle:thin:#localhost:1521:orcl
Update 2
Here is a reference from Oracle that supports the syntax with slashes.
Here is a reference from Orafaq that supports the syntax with colons.
Perhaps it's worth a try even if the slashes are legal?
Update 3
Just a few more ideas from the "getting desperate" box of tricks:
ORA-12516: TNS:listener could not find available handler with matching protocol stack
This message looks like a TNS configuration issue. The JDBC thin driver shouldn't need a TNS configuration, but I've found that sometimes it just refuses to work without one.
You could also try the fully qualified host name instead of localhost. Sometimes machine.company.com works when machine on its own doesn't.

Categories

Resources