Hi Stephan,

I think the dynamic import is a nice workaround short term.

I think 3 (with a handler) is more robust long term. WDYT ?

Regards
JB

On 11/02/2019 12:35, Siano, Stephan wrote:
> Hi,
> 
> A little more than a week ago I wrote about an issue about an interference 
> between the way javax.activation is installed on Karaf 4.2.3 for Java 8, and 
> the Javamail and the saaj-impl 1.3.1 bundles and the way they expose MIME 
> handlers, which resulted in a ClassCastException. In the meantime 
> Jean-Baptiste has released a new servicemix wrapper for saaj-impl 1.4.0 
> (1.4.0_2), and with this bundles the ClassCastException goes away (many 
> thanks for that!).
> 
> I have created some test coding for the issue:
> 
> A:
>             Session session = Session.getInstance(System.getProperties());
>             MimeMessage message = new MimeMessage(session);
>             message.setSubject("Testing Subject");
>             message.addHeader("X-Test-Header", "test value");
>             MimeMultipart mp = new MimeMultipart("mixed");
>             BodyPart part = new MimeBodyPart();
>             part.setText("Test body");
>             mp.addBodyPart(part);
>             message.setContent(mp);
>             message.saveChanges();
>             ByteArrayOutputStream bos = new ByteArrayOutputStream();
>             message.writeTo(bos);
> 
> B:
>             MessageFactory messageFactory = MessageFactory.newInstance();
>             SOAPMessage message = messageFactory.createMessage();
>             AttachmentPart attachmentPart = message.createAttachmentPart();
>             attachmentPart.setContentId("contentid");
> 
> On the first glance this seems to work now, I can invoke coding A and coding 
> B in arbitrary order. However, as soon as I have another bundle in the stack 
> that contains a mailcap file and is installed after the javamail bundle, code 
> A will start to fail again after B was invoked. (It will work fine before 
> that). The new error is now that there is no MIME handler registered for 
> text/plain
> 
> I think the root cause for the issue is in the OsgiMailcapCommandMap class.
> 
> If a bundle contains a mailcap file, the extender from the 
> org.apache.servicemix.specs.activation-api-1.1 bundle will call the 
> addMailcap(String line, Bundle bundle) method, which will set the 
> currentBundle attribute and then call addMailcap(String line) from the 
> superclass. Eventually the addCommand() method will be called, which will add 
> the current bundle to the bundles map (with the command as the key). Later in 
> the createDataContentHandler() method this map will be used to look up the 
> bundle and MIME handler is instantiated from the bundle classloader of that 
> bundle.
> 
> This works fine for all MIME handler registered via mailcap file. 
> Unfortunately, the constructor of 
> com.sun.xml.messaging.saaj.soap.AttachmentPartImpl (which is called by the 
> message.createAttachmentPart() call) will just call the addMailcap(String 
> line) method on the default command map, so the currentBundle attribute is 
> not updated and the MIME handlers are registered with the last bundle that 
> registered a MIME handler from a mailcap file. In the first case this is 
> javamail. This even works because the javamail bundle has a 
> "DynamicImport-Package: *" in it's Manifest, so the javamail classloader is 
> actually able to load the MIME handlers from saaj-impl.
> 
> The dirty workaround for this is to add the DynamicImport-Package: * manifest 
> header to all bundles with a mailcap file, but eventually I think the 
> org.apache.servicemix.specs.activation-api-1.1 should be fixed.
> 
> The first solution that comes into my mind would be the following:
> 
>   1.  change the addMailcap(String line, Bundle bundle) method of 
> OsgiMailcapCommandMap in a way that it sets currentBundle to null after 
> calling the addMailcap(line) method. This way the addCommand() method will 
> not add anything to the bundles map for it.
>   2.  Add the DynamicImport-Package: * header to the bundle manifest file. 
> This will allow OsgiMailcapCommandMap to load all Mime handler without 
> registered bundle which point to exported classes with its own ClassLoader.
>   3.  change the createDataContentHandler(String mimeType) to try to load the 
> MIME Handler with its own class loader if no bundle is found before trying 
> the ThreadContextClassloader.
> 
> Alternatively one might try to find out the bundle somehow in the 
> addCommand() method, but I have no good idea how to do that.
> 
> What do you think?
> 
> Best regards
> Stephan
> 

-- 
Jean-Baptiste Onofré
jbono...@apache.org
http://blog.nanthrax.net
Talend - http://www.talend.com

Reply via email to