Hi,
I think I've stumbled upon a bug in the databases block; it's quite obvious but
I've found no mention of it so far.
The problem is that DatabaseReader and SQLTransformer fail to obtain the
configured datasource. (There might be other components with this problem, but
these are the two I know of). The exception says "Component with
'org.apache.avalon.excalibur.datasource.DataSourceComponent/personnel' is not
defined in this service manager. (Key='AvalonServiceManager')".
The result is the same whether I define the data source in the Avalon [1] or
Spring way (defining a bean of class
org.springframework.jdbc.datasource.DriverManagerDataSource; at least I think
it's the Spring way, I've found no info about it yet). (The SQL transformer
sample [2] is also broken, so it's probably not me doing something wrong.)
Now, I've found this nice 'Creating a Reader' page [3] and I've noticed that
the code it lists for obtaining the data source is not the same as in
DatabaseReader.java [4]. Upon modifying the reader in accordance with the
sample in [3] it started to work again (both the Avalon and Spring way).
I'm attaching my modification as a patch to make it easier to see what I'm
talking about. (I have very little understanding of what's going on in the code
involved; the patch might break things more, as far as I can tell, despite the
fact that "It Works For Me"(tm).)
Csaba
P.S. I'm using revision 560710 as the current head won't start because of
cocoon-expression-language-impl; I don't think it matters though, recent
commits seem to be unrelated to the issue.
P.P.S. If I should've filed a bug report through JIRA, please tell me, and I'll
learn how to do so for the next time :)
[1]
http://svn.apache.org/repos/asf/cocoon/trunk/blocks/cocoon-databases/cocoon-databases-sample/src/main/resources/META-INF/cocoon/avalon/cocoon-databases-sample.xconf
[2] http://localhost:8888/blocks/cocoon-databases-sample/transform/sql-page
[3] http://cocoon.zones.apache.org/daisy/cdocs/g1/g1/g2/g1/g2/681.html
[4]
http://svn.apache.org/repos/asf/cocoon/trunk/blocks/cocoon-databases/cocoon-databases-impl/src/main/java/org/apache/cocoon/reading/DatabaseReader.java
Index:
blocks/cocoon-databases/cocoon-databases-impl/src/main/java/org/apache/cocoon/reading/DatabaseReader.java
===================================================================
---
blocks/cocoon-databases/cocoon-databases-impl/src/main/java/org/apache/cocoon/reading/DatabaseReader.java
(revision 560710)
+++
blocks/cocoon-databases/cocoon-databases-impl/src/main/java/org/apache/cocoon/reading/DatabaseReader.java
(working copy)
@@ -35,6 +35,7 @@
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.caching.CacheableProcessingComponent;
@@ -58,6 +59,7 @@
implements Configurable, Disposable,
CacheableProcessingComponent {
private DataSourceComponent dataSourceComponent;
+ private ServiceSelector serviceSelector;
private DataSource dataSource;
@@ -90,7 +92,8 @@
if ( this.dataSource == null ) {
String datasourceName = conf.getChild("use-connection").getValue();
try {
- this.dataSourceComponent = (DataSourceComponent)
this.manager.lookup(DataSourceComponent.ROLE + '/' + datasourceName);
+ this.serviceSelector = (ServiceSelector)
this.manager.lookup(DataSourceComponent.ROLE + "Selector");
+ this.dataSourceComponent = (DataSourceComponent)
this.serviceSelector.select(datasourceName);
} catch (ServiceException e) {
throw new ConfigurationException("Datasource '" +
datasourceName + "' is not available.", e);
}
@@ -381,7 +384,9 @@
public void dispose() {
this.recycle();
if (manager != null) {
- this.manager.release(dataSourceComponent);
+ serviceSelector.release(dataSourceComponent);
+ this.manager.release(serviceSelector);
+ serviceSelector = null;
dataSourceComponent = null;
this.manager = null;
}