I'm deploying a working Tomcat webapp on websphere-liberty on docker. The webapp connects to a postgres data source on docker. In websphere when I try to get connection with
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/postgres");
Connection conn = ds.getConnection();
my web.xml is setted as:
<resource-ref>
<description>postgreSQL Connection</description>
<res-ref-name>jdbc/postgres</res-ref-name>
<res-type>javax.sql.XADataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
I get the following error
javax.naming.NamingException: CWNEN1001E: The object referenced by the java:comp/env/jdbc/postgres JNDI name could not be instantiated.
If the reference name maps to a JNDI name in the deployment descriptor bindings for the application
performing the JNDI lookup, make sure that the JNDI name mapping in the deployment descriptor binding is correct.
If the JNDI name mapping is correct, make sure the target resource
can be resolved with the specified name relative to the default initial context.
[Root exception is com.ibm.wsspi.injectionengine.InjectionException: CWNEN0030E: The
server was unable to obtain an object instance for the java:comp/env/jdbc/postgres reference.
The exception message was: CWNEN1004E: The server was unable to find the jdbc/postgres default binding with the javax.sql.XADataSource type for
the java:comp/env/jdbc/postgres reference.]
I exlude that is a problem with docker network. What I have setted wrong? Is something in my websphere-liberty?
server.xml is
<server description="Default server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-7.0</feature>
<feature>adminCenter-1.0</feature>
<feature>jdbc-4.0</feature>
</featureManager>
<quickStartSecurity userName="admin" userPassword="password"/>
<!-- Define the host name for use by the collective.
If the host name needs to be changed, the server should be
removed from the collective and re-joined. -->
<!-- <variable name="defaultHostName" value="localhost" /> -->
<!-- Define an Administrator and non-Administrator -->
<basicRegistry id="basic">
<user name="admin" password="admin" />
<user name="nonadmin" password="nonadminpwd" />
</basicRegistry>
<!-- Assign 'admin' to Administrator -->
<administrator-role>
<user>admin</user>
</administrator-role>
<!-- <keyStore id="defaultKeyStore" password="Liberty" /> -->
<httpEndpoint id="defaultHttpEndpoint"
host="*"
httpPort="9080"
httpsPort="9443" />
<remoteFileAccess>
<writeDir>${server.config.dir}</writeDir>
</remoteFileAccess>
<library id="postgres-lib">
<fileset dir="/arturial/project/" includes="postgresql-9.4.1208.jre6.jar"/>
</library>
<dataSource id="jdbc-Prima_WA_db" jndiName="jdbc/postgres" type="javax.sql.DataSource">
<jdbcDriver libraryRef="postgres-lib"/>
<connectionManager numConnectionsPerThreadLocal="10" id="connectionManager" minPoolSize="1"/>
<!-- <properties.oracle user="postgres" password="postgres" -
url="jdbc:postgres://172.17.0.3:5432/Prima_WA_db"/> -->
</dataSource>
<!--
<applicationManager updateTrigger="disabled"/>
<application id="primawebapp" name="primawebapp" location="war/primawebapp" type="war">
<classLoader delegation="parentLast" commonLibraryRef="postgres-lib"/>
</application>
-->
</server>
Try this;
DataSource ds = (DataSource)ctx.lookup("jdbc/postgres");
Also, a different way.
Your <datasource> must have properties configured under it, otherwise there is no way for Liberty to know how to connect to your database.
For postgresql, try the following configuration:
<dataSource id="jdbc-Prima_WA_db" jndiName="jdbc/postgres">
<jdbcDriver libraryRef="postgres-lib"/>
<properties serverName="172.17.0.3" portNumber="5432" databaseName="Prima_WA_db"
user="postgres" password="postgres"/>
</dataSource>
Of course, using the proper values that correspond to the postgresql instance that you are running on.
Looks like your datasource definition might be incomplete, try updating it with the following:
<dataSource type="javax.sql.XADataSource" ...
<jdbcDriver javax.sql.XADataSource="org.postgresql.xa.PGXADataSource" ...
Related
we are getting below exception in liberty running in linux box for jax-rs based web service application. But while running in local windows version Liberty (21.0.0.6) , it works fine and no exception thrown. Also we tried various option available in stack overflow and google, nothing worked. can anyone help us on this
E SRVE0271E: Uncaught init() exception created by servlet [JAX-RS Servlet] in application [ABC_WSv2.1]: java.lang.ClassCastException: com.abc.occws.SearchingApplication incompatible with javax.ws.rs.core.Application
server.xml configuration below
<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-8.0</feature>
</featureManager>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint" />
<dataSource id="ABCDataSource" jndiName="jdbc/ABCDS" queryTimeout="20m" type="javax.sql.DataSource">
<connectionManager agedTimeout="1000m" minPoolSize="1" numConnectionsPerThreadLocal="10"/>
<jdbcDriver libraryRef="OracleLib"/>
<properties.oracle URL="jdbc:oracle:thin:#//10.135.157.5:1565/DOABC_APP" password="xxx" user="xxxx"/>
</dataSource>
<!-- Define JDBC Drivers -->
<library id="OracleLib">
<file name="C:/dev/Liberty/ojdbc8-19.3.0.0.jar"/>
</library>
<applicationMonitor updateTrigger="mbean" />
<application id="ABC_WSv2.1" location="C:\Dev\Liberty\ABC_WSv2.1.ear" name="ABC_WSv2.1" type="ear" context-root="/abc-ws">
<classloader commonLibraryRef="OracleLib"/>
</application>
<webContainer uppressHtmlRecursiveErrorOutput="true"/>
</server>
On the surface this looks like this problem is classloader related. On Windows I suspect you are running this application is isolation whereas on Linux it is running in concert with other things and likely Parent-Last classloading is involved.
I would suggest collecting Liberty classloader trace to see where the affected classes are being loaded from. Here are some instructions for doing that: Liberty Classloader Mustgather
Note: This is assuming that you are running the same version of your application on both Windows and Linux and in both cases your application class extends javax.ws.rs.core.Application. If that is not the case then that is certainly causing the problem.
I have an application on Tomcat. It uses mysql for persistence. I define the mysql connection related data in context.xml as follows:
<Context>
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<!-- Uncomment this to enable Comet connection tacking (provides events
on session expiration as well as webapp lifecycle) -->
<!--
<Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-->
<Resource
auth="Container"
description="User database that can be updated and saved"
name="jdbc/VTREProto"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
removeAbandoned="true"
username="vtreapp"
password="vtre!##$%"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/developermodule"
/>
</Context>
I access this in my java code as:
InitialContext initCTX = new InitialContext();
// Lookup the DataSource, which will be backed by a pool
// that the application server provides.
pool = (DataSource)initCTX.lookup("java:comp/env/jdbc/VTREProto");
I want to migrate to JBoss EAP 7.0.0. how and where do I specify the above resource in JBoss EAP 7.0.0 without breaking my java code.
Thanx and regards
In JBoss you don't need a context.xml.
You only need to create a datasource in configuration file: (standalone.xml or domain.xml) accordingly to the mode you are running JBoss.
I suggest you change the jndi name as well to the default "java:jboss/datasources/VTREProto" for example. Instead of "java:comp/env/jdbc/VTREProto".
An example of mysql datasource :
<datasources>
<datasource jndi-name="java:jboss/datasources/VTREProto" pool-name="VTREProtoDS">
<connection-url>jdbc:mysql://localhost:3306/jbossdb</connection-url>
<driver>mysql</driver>
<security>
<user-name>admin</user-name>
<password>admin</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
<validate-on-match>true</validate-on-match>
<background-validation>false</background-validation>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
</validation>
</datasource>
More details on official documentation.
We are in the process of moving from Glassfish to WildFly. In Glassfish we setup our LDAP server and use it for authentication and we also reference it with JNDI for us within the application for things such as searching users, etc. I am wondering if there is a way to setup the LDAP connection in the standalone.xml file in WildFly for reference via JNDI in the application like we currently do. I have setup LDAP for authentication and that works but I do not know how to reference that connection for use in our application.
In Wildfly you can use Naming Subsystem for binding a Ldap context, in particular External Context Federation binding type:
External Context Federation
Federation of external JNDI contexts, such as a LDAP context, are
achieved by adding External Context bindings to the global bindings
configuration, through the external-context XML element
For example:
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<bindings>
<external-context name="java:global/federation/ldap/example" class="javax.naming.directory.InitialDirContext" module="org.jboss.as.naming" cache="true">
<environment>
<property name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory" />
<property name="java.naming.provider.url" value="ldap://ldap.example.com:389" />
<property name="java.naming.security.authentication" value="simple" />
<property name="java.naming.security.principal" value="uid=admin,ou=system" />
<property name="java.naming.security.credentials" value="secret" />
</environment>
</external-context>
</bindings>
<remote-naming/>
</subsystem>
Ref: WildFly 8
- Naming Subsystem Configuration
I hope this help.
We are experimenting with IBM's WebSphere Liberty profile. Now we have trouble to connect to our WebSphere MQ server. It works for normal WebSphere profile. We followed this tutorial https://developer.ibm.com/wasdev/2013/06/14/using-websphere-mq-with-the-liberty-profile/ and I ran into the following Exception:
Stack Dump = java.lang.ClassNotFoundException: com.ibm.mq.jms.MQQueue
Any idea what I could change, so that this class could be found?
I am working with Liberty Profile, version 8.5.5.3.
my server.xml looks the following:
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>jsf-2.0</feature>
<feature>jpa-2.0</feature>
<feature>jndi-1.0</feature>
<feature>localConnector-1.0</feature>
<feature>beanValidation-1.0</feature>
<feature>wasJmsClient-1.1</feature>
<feature>jaxws-2.2</feature>
<feature>jmsMdb-3.1</feature>
</featureManager>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443" />
<application id="myapp" name="myApp" type="ear" location="d:\somehwere">
<classloader delegation="parentLast" commonLibraryRef="global" />
</application>
<variable name="wmqJmsClient.rar.location" value="D:\opt\was_liberty_profile\was_8_5_5_3\wlp\usr\shared\wmq\wmq.jmsra.rar"/>
<library id="global">
<file name="d:/dev/mavenrepo/com/h2database/h2/1.4.181/h2-1.4.181.jar" />
</library>
<jmsQueue id="MYAPP_QUEUE" jndiName="jms/test/testq">
<properties.wmqJms
baseQueueName="MYAPP.TEST.A"
persistence="PERS"
targetClient="MQ"/>
</jmsQueue>
<jmsQueueConnectionFactory id="TEST.SVRCONN.001" jndiName="jms/test/testcf"><!-- connectionManagerRef="ConMgr2">-->
<properties.wmqJms
channel="WM026D.SVRCONN.001"
hostName="i19328.myhost.ch"
port="1439"
queueManager="WM026D"
targetClientMatching="false"/>
</jmsQueueConnectionFactory>
<jmsActivationSpec id="fvtapp/fvtmdb/FVTMessageDrivenBean">
<properties.wmqJms destinationRef="MYAPP_QUEUE"
destinationType="javax.jms.Queue"
queueManager="WM026D"/>
</jmsActivationSpec>
</server>
You have the wrong feature there. It should be:
<feature>wmqJmsClient-1.1</feature>
not:
<feature>wasJmsClient-1.1</feature>
the later one is for built in messaging not MQ.
I've always used Spring's dependency injection to get datasource objects and use them in my DAOs, but now, I have to write an app without that.
With Spring I can write something like this:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1/app?characterEncoding=UTF-8" />
<property name="username" value="u" />
<property name="password" value="p" />
</bean>
But how can I use datasource in my DAOs without Spring or anything? I'm using servlets and JSPs only. Performance is very important factor.
Believe it or not, people were writing applications before Spring and some are still not using it :) In your case, you could use Tomcat connection pool (and there is a complete configuration example for MySQL in the documentation). Let me summarize it:
First, put your driver in $CATALINA_HOME/lib.
Then, configure a JNDI DataSource in Tomcat by adding a declaration for your resource to your Context:
<Context path="/DBTest" docBase="DBTest"
debug="5" reloadable="true" crossContext="true">
<!-- maxActive: Maximum number of dB connections in pool. Make sure you
configure your mysqld max_connections large enough to handle
all of your db connections. Set to -1 for no limit.
-->
<!-- maxIdle: Maximum number of idle dB connections to retain in pool.
Set to -1 for no limit. See also the DBCP documentation on this
and the minEvictableIdleTimeMillis configuration parameter.
-->
<!-- maxWait: Maximum time to wait for a dB connection to become available
in ms, in this example 10 seconds. An Exception is thrown if
this timeout is exceeded. Set to -1 to wait indefinitely.
-->
<!-- username and password: MySQL dB username and password for dB connections -->
<!-- driverClassName: Class name for the old mm.mysql JDBC driver is
org.gjt.mm.mysql.Driver - we recommend using Connector/J though.
Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver.
-->
<!-- url: The JDBC connection url for connecting to your MySQL dB.
-->
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest"/>
</Context>
Declare this resource in your web.xml:
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
And get the datasource with a JNDI lookup in your application:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
Note that such lookup is usually coded in a ServiceLocator (when you can't have a a DI container or a framework inject it for you).
I used to get error with sybase, I had missing META-INF folder in WebContent folder. Putting context.xml in that fixed the error Cannot create JDBC driver of class '' for connect URL 'null'...
// www.abbulkmailer.com
My context.xml looks like
<Context path="/reports" docBase="reports" debug="5" reloadable="true" crossContext="true">
<Resource name='jdbc/ASCSybaseConnection'
auth='Container'
type='javax.sql.DataSource'
username='fdd'
password='555'
driverClassName='com.sybase.jdbc2.jdbc.SybDriver'
maxActive='100'
maxIdle='100'
minIdle='10'
removeAbandoned="true"
removeAbandonedTimeout="60"
testOnBorrow="true"
logAbandoned="true"
url='jdbc:sybase:Tds:1.3.4.5:654/DB'/>
</Context>
You can declare your data source as a JNDI object and retrieve a datasource via a JNDI lookup:
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");
as documented here and here.
That's as bare-bones as you can get, so from there on, performance is completely up to you.