Michiel Hendriks created SM-4383:
------------------------------------

             Summary: activation-api spec modification to CommandMap leads to 
invalid registrations and memory leak
                 Key: SM-4383
                 URL: https://issues.apache.org/jira/browse/SM-4383
             Project: ServiceMix
          Issue Type: Bug
          Components: specs
    Affects Versions: specs-2.9.0, specs-2.8.0
         Environment: ServiceMix 7.0.1 using 
org.apache.servicemix.specs.activation-api-1.1-2.8.0
            Reporter: Michiel Hendriks


A common way for libraries to register their content handlers is via the 
CommandMap API (rather than using a mailcap file). For example BouncyCastle's 
bcmail does this (a lot).

This is generally done in this way:
{code:java}
CommandMap commandMap = CommandMap.getDefaultCommandMap();
if (commandMap instanceof MailcapCommandMap) {
    ((MailcapCommandMap) commandMap).addMailcap("application/pkcs7-mime;; 
x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime")
}
{code}
This is not a problem with the default MailcapCommandMap implementation. But 
with the overridden MailcapCommandMap, and subclassed OsgiMailcapCommandMap, of 
this spec this leads to a memory clean of duplicate CommandInfo instances, and 
for the OSGi case invalid registrations.

Problem 1, invalid registrations:

For OsgiMailcapCommandMap these programmatically added commands will be 
registered to the last bundle to get its mailcap file registered via the 
Activator: 
[https://github.com/apache/servicemix-specs/blob/master/activation-api-1.1/src/main/java/org/apache/servicemix/specs/activation/OsgiMailcapCommandMap.java#L45]

If the Activator would nullify the "currentBundle" at the end of rebuilding the 
command map, then entries later registered via the CommandMap via code will not 
be associated to the last bundle.

In 
[https://github.com/apache/servicemix-specs/blob/master/activation-api-1.1/src/main/java/org/apache/servicemix/specs/activation/Activator.java#L102]

This would do the trick
{code:java}
commandMap.addMailcap("", null);
{code}
With that in place the call to createDataContentHandler will mostlikely fall 
through to finding the class via the classloader. 

 

Problem 2, memory leak:

In the above example, calling addMailcap with the same value multiple times 
will result in multiple registrations.
{code:java}
commandMap.addMailcap("application/pkcs7-mime;; 
x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime")
commandMap.addMailcap("application/pkcs7-mime;; 
x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime")
// produces 2 entries
{code}
This is sadly a thing bcmail does with signing SMime messages.

With the standard MailcapCommandMap implementation this has no effect as 
duplicated classnames are filtered out and the CommandInfo instance is created 
when on request.

The overridden MailcapCommandMap simply appends every CommandInfo to the list 
without checking for duplicates: 
https://github.com/apache/servicemix-specs/blob/da08e2fd3ad8bdb026e5e655ae474f35638c52eb/activation-api-1.1/src/main/java/javax/activation/MailcapCommandMap.java#L301

 

 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to