Ticket #716 (closed Task: worksforme)

Opened 7 years ago

Last modified 6 years ago

Upgrade the dm4-mail to DM 4.3 and 4.4

Reported by: Malte Owned by: Malte
Priority: Major Milestone:
Component: 3rd Party Plugins Version: 4.3
Keywords: Cc: jri, dgf
Complexity: 3 Area: Application Framework / API
Module:

Description

As we decided that we want to re-animate the dm4-mail plugin I started work on it.

https://github.com/mukil/dm4-mail/commits/master

The latest version on my master branch now builds and runs with DM 4.3 (I have postfix installed locally) but I did not ran into any errors or exceptions thrown by the plugin yet (as foreseen by you) and that makes me suspicious.

In particular (because of #593) the "associatedDefaultSender()" should throw an error at subsequent usage (after mails were sent) or, not?
I could not reproduce this.

I will continue trying to better understand the dm4-mail application model and the plugins code. Will keep you updated.

Attachments

dm4--mail-plugin-screenshot-0.2-SNAP.png (111.1 KB) - added by Malte 7 years ago.
Mail Upgrade Doc. - model revealed and displaying many mails sent

Change History

comment:1 Changed 7 years ago by Malte

  • Component changed from DeepaMehta Standard Distribution to 3rd Party Plugins

comment:2 Changed 7 years ago by Malte

  • Status changed from new to accepted

comment:3 follow-up: ↓ 5 Changed 7 years ago by Malte

As I read now in the pom-file of this proejct, a "feature-complete build" of this mail plugin seems depending on #728.

comment:4 in reply to: ↑ description ; follow-up: ↓ 6 Changed 7 years ago by jri

Replying to Malte:

[...] I did not ran into any errors or exceptions thrown by the plugin yet (as foreseen by you) and that makes me suspicious.

In particular (because of #593) the "associatedDefaultSender()" should throw an error at subsequent usage (after mails were sent) or, not?
I could not reproduce this.

Hi dgf!
Can you help with some info here?

You probably remember the problem that occured once DM 4.1.3 introduced the TopicReferenceModel class (see BREAKING CHANGES in #574). The Mail module (which is compatible only with DM 4.1 to my knowledge) accidentally copied a topic when it was meant to create a reference to an existing topic. Result was a corrupted database (a thing meant to exist once actually exists twice). You filed #593 addressing the underlying problem (which is resolved as wontfix).

What was the exact usage scenario? How can Malte reproduce the problem?
Did you've fixed it already after all?

Thanks
Jörg

comment:5 in reply to: ↑ 3 Changed 7 years ago by jri

Replying to Malte:

As I read now in the pom-file of this proejct, a "feature-complete build" of this mail plugin seems depending on #728.

Yes, the dm4-mail module depends on the dm4-images module. They were developed together by dgf. The Images module is needed in particular with collaborative use, that is a client-server setup. The Images module features image upload and a browsable server-side image repository (integrated with CKEditor). Uploaded images can be (re)used in mail content as well as in (preconfigured) mail signatures. However, I'm not sure if the Images dependency is a hard dependency or an optional dependency.

It's great that you're caring about the Mail module!
:-)

comment:6 in reply to: ↑ 4 Changed 7 years ago by dgf

Replying to jri:

What was the exact usage scenario? How can Malte reproduce the problem?

// https://github.com/mukil/dm4-mail/blob/master/src/main/java/de/deepamehta/plugins/mail/MailPlugin.java#L566
// ..) what is fetched here: the model of an association associated to AssocType sender?
// that would be an "E-Mail Address"-Value (being aggregated to a "Sender"-AssocType)
CompositeValueModel value = sender.getRelatingAssociation().getCompositeValue().getModel();
// making: associateSender(MailTopic, SenderTopic, E-Mail Address Value)?
associateSender(mail.getId(), sender, value, clientState);

// https://github.com/mukil/dm4-mail/blob/master/src/main/java/de/deepamehta/plugins/mail/MailPlugin.java#L603

private Association associateSender(long topicId, Topic sender, CompositeValueModel value, ClientState clientState) {
    return dms.createAssociation(new AssociationModel(SENDER,//
        new TopicRoleModel(sender.getId(), CHILD),//
        new TopicRoleModel(topicId, PARENT), value), clientState);
}

This copy of the sender association composite works in 4.1 but corrupts the database in 4.1.3, see #593

This should be reproducable as follows

  • start with a fresh database
  • configure a default sender in the mail plugin or the admin user account
  • create a new mail (sender copy creates an invalid topic model)
  • restart > corrupt database

To work around this you have to create a new CompositeValueModel with a RelatedTopic that references the E-Mail Address of the sender configuration.

Did you've fixed it already after all?

No

comment:7 Changed 7 years ago by jri

Thank you very much, dgf, for the detailed info!

comment:8 follow-up: ↓ 10 Changed 7 years ago by Malte

Hello all and thanks for your nice efforts to help.

What I can say is when working with 4.3 and the 0.2-SNAPSHOT Mail Plugin built on (or after) the 5th of November one can send many mails and restart DeepaMehta without any visible errors. With "corrupt database" you mean DM4 should not even boot correctly?

What I understood from the application model so far (and please tell me when I am wrong):

  • "Signatures" are the topics to be re-used
  • "Signatures" must be referenced in "Mail"-Topics (optional: in drafts; required: to sent a mail)
  • "Signatures" relate to "Persons" (indirectly via an E-Mail-Address value or directly?)
  • "Signatures" are identified by an "E-Mail Address"-Topic
  • "Mails" will directly relate to "Person" via "Sender" or "Recipient" associations
  • "E-Mail Address"-Topic become aggregate of "Sender" or "Recipient" associations (not the Signature used to send this)
  • "Signature Preview" keeps no important data, it is a dummy topic-type (for solving a custom renderer issue)
  • "Recipients" (dm4.mail.recipient.list) is used to signal if there are more recipients involved or just one.

I will attach a screenshot of my tests and some parts of the application relevant for building a better understanding.

(edited: to be more clear in the statements)

Last edited 7 years ago by Malte (previous) (diff)

comment:9 Changed 7 years ago by Malte

Sorry, attachments do not (yet) work (afer the upgrade) and I created #730.

comment:10 in reply to: ↑ 8 Changed 7 years ago by jri

Replying to Malte:

What I can say is when working with 4.3 and the 0.2-SNAPSHOT Mail Plugin built on (or after) the 5th of November one can send many mails and restart DeepaMehta without any visible errors. With "corrupt database" you mean DM4 should not even boot correctly?

I think "corrupt database" here means that just dm4-mail does not work properly anymore. (Kind of "data ambiguity" exception occurs.)

Furthermore I think the discussed problem is related to this point of dgf's comment:

configure a default sender in the mail plugin or the admin user account

Did you've configured a default sender?
If not the problem will not appear.

A "default sender" is basically the email address that dm4-mail sets as the default "From" address for a newly created Email topic.

See the config sections in the README:
https://github.com/dgf/dm4-mail#configure-global-and-default-mail-preferences
https://github.com/dgf/dm4-mail#configure-user-specific-sender-and-signature

  • "Signature Preview" keeps no important data, it is a dummy topic-type (for solving a custom renderer issue)

The "Signature Preview" is supposed to show the signature currently selected. So, yes, it is just a "placeholder" field for performing custom rendering.
Note: the signature selector (menu) appears between the "From" and "Recipients" fields and is not labelled. You see the signature selector when editing an Email topic.

The "rendering issue" you mention might apply to this: "Signature" (or "Signature Preview"?) is modeled as a "many" relationship (although it is actually an "one" relationship) in order to let dm4-mail provide a custom renderer. Note: while DM has a concept of a "Multi Renderer" it has yet no concept of a "Composite Renderer".

Great, to hear about your progress!

comment:11 follow-up: ↓ 15 Changed 7 years ago by Malte

Yes, I configured a "global" (system-wide) default sender. I also experimented with a user-related "default sender" configuration, both seem to work fine.

I think "corrupt database" here means that just dm4-mail does not work properly anymore. (Kind of "data ambiguity" exception occurs.)

Also after subsequent sending of many "Mail"-Topics no visible error messages are produced - I just keep getting the following message: "Mail was SUCCESSFULLY sent to 1 mail addresses" ...

If no objections come (tests & error messages fly in), I plan to release a dm4-mail SNAPSHOT version for 4.3 within this or next week and then start the upgrade process for 4.4.

Thanks & Cheers.

Changed 7 years ago by Malte

Mail Upgrade Doc. - model revealed and displaying many mails sent

comment:12 Changed 7 years ago by Malte

Now the upload worked fine, thanks dgf.
I will test drive current state of affairs once more and start over with a fresh database.

comment:13 follow-up: ↓ 16 Changed 7 years ago by Malte

Notes for the ticket owner:

  • Removing a "Recipient" from an unsent "Mail"-Topic does not work. Easy to fix.
    DELETE http://localhost:8080/core/association/[object%20Object] 400 (Bad Request) 
    
  • List of recipients does not scroll (how to fix this?)
  • Assigning me (the person which is configured as the system wide default sender) as a recipient returns a Schema violation. Maybe this is what we're digging for, associateRecipient not Sender:
    Nov 12, 2014 9:29:38 AM de.deepamehta.plugins.mail.MailPlugin associateRecipient
    INFORMATION: associate 694145 with recipient address 691000
    Nov 12, 2014 9:29:38 AM de.deepamehta.plugins.webservice.provider.CatchAllExceptionMapper toResponse
    SCHWERWIEGEND: A DeepaMehta resource method or event listener threw an exception resp. an error occurred. Mapping exception/error to response: 500 (Internal Server Error).
    java.lang.RuntimeException: Schema violation: association definition "dm4.contacts.email_address" not found in association type (id=48, uri="dm4.core.association", value="Association", typeUri="dm4.core.assoc_type", dataTypeUri="dm4.core.text", indexModes=[], assocDefs=[], labelConfig=[], view configuration {dm4.webclient.view_config=topic (id=663, uri="", typeUri="dm4.webclient.view_config", value="View Configuration", composite={dm4.webclient.color=topic (id=664, uri="", typeUri="dm4.webclient.color", value="rgb(178, 178, 178)", composite={}), relating association (id=667, uri="", typeUri="dm4.core.composition", value="", composite={},
            topic role (roleTypeUri="dm4.core.child", playerId=664),
            topic role (roleTypeUri="dm4.core.parent", playerId=663))}), relating association (id=671, uri="", typeUri="dm4.core.aggregation", value="", composite={},
            topic role (roleTypeUri="dm4.core.view_config", playerId=663),
            topic role (roleTypeUri="dm4.core.type", playerId=48))})
    	at de.deepamehta.core.impl.AttachedType.getAssocDef(AttachedType.java:152)
    	at de.deepamehta.core.impl.AttachedCompositeValue.getAssocDef(AttachedCompositeValue.java:714)
    	at de.deepamehta.core.impl.AttachedCompositeValue.loadChildTopics(AttachedCompositeValue.java:316)
    	at de.deepamehta.core.impl.AttachedCompositeValue.getTopic(AttachedCompositeValue.java:69)
    	at de.deepamehta.plugins.mail.MailPlugin.getRecipientAssociation(MailPlugin.java:627)
    	at de.deepamehta.plugins.mail.MailPlugin.associateRecipient(MailPlugin.java:120)
    	at de.deepamehta.plugins.mail.MailPlugin.associateRecipient(MailPlugin.java:106)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:606)
    	at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    	at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
    	at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    	at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
    	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    	at com.sun.jersey.server.impl.uri.rules.ResourceObjectRule.accept(ResourceObjectRule.java:100)
    	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    	at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1480)
    	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1411)
    	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360)
    	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350)
    	at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
    	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    	at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:96)
    	at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:79)
    	at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:42)
    	at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:49)
    	at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
    	at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:48)
    	at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:39)
    	at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:654)
    	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:445)
    	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225)
    	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1044)
    	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:372)
    	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:189)
    	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:978)
    	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
    	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    	at org.eclipse.jetty.server.Server.handle(Server.java:369)
    	at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:486)
    	at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:933)
    	at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:995)
    	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
    	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
    	at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668)
    	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
    	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    	at java.lang.Thread.run(Thread.java:745)
    
    Nov 12, 2014 9:29:40 AM de.deepamehta.plugins.mail.MailPlugin associateRecipient
    INFORMATION: associate 694145 with recipient address 691000
    
    
  • To circumvent the following error, on a "localhost" postfix setup, I should just need to enter the tld of the recipients mailbox into my local mail.cnf's "mydestination", and restart postfix, or?
Sending mail FAILED, 
Sending error
Sending the email to the following server failed : localhost:25: Invalid Addresses

comment:14 Changed 7 years ago by Malte

Despite the other errors:

  • After sending two mails and a reboot I still can write and sends new ones.
  • The schema violation seems to be unrelated to "system wide configured default sender as recipient", since I can use "Write Mail" to "Me (Person-Topic)" and the recipient gets correctly (without any schema violation).


comment:15 in reply to: ↑ 11 Changed 7 years ago by jri

Replying to Malte:

If no objections come (tests & error messages fly in), I plan to release a dm4-mail SNAPSHOT version for 4.3 within this or next week and then start the upgrade process for 4.4.

That's good!
Perhaps later dgf can help us even further with detecting the data corruption problem.

comment:16 in reply to: ↑ 13 Changed 7 years ago by jri

Replying to Malte:

  • Assigning me (the person which is configured as the system wide default sender) as a recipient returns a Schema violation.

The exception says that dm4-mail tries to access an Email Address child topic from a regular association (of type "Association").

This might be a content authoring problem: an Association was found when a Recipient was expected.

To make dm4-mail more robust you could change (the loop body in getRecipientAssociation(), line 624)

Association association = dms.getAssociation(recipient.getId(), true);
Topic address = association.getCompositeValue().getTopic(EMAIL_ADDRESS);
if (association.getTypeUri().equals(RECIPIENT) && address.getId() == addressId) {
    return association;
}

to

if (recipient.getTypeUri().equals(RECIPIENT)) {
    Association association = dms.getAssociation(recipient.getId(), true);
    Topic address = association.getCompositeValue().getTopic(EMAIL_ADDRESS);
    if (address.getId() == addressId) {
        return association;
    }
}

That is, accessing the Email Address child topic only if you have actually a Recipient at hand.

Alternatively, you could call comp.has(EMAIL_ADDRESS) before calling comp.getTopic(EMAIL_ADDRESS).

Note: once adapted to DM 4.4 the dms.getAssociation(..., true) call is not necessary anymore as DM 4.4 loads child topics on-demand (the fetchComposite parameters are gone).

comment:17 follow-up: ↓ 18 Changed 7 years ago by Malte

Sorry for bothering you again. From my perspective, what I just need to understand is:
Which Topic Type is the one to be re-used (referenced and not copied) because it must remain unique?

The rest I can most probably figure out myself.
Thanks & Nice greetings.

comment:18 in reply to: ↑ 17 ; follow-up: ↓ 19 Changed 7 years ago by jri

Replying to Malte:

Which Topic Type is the one to be re-used (referenced and not copied) because it must remain unique?

As far as I remember it is the Topic Type "Recipient Type" with its 3 unique instances: To, Cc, and Bcc. These instances are accidentally duplicated.

Try this: edit your "Local Mail Configuration" and choose e.g. "To" as the default recipient type. The default recipient type is the one that is assigned by default when you add a new recipient to a Mail.

A recipient is represented as an association of type "Recipient" between the Mail and a contact. The Recipient association is itself associated with a "Recipient Type" instance via an Aggregation. I guess parts of this aggregation are created by copying the aggregation that is involved in the Mail Configuration (to represent the choosen default recipient type).

Reveal the "Local Mail Configuration" by navigating via he "Mail Configuration" topic type or by searching for e.g. "local". Local Mail Configuration is a singleton instance of "Mail Configuration".

I'm not 100% sure if I'm right with all of this. dgf might know it better.

Did you understood which code dgf is refering to in comment:6?

Last edited 7 years ago by jri (previous) (diff)

comment:19 in reply to: ↑ 18 Changed 7 years ago by jri

Replying to jri:

Did you understood which code dgf is refering to in comment:6?

UPDATE: this must be comment:6 (corrected).

comment:20 Changed 7 years ago by Malte

Danke schön! Now I understand enough to investigate if there is such an issue.
And yes (he referred to his code, forked and commented by me).

Last edited 7 years ago by Malte (previous) (diff)

comment:21 follow-ups: ↓ 22 ↓ 23 Changed 7 years ago by Malte

Identified and fixed three issues:

  • "E-Mail Address"-Topics are re-used across "Sender" and "Recipient" assocations
  • "Signatures" are not copied after users press "Send Again"
  • "Recipient Types" are referenced when users press "Send Again"

Released 4.3 compatible version (everything should be working as expected) at:
http://download.deepamehta.de/nightly/dm43-deepamehta-mail-0.2.1.jar

Upgrading the plugin to DM 4.4 revealed a completely new issue, probably due to new library on the classpath which includes 'javax.activation' or 'mail'.

When attempting to simply send a mail, the following ClassCastException? is thrown:

Help would be very appreciated since I feel a bit lost on where to start with investigating this:

07.12.2014 18:17:43 de.deepamehta.plugins.mail.MailPlugin send
INFO: send mail 3778
07.12.2014 18:17:43 de.deepamehta.plugins.mail.MailConfigurationCache getSmtpHost
INFO: reveal smtp host
DEBUG: JavaMail version 1.4.5
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
07.12.2014 18:17:43 de.deepamehta.plugins.mail.MailPlugin reportException
SCHWERWIEGEND: Sending error: Sending the email to the following server failed : localhost:25: com.sun.mail.handlers.text_plain cannot be cast to javax.activation.DataContentHandler
org.apache.commons.mail.EmailException: Sending the email to the following server failed : localhost:25
	at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1410)
	at org.apache.commons.mail.Email.send(Email.java:1437)
	at de.deepamehta.plugins.mail.MailPlugin.send(MailPlugin.java:453)
	at de.deepamehta.plugins.mail.MailPlugin.send(MailPlugin.java:373)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:622)
	at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
	at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
	at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
	at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	at com.sun.jersey.server.impl.uri.rules.ResourceObjectRule.accept(ResourceObjectRule.java:100)
	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1480)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1411)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350)
	at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:69)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:240)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
	at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:77)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
	at org.eclipse.jetty.server.Server.handle(Server.java:370)
	at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
	at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)
	at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
	at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
	at java.lang.Thread.run(Thread.java:701)
Caused by: java.lang.ClassCastException: com.sun.mail.handlers.text_plain cannot be cast to javax.activation.DataContentHandler
	at javax.activation.MailcapCommandMap.getDataContentHandler(MailcapCommandMap.java:609)
	at javax.activation.MailcapCommandMap.createDataContentHandler(MailcapCommandMap.java:563)
	at javax.activation.DataHandler.getDataContentHandler(DataHandler.java:625)
	at javax.activation.DataHandler.writeTo(DataHandler.java:329)
	at javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:311)
	at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1375)
	at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1021)
	at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:419)
	at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1354)
	at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1021)
	at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:419)
	at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1354)
	at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2107)
	at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2075)
	at javax.mail.Transport.send(Transport.java:123)
	at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1400)
	... 49 more

Thanks & Cheeers!

comment:22 in reply to: ↑ 21 Changed 7 years ago by jri

Replying to Malte:

Identified and fixed three issues:

  • "E-Mail Address"-Topics are re-used across "Sender" and "Recipient" assocations

This is the way it should be, right?

  • "Signatures" are not copied after users press "Send Again"

Do you mean they are referenced instead of copied?
This is the way it should be, right?

  • "Recipient Types" are referenced when users press "Send Again"

This is the way it should be, right?

So, your formulations doesn't describe the error but the fixed state, right?

Great you proceed with the mail plugin!

comment:23 in reply to: ↑ 21 Changed 7 years ago by jri

Replying to Malte:

Upgrading the plugin to DM 4.4 revealed a completely new issue, probably due to new library on the classpath which includes 'javax.activation' or 'mail'.

When attempting to simply send a mail, the following ClassCastException? is thrown:

At the moment I have no clue about that.
I hope dgf can help here.

comment:24 Changed 7 years ago by dgf

The cause of this class loader problems is the pax-web-jetty-bundle bundle provided in the DeepaMehta standard environment. It exports only the root package of JavaMail and I found no way to merge these into other bundles.

Theoretically it doesn't matters and a Import-Package definition should automaticly join exported packages of other bundles with local embedded packages, but I haven't found any combination of Imports/Exports/Embed/... that works in this scenario.

Please have a look at the article OSGi and Classloading from Simon Kitching, it describes very understandable how it should work.

After further research I realised that the features definition of pax-http includes pax-jetty and all required dependencies separatly (e.g. <bundle dependency="true" start-level="30">mvn:javax.mail/mail/1.4.4</bundle>)
see https://repo1.maven.org/maven2/org/ops4j/pax/web/pax-web-features/3.1.2/pax-web-features-3.1.2-features.xml

IMO there are two possible solutions and I prefer the first (cleaner) one

I. use separate bundles

Replacing the pax-web-jetty-bundle in the standard distribution and Pax Runner environment
with an usage of all dependencies as defined in the pax-http and pax-jetty feature.
This results in a fully exported JavaMail API and the dm4-mail bundle just needs to embed extra dependencies

pom.xml

<Embed-Dependency>jsoup,commons-email</Embed-Dependency>

II. local class loader

Temporarilly switch the class loader before using the transport.

MailPlugin.java

String messageId = null;
try {
    messageId = email.send();
} catch (EmailException e) {
    if (e.getCause() instanceof NoSuchProviderException) {
        // retry with local class loader
        ClassLoader threadContext = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        try {
            messageId = email.sendMimeMessage();
        } finally {
            // reuse the original thread class loader
            Thread.currentThread().setContextClassLoader(threadContext);
        }
    } else {
       // rethrow mail exception
       throw e;
    }
}

This requires also an OSGi import of all JavaMail API packages to ensure the class loader merging of ApacheMail and Jsoup in an environment where javax.mail is provided from another bundle (exported packages of an external bundle always hides/overrules local packages).

pom.xml

<Embed-Dependency>jsoup,activation,mail,commons-email</Embed-Dependency>
<Import-Package>
    javax.activation;resolution:=optional,
    javax.mail.internet;resolution:=optional,
    javax.mail;resolution:=optional,
    org.apache.commons.mail;resolution:=optional,
    org.jsoup.nodes;resolution:=optional,
    org.jsoup;resolution:=optional,
    sun.security.util;resolution:=optional,
    *
</Import-Package>

comment:25 Changed 6 years ago by Malte

  • Status changed from accepted to closed
  • Resolution set to worksforme

I implemented option (1) in the following commit (https://github.com/mukil/dm4-mail/commit/84431032906702b00040074d10bfcf5a2ddc0fd1) i and tested dm4-mail-0.3-SNAPSHOT with DM 4.4.x.

The solutiion developed here works for me and will run in every 4.4. installation.

To go on and make a new and final release of d4m-mail (but compatible with 4.6.x) there is a new ticket #822.

Note: See TracTickets for help on using tickets.