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 Sat, 23 May 2015 15:05:49 GMT
Here it is once again:

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 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 {

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

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

        boolean bindResourcesFirst = args.length > 0 ? "-brf".equals(args[0]) : false;

        AggregateBuilder builder = new AggregateBuilder();

        ExternalResourceDescription resourceA = ExternalResourceFactory.createExternalResourceDescription(ResourceA.class,"http://resource.org/a");
        ExternalResourceDescription resourceB = ExternalResourceFactory.createExternalResourceDescription(ResourceB.class,"http://resource.org/b");
        CollectionReaderDescription reader = CollectionReaderFactory.createReaderDescription(SimpleCollectionReader.class);
        FlowControllerDescription flow = FlowControllerFactory.createFlowControllerDescription(FlowController.class);
        AnalysisEngineDescription ae = AnalysisEngineFactory.createEngineDescription(SimpleAnalyser.class);

        if(bindResourcesFirst) // Variation to illustrate the different error outcome
            bindExternalResource(resourceB, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(flow, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(flow, ResourceB.RESOURCE_B_KEY, resourceB);
        bindExternalResource(reader, ResourceA.RESOURCE_A_KEY, resourceA);
        bindExternalResource(reader, ResourceB.RESOURCE_B_KEY, resourceB);
        if(!bindResourcesFirst)
            bindExternalResource(resourceB, ResourceA.RESOURCE_A_KEY, resourceA);

        builder.add(ae);
        builder.setFlowControllerDescription(flow);

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

> On 23 May 2015, at 15:19 , Richard Eckart de Castilho <rec@apache.org> wrote:
> 
> Mario, it appears as if the attachment didn't make it through. No idea
> if the list filters it. I expect the code snippet is not too long,
> so maybe you can paste it directly to the mail?
> 
> -- Richard
> 
> On 23.05.2015, at 11:53, Mario Gazzo <mario.gazzo@gmail.com> wrote:
> 
>> I attached a small Java example program that reproduces the problem using the simple
pipeline but the error is the same with CPE. We are still using UIMA 2.6 with uimaFIT 2.1.0
but I could reproduce it with UIMA 2.7.
>> 
>> You can vary the binding sequence to see how the error differs depending on whether
resource B is bound to resource A first or last. Also try to comment out the dependencies
of B on A and see that everything then works as expected.
>> 
>> Let me know if its just me doing something wrong ;)
>> 
>> Cheers
>> Mario
>> 
>> 
>> 
>>> On 22 May 2015, at 17:32 , Mario Gazzo <mario.gazzo@gmail.com> wrote:
>>> 
>>> Yes, I am using the uimaFIT base classes but I will try to reproduce it in a
micro sample application as soon as possible and post it here.
>>> 
>>>> On 22 May 2015, at 17:04 , Richard Eckart de Castilho <rec@apache.org>
wrote:
>>>> 
>>>> I am not sure that I have ever tested nested resources on readers;
>>>> certainly, I have never tested them on flow controllers - only on AEs.
>>>> 
>>>> Anyway - are you using the uimaFIT base-classes for readers and flow
>>>> controllers - those that call ExternalResourceInitializer.initialize(...)
>>>> in their initialize(...) methods?
>>>> 
>>>> Can you provide some example code?
>>>> 
>>>> Cheers,
>>>> 
>>>> -- Richard
>>>> 
>>>> On 22.05.2015, at 16:59, Mario Gazzo <mario.gazzo@gmail.com> wrote:
>>>> 
>>>>> I have some trouble with initialising some nested resource with UIMA
fit. I have followed the approach described in the section “Resources implementing SharedResourceObject”.
I just have a resource B that uses resource A and a collection reader and a flow control that
use both A and B but I get "mandatory resource A not set on resource B” illegal state exception.
I use the @ExternalResource annotations to get them injected and I used ExternalResourceFactory.bindExternalResource
with A and B on the collection reader and flow control descriptions when creating my aggregate.
It works if B is not dependent on A but as soon I add the dependency then it breaks. I also
tried to explicitly use ExternalResourceFactory.bindExternalResource on A to B but that caused
null pointer exception in ExternalResourceFactory when trying to bind to the collection reader
right after.
>>>>> 
>>>>> I would appreciate any ideas about what I might be doing wrong.
>>>>> 
>>>>> Cheers
>>>>> Mario
>>>> 
>>> 
>> 
> 


Mime
View raw message