How to resolve IllegalStateException and ParserConfigurationException for finding location in android studio by using apache OpenNLP

Viewed 407
 package com.example.dell.apacheopennlp;
    import android.os.StrictMode;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.TextView;
    import java.io.IOException;
    import java.io.InputStream;
    import opennlp.tools.namefind.NameFinderME;
    import opennlp.tools.namefind.TokenNameFinderModel;
    import opennlp.tools.tokenize.TokenizerME;
    import opennlp.tools.tokenize.TokenizerModel;
    import opennlp.tools.util.Span;
    public class apacheOpenNLP extends AppCompatActivity {
         TokenNameFinderModel locationModel = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate (savedInstanceState);
            setContentView (R.layout.activity_apache_open_nlp);
            final TextView txt = (TextView) findViewById (R.id.txtView);
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
             StrictMode.setThreadPolicy(policy);

            InputStream inputStream = null;
            TokenizerModel tokenModel = null;
            try {
                inputStream = getAssets ( ).open ("en-token.bin");
                tokenModel = new TokenizerModel (inputStream);
                inputStream.close ( );
            } catch (IOException e) {
                e.printStackTrace ( );
                txt.setText (e.toString ( ) + " inside catch of token");
            }

            if (tokenModel != null) {
                TokenizerME tokenizer = new TokenizerME (tokenModel);
                String paragraph = "Tutorialspoint is located in Hyderabad";
                String tokens[] = tokenizer.tokenize (paragraph);
                InputStream locationInputStream = null;

                try {
                    locationInputStream = getAssets ( ).open ("en-ner-location.bin");
                    locationModel = new TokenNameFinderModel (locationInputStream);

                } catch (IOException e) {
                    e.printStackTrace ( );
                    txt.setText (e.toString ( ) + " inside catch of location");
                }
                Thread thread = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try  {
                            NameFinderME nameFinder = null;
                            if (locationModel != null) {
                                txt.setText ("Location model is not empty");
                                nameFinder = new NameFinderME (locationModel);

                                //after this line..its goes in the catch and the app crashes 
                                Span nameSpans[] = nameFinder.find (tokens);
                                String result = null;
                                for (Span s : nameSpans)
                                   result += s.toString ( );
                                txt.setText (result);
                                // txt.setText ("Location model is not empty");*/
                            }
                            else{
                                txt.setText ("Location model is empty");
                            }
                    } catch (Exception e) {
                        txt.setText(e.toString ()+"++++++");
                        e.printStackTrace();
                    }
                }
            });

            thread.start();

        }

        }

    }

I am using the apache openNLP to find the location in a sentence and i am getting errors when it passes at nameFinder = new NameFinderME(locationModel); I have tried other examples when it uses NameFinderME, it did not work also. Can somebody figure out the issue?

W/System.err: java.lang.IllegalStateException: javax.xml.parsers.ParserConfigurationException: http://javax.xml.XMLConstants/feature/secure-processing
                  at opennlp.tools.util.XmlUtil.createDocumentBuilder(XmlUtil.java:42)
                  at opennlp.tools.util.featuregen.GeneratorFactory.createDOM(GeneratorFactory.java:557)
                  at opennlp.tools.util.featuregen.GeneratorFactory.create(GeneratorFactory.java:590)
                  at opennlp.tools.namefind.TokenNameFinderFactory.createFeatureGenerators(TokenNameFinderFactory.java:189)
                  at opennlp.tools.namefind.TokenNameFinderFactory.createContextGenerator(TokenNameFinderFactory.java:150)
                  at opennlp.tools.namefind.NameFinderME.<init>(NameFinderME.java:83)
                  at com.example.dell.apacheopennlp.apacheOpenNLP$1.run(apacheOpenNLP.java:60)
                  at java.lang.Thread.run(Thread.java:764)

W/System.err: Caused by: javax.xml.parsers.ParserConfigurationException: http://javax.xml.XMLConstants/feature/secure-processing
                  at org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl.setFeature(DocumentBuilderFactoryImpl.java:101)
2 Answers

In case you are using a more recent version of Apache OpenNLP you can directly pass the URL which is returned by getResource to the TokenizerModel constructor.

TokenizerModel tokenModel = 
    new TokenizerModel(apacheOpenNLP.class.getResource("en-token.bin"));  

You should not load the model each time you invoke the tokenizer, the model should be reused for multiple invocations.

Can you try to change the nameFinder to be declared as TokenNameFinder interface type?

Just try to replace

NameFinderME nameFinder = null

with

TokenNameFinder nameFinder = null

Rest all should be same.

Related