How to use a datasource in a realm in a tomcat environment.
When coding your own realm for the tomcat webapplication-sever its sometimes very helpful to use a dataosurce. This is a very easy task to do. Just define the datasource in the serverl.xml within the GlobalNamingResource-tag like this
(example for a Oracle-DB, for more Information on configuring dataosurces refer to the tomcat manual)
<GlobalNamingResources>
...
<Resource name="jdbc/datasource" auth="Container"
type="javax.sql.DataSource"
factory="org.apache.commons.dbcp.BasicDataSourceFactory"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@localhost:1521:xe"
username="username" password="password" maxActive="20" maxIdle="10"
maxWait="-1" />
...
</GlobalNamingResources>
and within your realm implemantation you make a lookup for the datasoruce like this
public class MyOwnRealm extends RealmBase
private Datasource datasoruce;
...
public void start() throws LifecycleException {
super.start();
StandardServer server = (StandardServer) ServerFactory.getServer();
Context context = server.getGlobalNamingContext();
try {
dataSource = (DataSource)context.lookup("jdbc/datasource");
} catch (NamingException e) {
....
}
}
...
public Principal authenticate(String userId, String password) {
// do something with the datasource
}
}
voilà, this is as easy as been shown above.
But, in my last project i used Ibatis (very useful stuff, by the way) as persistencelayer and was unsuccessful to get access from the ibatis TransactionManager to the datasource configured in the server.xml.
Any configuration I tried was useless.
The solution at last was implementing an own com.ibatis.sqlmap.engine.datasource.DataSourceFactory and refer to it in the TransActionManager definition.
Codesnippet for JndiDataSourceFactory
public class JndiDataSourceFactory implements DataSourceFactory {
private static DataSource dataSource;
public void initialize(Map map) {
StandardServer server = (StandardServer) ServerFactory.getServer();
Context context = server.getGlobalNamingContext();
try {
dataSource = (DataSource)context.lookup((String)map.get("DataSource"));
} catch (NamingException e) {
e.printStackTrace();
}
}
public DataSource getDataSource() {
return dataSource;
}
}
Codesnippet for TransactionManager configuration
<typeAlias alias="global" type="de.rscheuch.realm.JndiDataSourceFactory" />
<transactionManager type="JDBC" commitRequired="false">
<dataSource type="global">
<property name="DataSource" value="jdbc/datasource"
</dataSource>
</transactionManager>
deploy the realm, restart the server… bingo! It works!
At least it was tested on a Tomcat 5.5



Hey Oliver, wie siehts aus, haste nicht mal Lust sowas in das Resco Blog zu schreiben?
Einmal auf Deutsch, bitte!