Uploaded image for project: 'ServiceMix'
  1. ServiceMix
  2. SM-4383

activation-api spec modification to CommandMap leads to invalid registrations and memory leak

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • specs-2.8.0, specs-2.9.0
    • activation-api-1.1_1
    • specs
    • None
    • ServiceMix 7.0.1 using org.apache.servicemix.specs.activation-api-1.1-2.8.0

    Description

      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:

      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")
      }
      

      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

      commandMap.addMailcap("", null);
      

      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.

      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
      

      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

       

       

      Attachments

        Activity

          People

            jbonofre Jean-Baptiste Onofré
            elmuerte Michiel Hendriks
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 20m
                20m