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)