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;
         }

Reply via email to