james-mime4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stefano Bagnara (JIRA)" <mime4j-...@james.apache.org>
Subject [jira] Commented: (MIME4J-139) DelegatingFieldParser NPE problem
Date Wed, 04 Nov 2009 00:06:32 GMT

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


Mime
View raw message