uima-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mario Gazzo <mario.ga...@gmail.com>
Subject Re: Injecting nested resources using UIMA fit
Date Fri, 19 Jun 2015 20:24:45 GMT
Hi Richard,

Seems something still spooky with my nested resources. This time I added an additional resource,
which depends on the same shared resource as another. I now have two different resources dependent
on the same external resource but during initialisation I get the error shown below. I can
use both resources independently of each other but just not together. I have been able to
replicate it by extending the earlier simple example (see further down).

You will notice in the example that I bind every resource to every description specified even
though there is no declared dependency. Reason is because our actual application has a small
DSL that aggregates the descriptions and then tries to bind resources on all possible descriptions
just before execution. However, I just did a naive approach where I bind every resource to
every possible description that was added but I didn’t do code that first inspects whether
a description has actually declared the dependency before attempting to bind. Yes, its inefficient
for a very large amount of resources but we don’t have that. My naive assumption was that
the UIMAfit binding process would figure this out way better than I could myself and I just
sticked with this since it worked fine until now and it was simple to program. I don’t know
whether this actually is the direct cause of the problem or whether my use just triggered
a bug. It works if I don’t do these superfluous bindings. If this use case cannot be supported
then I would like to know what would alternatively be the simplest way to make these inspections
on the descriptors before making a binding attempt?

Thanks a lot for your help.

Cheers
Mario

///////////////////////// EXAMPLE OUTPUT ///////////////////////////////////

Resource A loaded
Resource B loaded
Resource C loaded
Resource C initialized. Now calling resource A
Hello resource A
Exception in thread "main" org.apache.uima.resource.ResourceInitializationException
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:128)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.initialize(ExternalResourceInitializer.java:72)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.initializeNestedResources(ExternalResourceInitializer.java:199)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:98)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:94)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.initialize(ExternalResourceInitializer.java:72)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.initializeNestedResources(ExternalResourceInitializer.java:199)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:98)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:94)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:94)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:94)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:94)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.configure(ExternalResourceInitializer.java:94)
	at org.apache.uima.fit.component.initialize.ExternalResourceInitializer.initialize(ExternalResourceInitializer.java:72)
	at org.apache.uima.fit.component.JCasCollectionReader_ImplBase.initialize(JCasCollectionReader_ImplBase.java:55)
	at org.apache.uima.collection.CollectionReader_ImplBase.initialize(CollectionReader_ImplBase.java:70)
	at org.apache.uima.impl.CollectionReaderFactory_impl.produceResource(CollectionReaderFactory_impl.java:103)
	at org.apache.uima.impl.CompositeResourceFactory_impl.produceResource(CompositeResourceFactory_impl.java:62)
	at org.apache.uima.UIMAFramework.produceResource(UIMAFramework.java:279)
	at org.apache.uima.UIMAFramework.produceResource(UIMAFramework.java:331)
	at org.apache.uima.UIMAFramework.produceCollectionReader(UIMAFramework.java:812)
	at org.apache.uima.fit.pipeline.SimplePipeline.runPipeline(SimplePipeline.java:134)
	at NestedResourceExample.main(NestedResourceExample.java:291)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.IllegalStateException: Mandatory resource [NestedResourceExample$ResourceB-1##Resource-A]
is not set on [class NestedResourceExample$ResourceB]
	... 28 more


///////////////////////// EXAMPLE CODE ///////////////////////////////////

import org.apache.uima.UIMAException;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.analysis_engine.metadata.FixedFlow;
import org.apache.uima.analysis_engine.metadata.FlowConstraints;
import org.apache.uima.cas.AbstractCas;
import org.apache.uima.cas.CAS;
import org.apache.uima.collection.CollectionException;
import org.apache.uima.collection.CollectionReaderDescription;
import org.apache.uima.fit.component.*;
import org.apache.uima.fit.component.JCasFlowController_ImplBase;
import org.apache.uima.fit.component.initialize.ConfigurationParameterInitializer;
import org.apache.uima.fit.descriptor.ConfigurationParameter;
import org.apache.uima.fit.descriptor.ExternalResource;
import org.apache.uima.fit.factory.*;
import org.apache.uima.fit.pipeline.SimplePipeline;
import org.apache.uima.fit.util.JCasUtil;
import org.apache.uima.flow.*;
import org.apache.uima.jcas.JCas;
import org.apache.uima.resource.DataResource;
import org.apache.uima.resource.ExternalResourceDescription;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.SharedResourceObject;
import org.apache.uima.util.Progress;
import org.apache.uima.util.ProgressImpl;

import java.io.IOException;
import java.util.ArrayList;

import static org.apache.uima.fit.factory.ExternalResourceFactory.bindExternalResource;

/**
 * Micro example illustrating a problem when initializing nested resources
 */

public class NestedResourceExample {

    public static class ResourceA implements SharedResourceObject, ExternalResourceAware {

        public static final String RESOURCE_A_KEY = "Resource-A";

        @ConfigurationParameter(name= ExternalResourceFactory.PARAM_RESOURCE_NAME)
        private String resourceName;

        @Override
        public String getResourceName() {
            return resourceName;
        }

        @Override
        public void afterResourcesInitialized() throws ResourceInitializationException {
            System.out.println("Resource A initialized");
        }

        @Override
        public void load(DataResource aData) throws ResourceInitializationException {
            ConfigurationParameterInitializer.initialize(this, aData);
            System.out.println("Resource A loaded");
        }

        public void helloA() {
            System.out.println("Hello resource A");
        }
    }

    public static class ResourceB implements SharedResourceObject, ExternalResourceAware {

        public static final String RESOURCE_B_KEY = "Resource-B";

        @ExternalResource(key = ResourceA.RESOURCE_A_KEY)
        private ResourceA resourceA;

        @ConfigurationParameter(name= ExternalResourceFactory.PARAM_RESOURCE_NAME)
        private String resourceName;

        @Override
        public String getResourceName() {
            return resourceName;
        }

        @Override
        public void afterResourcesInitialized() throws ResourceInitializationException {
            System.out.println("Resource B initialized. Now calling resource A");
            resourceA.helloA();
        }

        @Override
        public void load(DataResource aData) throws ResourceInitializationException {
            ConfigurationParameterInitializer.initialize(this, aData);
            System.out.println("Resource B loaded");
        }

        public void helloB() {
            System.out.println("Hello resource B");
        }
    }

    public static class ResourceC implements SharedResourceObject, ExternalResourceAware {

        public static final String RESOURCE_C_KEY = "Resource-C";

        @ExternalResource(key = ResourceA.RESOURCE_A_KEY)
        private ResourceA resourceA;

        @ConfigurationParameter(name= ExternalResourceFactory.PARAM_RESOURCE_NAME)
        private String resourceName;

        @Override
        public String getResourceName() {
            return resourceName;
        }

        @Override
        public void afterResourcesInitialized() throws ResourceInitializationException {
            System.out.println("Resource C initialized. Now calling resource A");
            resourceA.helloA();
        }

        @Override
        public void load(DataResource aData) throws ResourceInitializationException {
            ConfigurationParameterInitializer.initialize(this, aData);
            System.out.println("Resource C loaded");
        }

        public void helloC() {
            System.out.println("Hello resource C");
        }
    }

    public static class FlowController extends JCasFlowController_ImplBase {

        @ExternalResource(key = ResourceA.RESOURCE_A_KEY)
        private ResourceA resourceA;

        @ExternalResource(key = ResourceB.RESOURCE_B_KEY)
        private ResourceB resourceB;

        private ArrayList<Step> pipeline = new ArrayList<>();

        @Override
        public void initialize(FlowControllerContext context) throws ResourceInitializationException
{
            super.initialize(context);

            FlowConstraints flowConstraints = context.getAggregateMetadata().getFlowConstraints();
            String[] sequence = ((FixedFlow) flowConstraints).getFixedFlow();
            for( String key : sequence ) {
                pipeline.add(new SimpleStep(key));
            }

        }

        @Override
        public Flow computeFlow(JCas aJCas) throws AnalysisEngineProcessException {
            return new SimpleFlow(aJCas);
        }

        public class SimpleFlow implements Flow {

            private final JCas jCas;

            private int step = 0;

            public SimpleFlow(JCas jCas) {
                this.jCas = jCas;
            }

            @Override
            public Step next() throws AnalysisEngineProcessException {
                if(step < pipeline.size()) {
                    return pipeline.get(step++);
                } else {
                    resourceA.helloA();
                    resourceB.helloB();
                    return new FinalStep();
                }
            }

            @Override
            public Flow newCasProduced(AbstractCas newCas, String producedBy) throws AnalysisEngineProcessException
{
                return null;
            }

            @Override
            public boolean continueOnFailure(String failedAeKey, Exception failure) {
                return false;
            }

            @Override
            public void aborted() {
                System.out.println("Simple flow aborted");
            }
        }
    }

    public static class SimpleCollectionReader extends JCasCollectionReader_ImplBase {

        @ExternalResource(key = ResourceA.RESOURCE_A_KEY)
        private ResourceA resourceA;

        @ExternalResource(key = ResourceB.RESOURCE_B_KEY)
        private ResourceB resourceB;

        private int completed = 0;

        @Override
        public void getNext(JCas jCas) throws IOException, CollectionException {
            try {
                JCas view = ViewCreatorAnnotator.createViewSafely(jCas, CAS.NAME_DEFAULT_SOFA);
                view.setDocumentText("This is some text "+completed++);
                resourceA.helloA();
                resourceB.helloB();
            } catch (AnalysisEngineProcessException e) {
                throw new CollectionException(e);
            }
        }

        @Override
        public boolean hasNext() throws IOException, CollectionException {
            return completed < 1;
        }

        @Override
        public Progress[] getProgress() {
            return new Progress[] { new ProgressImpl(0, 1, Progress.ENTITIES) };
        }
    }

    public static class SimpleAnalyser extends JCasAnnotator_ImplBase {

        @ExternalResource(key = ResourceB.RESOURCE_B_KEY)
        private ResourceB resourceB;

        @Override
        public void process(JCas jCas) throws AnalysisEngineProcessException {
            JCas view = JCasUtil.getView(jCas, CAS.NAME_DEFAULT_SOFA, true);
            System.out.println(view.getDocumentText());
            resourceB.helloB();
        }
    }

    public static class AnotherSimpleAnalyser extends JCasAnnotator_ImplBase {

        @ExternalResource(key = ResourceC.RESOURCE_C_KEY)
        private ResourceC resourceC;

        @Override
        public void process(JCas jCas) throws AnalysisEngineProcessException {
            System.out.println("One more analysis");
            resourceC.helloC();
        }
    }

    public static void main(String[] args) throws UIMAException, IOException {

        AggregateBuilder builder = new AggregateBuilder();

        ExternalResourceDescription resourceA = ExternalResourceFactory.createExternalResourceDescription(ResourceA.class,"http://resource.org/a");
        ExternalResourceDescription resourceB = ExternalResourceFactory.createExternalResourceDescription(ResourceB.class,"http://resource.org/b");
        ExternalResourceDescription resourceC = ExternalResourceFactory.createExternalResourceDescription(ResourceC.class,"http://resource.org/c");

        CollectionReaderDescription reader = CollectionReaderFactory.createReaderDescription(SimpleCollectionReader.class);
        FlowControllerDescription flow = FlowControllerFactory.createFlowControllerDescription(FlowController.class);
        AnalysisEngineDescription ae1 = AnalysisEngineFactory.createEngineDescription(SimpleAnalyser.class);
        AnalysisEngineDescription ae2 = AnalysisEngineFactory.createEngineDescription(AnotherSimpleAnalyser.class);

        bindExternalResource(resourceA, ResourceB.RESOURCE_B_KEY, resourceB);
        bindExternalResource(resourceC, ResourceC.RESOURCE_C_KEY, resourceC);
        bindExternalResource(resourceB, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(resourceB, ResourceC.RESOURCE_C_KEY, resourceC);
        bindExternalResource(resourceC, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(resourceC, ResourceB.RESOURCE_B_KEY, resourceB);
        bindExternalResource(flow, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(flow, ResourceB.RESOURCE_B_KEY, resourceB);
        bindExternalResource(flow, ResourceC.RESOURCE_C_KEY, resourceC);
        bindExternalResource(reader, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(reader, ResourceB.RESOURCE_B_KEY, resourceB);
        bindExternalResource(reader, ResourceC.RESOURCE_C_KEY, resourceC);
        bindExternalResource(ae1, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(ae1, ResourceB.RESOURCE_B_KEY, resourceB);
        bindExternalResource(ae1, ResourceC.RESOURCE_C_KEY, resourceC);
        bindExternalResource(ae2, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(ae2, ResourceB.RESOURCE_B_KEY, resourceB);
        bindExternalResource(ae2, ResourceC.RESOURCE_C_KEY, resourceC);

        builder.add(ae1);
        builder.add(ae2);
        builder.setFlowControllerDescription(flow);

        SimplePipeline.runPipeline(reader, builder.createAggregateDescription());
    }
}

> On 24 May 2015, at 13:19 , Mario Gazzo <mario.gazzo@gmail.com> wrote:
> 
> Works nicely now, Richard. Thanks a lot :)
> 
> I will run with the 2.2.0 branch from the Git repository in the coming period and I will
report back if I stumble upon any issues.
> 
> Is there some time horizon for the final release?
> 
> Cheers
> Mario
> 
>> On 24 May 2015, at 02:26 , Richard Eckart de Castilho <rec@apache.org> wrote:
>> 
>> Ok, so for what it's worth - bindExternalResource() should also have worked
>> in the way that you used it and it was a bug that it didn't.
>> 
>> So both of these issues are sorted out now:
>> 
>> - https://issues.apache.org/jira/browse/UIMA-4425
>> - https://issues.apache.org/jira/browse/UIMA-4426
>> 
>> I can now run your code with "bindResourcesFirst" set to true.
>> In fact, resourceA must be bound to resourceB before resourceB
>> is bound to further things.
>> 
>> We're not supposed to expose users to unreleased artifacts... 
>> but if you know how to get the latest uimaFIT from SVN and hook it
>> up to your code, it wouldn't hurt if you could give the fixes
>> a spin in your environment.
>> 
>> -- Richard
>> 
>> 
>> On 23.05.2015, at 22:52, Richard Eckart de Castilho <rec@apache.org> wrote:
>> 
>>> On 23.05.2015, at 22:45, Mario Gazzo <mario.gazzo@gmail.com> wrote:
>>> 
>>>> Thank you, Richard. The reason I use bindExternalResource is because I have
a light DSL layer on top where everything get’s wired together from different aggregate
modules. This way the modules don’t need to be that tightly coupled up front but I just
do the binding generically right before the execution. The example doesn’t show this.
>>> 
>>> ... ok, I'll double check again whether bindExternalResource really cannot be
used as you did here ... after fixing the other problem.
>>> 
>>> My main local uimaFIT checkout is currently a bit of a mess.
>>> 
>>> /me fetching duster and dusting off...
>>> 
>>> -- Richard
>> 
> 


Mime
View raw message