2017-08-31 5 views
1

Im ein MalformedByteSequenceException bekommen eine JSF-Anwendung ausgeführt wird, die Verwendung der Rom Rss-Parsing-Lib macht:MalformedByteSequenceException Parsing RSS Feed mit ROME

[2017-08-31T15:54:01.241+0200] [glassfish 5.0] [SEVERE] [] [] [tid: _ThreadID=101 _ThreadName=Thread-9] [timeMillis: 1504187641241] [levelValue: 1000] [[ 
    com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Ungültiges Byte 1 von 1-Byte-UTF-8-Sequenz. 
    at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:701) 
    at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:567) 
    at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1793) 
    at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipChar(XMLEntityScanner.java:1463) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2824) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) 
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) 
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243) 
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339) 
    at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:121) 
    at main.java.tools.RssAggregator.searchAggregatedFeeds(RssAggregator.java:119) 
    at main.java.jobs.ApplicationRunnable.lambda$execute$0(ApplicationRunnable.java:45) 
    at java.lang.Iterable.forEach(Iterable.java:75) 
    at main.java.jobs.ApplicationRunnable.execute(ApplicationRunnable.java:43) 
    at org.quartz.core.JobRunShell.run(JobRunShell.java:213) 
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) 
]] 

Der Fehler in RssAggregator.searchAggregatedFeeds geworfen wird() Linie 119:

public List<Feed> searchAggregatedFeeds(String keyword) { 
    keyword = keyword.toLowerCase(); 
    List<Feed> results = new LinkedList<>(); 
    Document document = null; 
    try { 
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder builder = factory.newDocumentBuilder(); 

     //document = builder.parse(IOUtils.toInputStream(this.aggregatedRssString); 
     InputStream stream = new ByteArrayInputStream(this.aggregatedRssString.getBytes()); 
     document = builder.parse(stream); //TODO HERE We have the Problem 
     stream.close(); 

     //Normalize the XML Structure; It's just too important !! 
     document.getDocumentElement().normalize(); 

    } catch (ParserConfigurationException | SAXException | IOException e) { 
     e.printStackTrace(); 
    } 

    //Here comes the root node 
    if (document != null) { 

     //Element root = document.getDocumentElement(); 
     //Get all 
     NodeList nList = document.getElementsByTagName("item"); 

     for (int i = 0; i < nList.getLength(); i++) { 

      Node node = nList.item(i); 
      Element ele = (Element) node; 

      Feed feed = new Feed(); 
      feed.setDate(ele.getElementsByTagName("dc:date").item(0).getTextContent()); 
      feed.setDescription(ele.getElementsByTagName("description").item(0).getTextContent()); 
      feed.setLink(ele.getElementsByTagName("link").item(0).getTextContent()); 
      feed.setSubject(ele.getElementsByTagName("title").item(0).getTextContent()); 
      feed.setId(getIdCounter()); //set the id. This increments also 

     /* now the searching ... */ 
      if (feed.getSubject().toLowerCase().contains(keyword) || feed.getDescription().toLowerCase().contains(keyword)) 
       results.add(feed); 
     } 
    } 
    return results; 
} 

ich kann nicht herausfinden, was mit der Linie document = builder.parse(stream); //TODO HERE We have the Problem falsch sein sollte?

Was mir auffällt, ist hier, dass, wenn es mit einem JUnit-Test zu testen, alles gut geht:

@Test 
public void searchTest() throws Exception { 
    List<Feed> results = rssAggregator.searchAggregatedFeeds("a"); 
    System.out.println("Hits: " + results.size()); 

    List<Feed> results2 = rssAggregator.searchAggregatedFeeds("z"); 
    System.out.println("Hits: " + results2.size()); 

    List<Feed> results3 = rssAggregator.searchAggregatedFeeds("x"); 
    System.out.println("Hits: " + results3.size()); 

} 

führt, wie erwartet: enter image description here

... während es aus dem zyklischen Job aufrufen nicht:

List<Feed> allResults = new LinkedList<>(); 

    /* for each WORD search the aggregatedfeed for matches and add them to allResults */ 
    configBean.words.forEach(w -> { 
     System.out.println("current searched for Word: " + w); 
     List<Feed> wResults = aggregator.searchAggregatedFeeds(w); // :(
     allResults.addAll(wResults); 
    }); 

Frage: warum funktioniert die junit-Testarbeiten, während die Anruf von innerhalb der Anwendung nicht? Die aggregierten Feeds sind genau gleich.

+1

Sind Ihre RSS-Daten UTF-8 codiert? Führen Sie den Junit-Test und die Anwendung in derselben Umgebung aus? – janih

+0

Danke, @janih, das war der genaue Grund, warum es nicht funktioniert hat! ich gerade geändert 'Inputstrom = new ByteArrayInputStream (this.aggregatedRssString.getBytes());' zu 'Inputstrom = new ByteArrayInputStream (this.aggregatedRssString.getBytes (StandardCharsets.UTF_8))' ... und es hat funktioniert! :) Können Sie bitte Ihren Kommentar zu einer Antwort fördern, damit ich akzeptieren kann ?! – Gewure

Antwort

1

Sind Ihre RSS-Daten UTF-8 codiert? Beim Aufrufen der no-Parameter-Version von String.getBytes() wird der Standard-Zeichensatz der Plattform verwendet, und es ist möglicherweise nicht UTF-8. Das ist der Grund, warum Ihr Test unter Linux funktioniert, aber unter Windows fehlschlägt. Versuchen Sie stattdessen String.getBytes(Charset charset).