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