I missed a thing I had to do to make Torque 3 run "in" OSGi
environments. I had to reimplement the SharedPoolDataSourceFactory
since the original one used CPDS which isn't capable of using the
OSGi-classloaders.
Here's a snapshot of what I had done:
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.torque.TorqueException;
import org.apache.torque.dsfactory.AbstractDataSourceFactory;
public class OsgiPoolDataSourceFactory extends
AbstractDataSourceFactory {
/** The log. */
private static Log log =
LogFactory.getLog(OsgiPoolDataSourceFactory.class);
private DataSourceAdapter ds = null;
@Override
@SuppressWarnings("unchecked")
public void initialize(Configuration configuration) throws
TorqueException {
super.initialize(configuration);
System.out.println("Initialize Torque DataSource...");
Properties properties = new Properties();
Iterator<String> iterator = configuration.getKeys();
while (iterator.hasNext()) {
String key = iterator.next();
String value = configuration.getProperty(key).toString();
System.out
.println("Found property " + key + " with value
" + value);
String property = null;
for (String[] k : mappings) {
if (k[0].equals(key))
property = k[1];
}
if (property != null) {
System.out.println("Found mapping for key " + key +
" to "
+ property);
properties.setProperty(property, value);
} else {
properties.setProperty(key, value);
}
}
try {
ds = new DataSourceAdapter((BasicDataSource)
BasicDataSourceFactory
.createDataSource(properties));
System.out
.println("Testing datasource for successful
connection...");
Connection connection = getDataSource().getConnection();
Statement statement = connection.createStatement();
statement.execute("SELECT 1");
System.out.println("Connection established...");
} catch (Exception e) {
e.printStackTrace();
throw new TorqueException(e);
}
}
@Override
public DataSource getDataSource() throws TorqueException {
return ds;
}
@Override
public void close() throws TorqueException {
try {
ds.close();
} catch (Exception e) {
log.error("Exception caught during close()", e);
throw new TorqueException(e);
}
ds = null;
}
private static final String[][] mappings = {
new String[] { "connection.driver", "driverClassName" },
new String[] { "connection.url", "url" },
new String[] { "connection.user", "username" },
new String[] { "connection.password", "password" } };
private static final class DataSourceAdapter implements DataSource {
private final int retry;
private final BasicDataSource dataSource;
public DataSourceAdapter(BasicDataSource basicDataSource) {
this(3, basicDataSource);
}
public DataSourceAdapter(int retry, BasicDataSource
basicDataSource) {
this.retry = retry;
this.dataSource = basicDataSource;
}
@Override
public Connection getConnection() throws SQLException {
for (int i = 0; i < retry; i++) {
try {
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
statement.execute("SELECT 1;");
return connection;
} catch (Exception e) {
log
.info("Caught
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException - try again");
// just ignore this one and try again
}
}
throw new SQLException("MySQL database link could not be
restored.");
}
@Override
public Connection getConnection(String username, String
password)
throws SQLException {
return dataSource.getConnection(username, password);
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return dataSource.getLogWriter();
}
@Override
public int getLoginTimeout() throws SQLException {
return dataSource.getLoginTimeout();
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
dataSource.setLogWriter(out);
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
dataSource.setLoginTimeout(seconds);
}
public void close() throws SQLException {
dataSource.close();
}
@Override
public boolean isWrapperFor(Class<?> iface) throws
SQLException {
try {
if (iface.isAssignableFrom(dataSource.getClass())) {
return true;
}
Method method =
dataSource.getClass().getMethod("isWrapperFor",
new Class[] { Class.class });
return Boolean.TRUE.equals(method.invoke(dataSource,
new Object[] { iface }));
} catch (NoSuchMethodException e) {
throw new UnsupportedOperationException();
} catch (IllegalAccessException e) {
throw new SQLException(e);
} catch (InvocationTargetException e) {
throw new SQLException(e);
}
}
@Override
@SuppressWarnings("unchecked")
public <T> T unwrap(Class<T> iface) throws SQLException {
try {
if (iface.isAssignableFrom(dataSource.getClass())) {
return (T) dataSource;
}
Method method =
dataSource.getClass().getMethod("unwrap",
new Class[] { Class.class });
return (T) method.invoke(dataSource, new Object[] {
iface });
} catch (NoSuchMethodException e) {
throw new UnsupportedOperationException();
} catch (IllegalAccessException e) {
throw new SQLException(e);
} catch (InvocationTargetException e) {
throw new SQLException(e);
}
}
}
}
Am 23.11.2010 19:03, schrieb Christoph Engelbert:
> At the moment there's some static way to initialize, shutdown
> torque by using the Torque-Class.
> The next problem would be some Buddy-Behaviour to make it possible
> for a Torque-Service-Bundle to persist the classes from other
> bundles (a woldcard-import would be possible but isn't really nice).
> I guess for a real Torque bundle that exports services the way
> EclipseLink, Hibernate and other peristance engine does there'll be
> more problems that does not recognized yet.
>
> At the moment we're using Torque in an OSGi environment but in a
> very ugly hacking way. It is bundled to the OSGi-Bundle that uses it
> and is initialized for every single os that bundles.
>
> Since there were some discussions about using interfaces and this
> possibly means bigger internal changes it could be a good reason to
> think about more changes that could help using Torque in OSGi
> environments.
>
> Am 23.11.2010 18:24, schrieb Thomas Fox:
>>> are there any plans to support OSGi runtime environments in Torque 4?
>> Not yet. I have not even thought about what it might mean. Do you have any
>> idea whether it means more than adding a manifest.mf to the runtime ?
>>
>> Thomas
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [email protected]
>> For additional commands, e-mail: [email protected]
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]