[ 
https://issues.apache.org/jira/browse/MIME4J-139?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12773299#action_12773299
 ] 

Stefano Bagnara commented on MIME4J-139:
----------------------------------------

IMO this is not a JRE bug, but simply a tricky java language specification 
behaviour.

It seems easy to reproduce:
------------
public class DefaultFieldParserTest extends TestCase {
        
    private static final DefaultFieldParser parser = new DefaultFieldParser();
    
        public void testTest() throws MimeException {
                AbstractField.parse("Something: some\r\n");
        }

}
------------
java.lang.NullPointerException
        at 
org.apache.james.mime4j.field.DelegatingFieldParser.parse(DelegatingFieldParser.java:51)
        at 
org.apache.james.mime4j.field.AbstractField.parse(AbstractField.java:171)
        at 
org.apache.james.mime4j.field.AbstractField.parse(AbstractField.java:90)
        at 
org.apache.james.mime4j.field.DefaultFieldParserTest.testTest(DefaultFieldParserTest.java:12)


IMHO it simply something to do with initialization and statics. Is the standard 
chicken vs egg issue.
When from static code you call constructors from other classes you have to 
remember that private variable instances have not yet initialized yet. Usually 
this kind of bug is eved more difficult to find because you don't get an NPE 
but you simply set a value in the instance and then the class initialization 
will overwrite your value. At least here we see a clear NPE.

Let's analyze it:
---
    public DelegatingFieldParser() {
        System.out.println("I: "+defaultParser+"|"+parsers);
        try {
                        throw new Exception();
                } catch (Exception e) {
                        e.printStackTrace();
                }
    }
---

and here is the output:
-----
java.lang.Exception
        at 
org.apache.james.mime4j.field.DelegatingFieldParser.<init>(DelegatingFieldParser.java:36)
I: null|{}
        at 
org.apache.james.mime4j.field.DefaultFieldParser.<init>(DefaultFieldParser.java:24)
        at 
org.apache.james.mime4j.field.AbstractField.<clinit>(AbstractField.java:38)
        at 
org.apache.james.mime4j.field.DelegatingFieldParser.<init>(DelegatingFieldParser.java:30)
        at 
org.apache.james.mime4j.field.DefaultFieldParser.<init>(DefaultFieldParser.java:24)
        at 
org.apache.james.mime4j.field.DefaultFieldParserTest.testTest(DefaultFieldParserTest.java:11)
-----
So when DefaultFieldParser is initialized in fact we have a nested 
initialization
During initialization DefaultFieldParser needs UnstructuredField.PARSER , so 
UnstructuredField must be initialized and it extends AbstractField. 
AbstractField declares a static final DefaultFieldParser 

Mixing static and not static code is a PITA, and this NPE is just a tip of the 
iceberg of issues related with class initialization:
http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19075

> DelegatingFieldParser NPE problem
> ---------------------------------
>
>                 Key: MIME4J-139
>                 URL: https://issues.apache.org/jira/browse/MIME4J-139
>             Project: JAMES Mime4j
>          Issue Type: Bug
>    Affects Versions: 0.6
>         Environment: jre 1.6.11
>            Reporter: Andrzej Rusin
>            Priority: Minor
>   Original Estimate: 0.08h
>  Remaining Estimate: 0.08h
>
> We have custom ContentHandlers that extend AbstractContentHandler and add 
> some custom Fields that extend AbstractField.
> We were getting:
> java.lang.NullPointerException
>  at 
> org.apache.james.mime4j.field.DelegatingFieldParser.parse(DelegatingFieldParser.java:51)
>  at org.apache.james.mime4j.field.AbstractField.parse(AbstractField.java:171)
>  at org.apache.james.mime4j.field.AbstractField.parse(AbstractField.java:63)
>  at 
> org.apache.james.mime4j.message.MessageBuilder.field(MessageBuilder.java:101)
>  at 
> org.apache.james.mime4j.parser.MimeStreamParser.parse(MimeStreamParser.java:121)
>  at org.apache.james.mime4j.message.Message.<init>(Message.java:141)
>  at org.apache.james.mime4j.message.Message.<init>(Message.java:100)
> always AFTER the MimeStreamParser got invoked with our content handlers (so, 
> not on our parsing, but eg. later, on normal 
> new Message(InputStream).
> Looked like we are currupting something inside MimeStreamParser.
> Then I noticed that DelegatingFieldParser.defaultParser is defined as:
> private FieldParser defaultParser = UnstructuredField.PARSER;
> while other field parsers have:
> static final FieldParser PARSER = new FieldParser() {...}
> So I changed DelegatingFieldParser.defaultParser to static final  and the 
> NPEs do not occur anymore.
> I do not undestand exactly why this happens, but that are the facts.
> Is there any reason why DelegatingFieldParser.defaultParser can't be static 
> final?

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to