how to unwrap PostgreSQL connection from the IBM WSJdbc41Connection - postgresql

I have been trying to unwrap PostgreSQL connection from the IBM JNDI (WebSphere liberty ) and have had no luck please any help with that :
Context ctx = new InitialContext();
DataSource dataSource = (DataSource) ctx.lookup("jdbc/indi");
Connection cnx = dataSource.getConnection();
I get this exception :
java.lang.ClassCastException:
com.ibm.ws.rsadapter.jdbc.v41.WSJdbc41Connection cannot be cast to
org.postgresql.PGConnection
I tried :
if(cnx.isWrapperFor(PGConnectionPoolDataSource.class)) {
//unwrap
}
if (cnx.isWrapperFor(org.postgresql.ds.jdbc4.AbstractJdbc4SimpleDataSource.class)) {
//unwrap
}
if (cnx.isWrapperFor(org.postgresql.core.v3.ConnectionFactoryImpl.class)) {
//unwrap
}
if (cnx.isWrapperFor(org.postgresql.jdbc2.AbstractJdbc2Connection.class)) {
//unwrap
}
if (cnx.isWrapperFor(org.postgresql.jdbc3.AbstractJdbc3Connection.class)) {
//unwrap
}
Thanks

If you would like to unwrap a JDBC object (DataSource, Connection, etc) to a vendor-specific interface, the JDBC driver in the configured <datSource> must be available to the application classloader. The configuration will look something like this:
<application location="oraclejdbcfat.war" >
<!-- expose the 'DBLib' containing the JDBC driver jar to the app classloader -->
<classloader commonLibraryRef="DBLib"/>
</application>
<library id="DBLib">
<fileset dir="${server.config.dir}/postgresql/" includes="*.jar"/>
</library>
<dataSource jndiName="jdbc/myDS">
<jdbcDriver libraryRef="DBLib"/>
<properties .../>
</dataSource>
From there, you can unwrap the object in the same way you were doing before, namely:
DataSource ds = InitialContext.doLookup("jdbc/myDS");
Connection conn = ds.getConnection();
PGConnection pgConn = conn.unwrap(org.postgresql.PGConnection.class);
Also, there is an enableConnectionCasting boolean attribute on <dataSource> configuration which will automatically call unwrap for you upon getConnection().
<dataSource jndiName="jdbc/myDS" enableConnectionCasting="true">
Then the java code is a bit simpler:
DataSource ds = InitialContext.lookup("jdbc/indi");
PGConnection pgConn = (PGConnection) ds.getConnection();

Related

Liberty class loading issues or problem with hibernate (migrating tomcat app on liberty)?

i have to deploy a multi-module application in ear on Liberty Server 20 in my Eclipse. This application use hibernate as provider jpa2 and Derby client + driver derby-10.12.1.1.jar(as shared fileset). Persistence.xml is configured with non jta.
This is server.xml:
<enterpriseApplication id="rubrica-ear" location="rubrica-ear.ear" name="rubrica-ear"/>
<dataSource jndiName="jdbc/TestappDS" type="javax.sql.ConnectionPoolDataSource">
<properties.derby.client createDatabase="false" databaseName=".rubrica"></properties.derby.client>
<jdbcDriver>
<library>
<fileset dir="C:\programmiMio\java-eclipse\drivers" id="shared"></fileset>
</library>
</jdbcDriver>
</dataSource>
My .rubrica db location is in /usr/home.
Because I dont want to start a server derby on console but automatically, i do taht in a #WebListener class:
#WebListener
public class ReqListener implements ServletContextListener {
static final Logger log = LoggerFactory.getLogger(ReqListener.class);
PrintWriter pw = new PrintWriter(System.out);
private NetworkServerControl derbyserver;
#Override
public void contextInitialized(ServletContextEvent arg0) {
try {
String userHomeDir = System.getProperty("user.home", ".");
String systemDir = userHomeDir + "/.rubrica";
// Set the db system directory and startup Server Derby for incoming connections.
System.setProperty("derby.system.home", systemDir);//il db viene salvato qui
derbyserver = new NetworkServerControl(InetAddress.getByName("localhost"), 1527);
derbyserver.start(pw);
log.info("Apache derby settings ok");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error(e.getMessage());
}
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
if (derbyserver!=null){
...
}
}
When i deploy i get this error
[ERROR] An error occurred in the org.hibernate.ejb.HibernatePersistence persistence provider when attempting to create the entity manager factory of the testapp persistence unit container. The following error occurred: java.lang.NullPointerException
at org.hibernate.engine.jdbc.spi.TypeInfo.extractTypeInfo(TypeInfo.java:128)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:163)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:152)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:67)
at com.ibm.ws.jpa.management.JPAPUnitInfo.createEMFactory(JPAPUnitInfo.java:919)
at [internal classes]
When I debug on Liberty i see that Hibernate classes running before the #WebListener code (this is not the same thing in Tomcat), how can i resolve this issue? Something about class loading settings?
I try derby Embedded instead, but problem still araise again, in server.xml:
<properties.derby.embedded createDatabase="create" databaseName="C:/Users/myuser/.rubrica" shutdownDatabase="false"/>
<jdbcDriver>
<library>
<fileset dir="C:\programmiMio\java-eclipse\drivers" id="shared-libs"/>
</library>
</jdbcDriver>
Thanks
Roberto

Cannot find datasource in Java Adapter in IBM MobileFirst

I have created a DataSource in MobileFirst server.xml:
<dataSource jndiName="jdbc/QAIWDB2">
<jdbcDriver libraryRef="DB2Lib"/>
<properties databaseName="QAIWPRD" password="pass" portNumber="99999" serverName="xyz.com" user="user"/>
</dataSource>
When I am trying to access it from a Java Adpater I am getting an error while deploying the adapter
Adapter deployment failed: An object could not be obtained for name
jdbc/QAIWDB2.
The code in Java Adapter is
static DataSource ds = null;
static Context ctx = null;
public static void init() throws NamingException {
ctx = new InitialContext();
ds = (DataSource)ctx.lookup("jdbc/QAIWDB2");
}
Try the DB2 JNDI definition proposal mentioned in this answer: https://stackoverflow.com/a/17851124/1530814.
Of course, change the values to yours...
<dataSource jndiName="jdbc/db2" type="javax.sql.DataSource">
<jdbcDriver>
<library>
<fileset dir="/usr/lib/java/ibm-db2-universal-driver" includes="db2jcc4.jar, db2jcc_license_cisuz.jar, db2jcc_license_cu.jar"/>
</library>
</jdbcDriver>
<properties databaseName="DB2T" portNumber="21020" serverName="db2t.lvm.de password=" ... " user=" ... "/>
</dataSource>

Spring MVC - nested exception is java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: relation "userid" does not exist

I am making a simple spring MVC application that takes data from a view and sends it to a PostgreSQL database on my machine. I have been following tutorials and am not completely familiar with the bean configuration style of handling connection settings in the Data Access Objects. The error that returns when I attempt to post to the database is as follows:
HTTP Status 500 - Request processing failed; nested exception is java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: relation "userid" does not exist
"userid" is my simple postgre table I'm using for testing.
My spring bean configuration file is this:
<?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.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/postgres" />
<property name="username" value="postgres" />
<property name="password" value="kittens" />
</bean>
This is the DAO handling the connection to the DB:
package com.ARSmvcTest.dao.impl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.ARSmvcTest.dao.arsDAO;
import com.ARSmvcTest.models.ARS;
public class JDBCarsDAO implements arsDAO {
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void insert(ARS ars){
String sql = "INSERT INTO UserID " +
"(ID_, First_, Last_, Email_, Pwd_) VALUES (?, ?, ?, ?, ?)";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, ars.getID_());
ps.setString(2, ars.getFirst_());
ps.setString(3, ars.getLast_());
ps.setString(5, ars.getPwd_());
ps.setString(4, ars.getEmail_());
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {}
}
}
}
// FIND ARS BY ID WILL GO HERE EVENTUALLY
}
The spring bean is passing data to the connection successfully as evidenced by this screenshot below:
http://i.imgur.com/Hb7O5Qi.png (apologies, new user and can't embed images)
Despite the dataSource object receiving connection properties from my above spring bean, I notice that the ConnectionProperties field is still null.
Is this what is causing my exception on the Insert attempt?
Lastly I will include a screenshot of the Exception and stack being displayed in browser at the moment of failure:
http://i.imgur.com/prj1HtY.png (apologies, can't embed images)
this exception is directly triggered from the database(-driver).
It tells you that the table named "userid" is not existing.
Please check:
the table name on database and your insert-statement
if the table is read and writabled for the user you use for your connection; you need to have grated the correct right to be able to see and write to the table
I hope this will help you as this seems to be the typical error for this kind of exception.

How to connect JBoss 7.1.1 remoting -jmx via java code?

I have a JBoss 7.1.1 server, for which I want to write jmx client. As far I understood, jboss 7.1.1 is not using typical rmi based jmx and they have given a layer of remoting-jmx over native management. I am using following code:
JMXServiceURL address = new JMXServiceURL("service:jmx:remoting-jmx://localhost:9999");
Map env = JMXConnectorConfig.getEnvironment(paramtbl);
JMXConnector connector = JMXConnectorFactory.connect(address, env);
But it is giving following exception:
java.net.MalformedURLException: Unsupported protocol: remoting-jmx
I googled it and the following thread seems relevant:
https://community.jboss.org/thread/204653?tstart=0
It asks to add jboss's libraries to my classpath. I tried that also but still getting same exception.
I got the same exception when trying to get a JmxServiceUrl.
Make sure that in your standalone.xml you have the following:
<subsystem xmlns="urn:jboss:domain:jmx:1.1">
<show-model value="true"/>
<remoting-connector use-management-endpoint="true" />
</subsystem>
And you should include in project classpath the jar named: jboss-client.jar, it can be found in JBOSS_DIRECTORY/bin/client. In fact, the JMX client must include that jar in its classpath.
This tip fixed the problem for me..Hope it will be helpful for you
Tried to do the same from Arquillian test on JBoss AS7 and finally had to use:
import org.jboss.remotingjmx.RemotingConnectorProvider;
RemotingConnectorProvider s = new RemotingConnectorProvider();
JMXConnector connector = s.newJMXConnector(url, credentials);
connector.connect();
Could not have "module name="org.jboss.remoting-jmx" services="import"" working
Also works with
environment.put("jmx.remote.protocol.provider.pkgs", "org.jboss.remotingjmx");
JMXConnector connector = JMXConnectorFactory.connect(url, environment);
connector.connect();
I used this code to connect to JBoss in a remote server
ModelControllerClient client = null;
try {
client = createClient(InetAddress.getByName("172.16.73.12"), 9999,
"admin", "pass", "ManagementRealm");
}
catch (UnknownHostException e) {
e.printStackTrace();
}
Where createClient is a method I wrote -
private ModelControllerClient createClient(final InetAddress host,
final int port, final String username, final String password,
final String securityRealmName) {
final CallbackHandler callbackHandler = new CallbackHandler() {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (Callback current : callbacks) {
if (current instanceof NameCallback) {
NameCallback ncb = (NameCallback) current;
ncb.setName(username);
} else if (current instanceof PasswordCallback) {
PasswordCallback pcb = (PasswordCallback) current;
pcb.setPassword(password.toCharArray());
} else if (current instanceof RealmCallback) {
RealmCallback rcb = (RealmCallback) current;
rcb.setText(rcb.getDefaultText());
} else {
throw new UnsupportedCallbackException(current);
}
}
}
};
return ModelControllerClient.Factory
.create(host, port, callbackHandler);
}
For more information on how to read the data obtained from Server or for the complete project using Java/Google visualizer API (to show the statistics in Graph after every 10 secs) , Please refer to this tutorial -
http://javacodingtutorial.blogspot.com/2014/05/reading-jboss-memory-usage-using-java.html
Add the following to your jboss-deployment-structure
<dependencies>
<module name="org.jboss.remoting3.remoting-jmx" services="import"/>
</dependencies>
Activate JMX remoting subsystem by adding following entry in standalone.xml
<subsystem xmlns="urn:jboss:domain:ee:1.1">
<!-- Activate JMX remoting -->
<global-modules>
<module name="org.jboss.remoting-jmx" slot="main"/>
</global-modules>
...
</subsystem>
It seems like "jboss-client.jar" is not available at run-time for JMX connection, So make sure that you have added "jboss-client.jar" in the class path.
And also you are using deprecated protocol "remoting-jmx" instead of "remote".
i.e, "service:jmx:remote://localhost:9999"
Hope it helps.

Configuring gwt-log's remoteLogger; use log4j to put it in a separate file

I have a (Smart)GWT application, that uses Spring on the server-side, and logs its stuff there via log4j. This works (deploying on tomcat6/ubuntu 10.04 LTS).
On the client-side I use the gwt-log remote logging library, configured properly. When running debug mode, I see the gwt-logs in the Eclipse 'Development Mode' pane. When deployed however, I don't see the gwt-log logs. I have configured things as follows:
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
...
<appender name="FILE_LOG2" class="org.apache.log4j.FileAppender">
<param name="File" value="${PuzzelVandaag-instance-root}WEB-INF/logs/Sytematic.log" />
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="--- %d [%.4t] %-5p %c{1} - %m%n"/>
</layout>
</appender>
...
<!-- this one works, normal server-side code -->
<category name="com.isomorphic">
<priority value="DEBUG" />
<appender-ref ref="FILE_LOG2" />
</category>
<!-- currently I use this to configure gwt-log stuff. Is this the right way? -->
<category name="gwt-log">
<level value="DEBUG" />
<appender-ref ref="FILE_LOG2"/>
</category>
The server-side package logging works, but I have troubles with the client-side. I am fairly sure the remote logging servlet works, as I don't see any errors on this. I have it configured as follows, in web.xml:
<servlet>
<servlet-name>gwt-log-remote-logger-servlet</servlet-name>
<servlet-class>com.allen_sauer.gwt.log.server.RemoteLoggerServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gwt-log-remote-logger-servlet</servlet-name>
<url-pattern>/[modulename]/gwt-log</url-pattern>
</servlet-mapping>
When I log stuff, I do a call like Log.debug("some msg"), whilst importing com.allen_sauer.gwt.log.client.Log.
All-in-all I think I followed the correct approach. I also run hosted mode with the -Dlog4j.debug parameter, and this is what it tells me:
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [gwt-log] additivity to [true].
log4j: Level value for gwt-log is [DEBUG].
log4j: gwt-log level set to DEBUG
log4j: Adding appender named [STDOUT] to category [gwt-log].
log4j: Adding appender named [SmartClientLog] to category [gwt-log].
log4j: Adding appender named [FILE_LOG2] to category [gwt-log].
For completion, here is the relevant part of .gwt.xml:
<inherits name="com.allen_sauer.gwt.log.gwt-log-DEBUG"/>
<set-property name="log_DivLogger" value="DISABLED"/>
<!-- In gwt-log-3.0.3 or later -->
<inherits name="com.allen_sauer.gwt.log.gwt-log-RemoteLogger"/>
Am I missing something obvious? I am a log4j newbie... Any help would be greatly appreciated!
If you take a look at the com.google.gwt.logging.server.RemoteLoggingServiceImpl code you will see that it is using java.util.logging.Logger to perform it's logging.
You are using Log4j.
There are two options for getting your logs to appear in Log4j.
Implement your own RemoteLoggingService
Use slf4j to "bridge" java.util.logging with log4j logging
Option 1 is not too hard.
I have below the class I created for this. Remember to point your web.xml to this new class.
import java.util.logging.LogRecord;
import com.google.gwt.logging.shared.RemoteLoggingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import java.util.logging.Level;
import org.springframework.stereotype.Component;
public class MyRemoteLoggingServlet extends RemoteServiceServlet implements RemoteLoggingService {
private final MyLogger logger = MyLoggerFactory.getLogger(getClass());
#Override
public String logOnServer(LogRecord record) {
Level level = record.getLevel();
String message = record.getMessage();
if (Level.INFO.equals(level)) {
logger.info(message);
} else if (Level.SEVERE.equals(level)) {
logger.error(message);
} else if (Level.WARNING.equals(level)) {
logger.warn(message);
} else if (Level.FINE.equals(level)) {
logger.debug(message);
}
return null;
}
}
Option 2
In this option you use SLF4J for your logging and configure a bridge that will redirect the java.util.logging.Logger to Log4j.
I havent implemented this method myself, but you can read about it here:
JUL to SLF4J Bridge
I took this approach, works for me.
public class UILogging extends RemoteServiceServlet implements
RemoteLoggingService {
private static final String SYMBOL_MAPS = "symbolMaps";
private static StackTraceDeobfuscator deobfuscator = null;
private static Logger logger = Logger.getLogger(UILogging.class);
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
setSymbolMapsDirectory(config.getInitParameter(SYMBOL_MAPS));
}
/**
* Logs a Log Record which has been serialized using GWT RPC on the server.
*
* #return either an error message, or null if logging is successful.
*/
public final String logOnServer(LogRecord lr) {
String strongName = getPermutationStrongName();
try {
if (deobfuscator != null) {
lr = deobfuscator.deobfuscateLogRecord(lr, strongName);
}
if (lr.getLevel().equals(Level.SEVERE)) {
logger.error(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.INFO)) {
logger.info(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.WARNING)) {
logger.warn(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.FINE)) {
logger.debug(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.ALL)) {
logger.trace(lr.getMessage(),lr.getThrown());
}
} catch (Exception e) {
logger.error("Remote logging failed", e);
return "Remote logging failed, check stack trace for details.";
}
return null;
}
/**
* By default, this service does not do any deobfuscation. In order to do
* server side deobfuscation, you must copy the symbolMaps files to a
* directory visible to the server and set the directory using this method.
*
* #param symbolMapsDir
*/
public void setSymbolMapsDirectory(String symbolMapsDir) {
if (deobfuscator == null) {
deobfuscator = new StackTraceDeobfuscator(symbolMapsDir);
} else {
deobfuscator.setSymbolMapsDirectory(symbolMapsDir);
}
}
}