[
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.