0

I have a content navigator plugin through which, I need to send out an email. Plugin is deployed in Websphere and below are the steps I followed.

  1. Created a mail provider in WAS
  2. Created mail session and selected 'smtp' as the protocol

I have a java code which sends out email

Context context = new InitialContext(); 
Session mailSession = (Session)context.lookup("mail/mySession"); 
Message msg = new MimeMessage(mailSession); 
msg.setFrom(new InternetAddress(email)); msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(destinationAddress)); 
// Set the subject and body text 
msg.setSubject(subject); 
msg.setText(messageBody); 
// send message 
Transport.send(msg);

I'm getting error as

java.lang.ClassCastException: javax.mail.Session incompatible with javax.mail.Session

My webpshere (C:\IBM\WebSphere\AppServer\lib)by default has mailapi.jar. Even navigator.war and taskManagerWeb.war also has the same jar. I think the issue is due to having multiple jars within the same websphere. Can anyone help me on how to solve this issue?

2
  • From what I remember, we tried to implement mail from ICN and eventually gave up in favour of mail from FileNet. If it is possible, I would suggest looking to see if FileNet (or PE) could provide the notification. Commented Jun 29, 2017 at 2:53
  • @Christopher Powell, thanks for your suggestion. Though the feature is in ICN, it doesn't use CPE. I will try some more options and see how it goes.
    – bajji
    Commented Jun 29, 2017 at 15:45

4 Answers 4

0

Since WebSphere is a Java EE product, it should have a full JavaMail implementation included in it. You shouldn't need to include any JavaMail jar files in your application.

5
  • @ Bill, Thanks for the comment. I have not included mailapi.jar in navigator.war and taskManagerWeb.war. These are the default apps that get installed as part of IBM Content Navigator and they have this jar in them.
    – bajji
    Commented Jun 27, 2017 at 20:59
  • Sounds like they're broken. They should not be included. Contact IBM Support. Commented Jun 27, 2017 at 21:01
  • thanks again. Is there a way to skip loading the jar files within the IBM Apps and use the default websphere one? or even if those jar files are loaded, is there a way I can pick and chose the jar which I want to use in my code?
    – bajji
    Commented Jun 27, 2017 at 21:06
  • I don't know, I'm not a WebSphere expert. Commented Jun 27, 2017 at 21:07
  • The jar used is based on the class loader delegation mode for the WAR - if it's PARENT_LAST, it will load from WAR libraries first; if it's PARENT_FIRST, it'll load from WebSphere libraries first - PARENT_FIRST is what you want. In this case, though, I'm thinking the issue is the mail session, not the WAR (particularly if you haven't explicitly adjusted class loader settings in the app). Did you specify that mail API jar in the class path of your mail session resource? That might be the issue.
    – Jarid
    Commented Jun 28, 2017 at 13:33
0

It's been a while, but i ran into the same problem a long time ago. I finally came to the conclusion that Navigator includes it's own javax.mail - and as your plugin is loaded by an ad-hoc navigator-created parent-last classloader, it will not be able to match the EE javax.mail.session to the javax.mail.session found by the plugin classloader.

I'd suggest one of the following two solutions:

  1. Move your mail functionality outside of the navigator plugin. E.g. Create an EJB that performs your functionality, and from within your plugin inject/lookup the EJB.
  2. Use the Navigator mail session instead of the Websphere mail-session.

Two additional alternatives:

  1. Don't do the typecasting and use reflection. I'm unsure though if you'll be able to locate the right MimeMessage constructor with reflection using the wrong class.

  2. E-mail from the CPE using a code-module. While the problem you described actually applies for the CPE as well, it would give you the choice of using either the PE configured or CE configured mail sessions.

0

You can configure CNMAIL to use java mail but it will not work with Office 365 and Modern Authentication. I opened a support ticket and asked if there was any out of the box solution and IBM's full and complete response is below:

"There is no out of the box ICN solution for this"

Microsoft does report now having javascript and java libraries to support modern authentication which might support a plugin. Other option would be to disable the menu item and user would then have to download and attach to an email manually. Here is the link wrt modern auth and javascript/java:

https://devblogs.microsoft.com/microsoft365dev/microsoft-authentication-libraries-for-java-and-python-are-now-generally-available/

-1

The following code might help you. Please note that I commented the code to help you use the solution.

 **- **RecoveryBin.js****
require([ "dojo/_base/declare", "dojo/_base/lang", "ecm/model/Request",
        "ecm/model/ResultSet", "recoveryBeanDojo/BestDialog",
        "ecm/widget/ComboBox", "dojo/domReady!" ], function(declare, lang,
        Request, ResultSet, BestDialog, ComboBox) {
    /**
     * Use this function to add any global JavaScript methods your plug-in requires.
     */
    lang.setObject("moveToRB", function(repository, items, callback, teamspace,
            resultSet, parameterMap) {
        /*
         * Add custom code for your action here. For example, your action might launch a dialog or call a plug-in service.
         */
        // Iterating items array --- {d0c1},{doc2}
        var itemsList="";
        console.log("Number of selected documents -- "+ items.length);
        for(var j=0;j<items.length;j++)
        {
            itemsList=itemsList+items[j].id+",";
            console.log("Item is --"+itemsList);
        }
        console.log("New Items String is ---- "+itemsList);
        var bestDialog = null;
        var serviceParams = {
            icnRepository : repository.id,
            serverType : repository.type,
        //  s : items[0].id,
            s : itemsList,
        };

        Request.invokePluginService("RecoveryBean", "MoveToRBService", {

            requestParams : serviceParams,

            requestCompleteCallback : lang.hitch(this, function(response) {
                var rb;
                for (var i = 0; i < response.rb.length; i++) {
                    rb = response.rb[i];
                }// success*/
                console.log("Before New Dialog ");
                bestDialog = new BestDialog();
                //bestDialog.setContentItem(items[0]);
                bestDialog._show(rb, repository, items);
                bestDialog.show();
                console.log("After bin Dialog");

            })

        });
    });
});

**

 - BestDialog.js

**

define([ "dojo/_base/declare", "ecm/widget/dialog/BaseDialog",
        "dijit/form/CurrencyTextBox", "dojo/currency", "ecm/model/ContentItem",
        "dojo/store/Memory", "ecm/model/Request", "ecm/model/ResultSet",
        "dijit/layout/ContentPane", "dojo/dom-attr",
        "ecm/widget/layout/_RepositorySelectorMixin",
        "ecm/widget/listView/ContentList", "ecm/model/Desktop",
        "dojo/_base/lang", "ecm/widget/ComboBox",
        "dojo/text!./templates/BestDialog.html" ], function(declare,
        BaseDialog, CurrencyTextBox, currency, ContentItem, MemoryStore,
        Request, ResultSet, ContentPane, domAttr, _RepositorySelectorMixin,
        ContentList, Desktop, lang, ComboBox, template) {

    /**
     * @name sampleICNPluginDojo.BestDialog
     * @class Provides a dialog that demonstrates the right thing to do. 
     * @augments ecm.widget.BaseDialog
     */
    return declare("newPluginDojo.BestDialog", [ BaseDialog ], {
        /** @lends sampleICNPluginDojo.BestDialog.prototype */

        contentString : template,
        widgetsInTemplate : true,
        contentItem : null,
        _repository : null,
        _items : null,
        itemsList:null,
        _binlist : null,        
        postCreate : function() {
            console.log("Inside BestDialog.js:: postCreate ");
            this.inherited(arguments);
            this.setTitle("Recovery - Beans");

            this.okButton = this.addButton("Ok", "_okClick", false, true);
        },
        _okClick : function() {
            console.log("Inside BestDialog.js:: _okClick ");
            var n = this._binlist.value;

            var serviceParams = {

                icnRepository : this._repository.id,
                serverType : this._repository.type,
                s : this.itemsList,
                rbName : n
            };
            Request.invokePluginService("RecoveryBean", "RecoveryService", {

                requestParams : serviceParams,
                requestCompleteCallback : lang.hitch(this, function(response) {

                    var bestDialog = new BaseDialog();
                    bestDialog.set("title", "Deleted Items Bean");
                    bestDialog.set("content","Document Are Successfully Moved To Recycle Bin");
                    bestDialog.show();
                    console.log("After Recovery Service Dialog");

                })

            });
            this.hide();
            this.destroyRecursive(); // Destroys all child widgets as well
        },

        onCancel : function() {
            this.destroyRecursive();
        },
        // Method responsible to show dialog box:- Documented by Ashok
        _show : function(rb, repository, items) {
            console.log("inside show ");
            this._repository = repository;
            this._items = items;
            this._rb = rb;
            var item = [];

            for ( var key in rb) {
                item.push({
                    "id" : rb[key],
                    "name" : key
                });
                console.log(key + ":" + rb[key]);
            }

            // Create test store.
            comboStore = new MemoryStore({
                data : item
            });
            this._binlist = this.binlist;
            this._binlist.store = comboStore;

            console.log("Completed");

        }

    });
});

**MoveToRBService.java**

package com.ibm.demo;

import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;

import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.filenet.api.collection.CmRecoveryItemSet;
import com.filenet.api.collection.EventSet;
import com.filenet.api.collection.IndependentObjectSet;
import com.filenet.api.constants.RefreshMode;
import com.filenet.api.core.Document;
import com.filenet.api.core.Factory;
import com.filenet.api.core.ObjectStore;
import com.filenet.api.core.VersionSeries;
import com.filenet.api.events.Event;
import com.filenet.api.query.SearchSQL;
import com.filenet.api.query.SearchScope;
import com.filenet.api.util.CmRecoveryBin;
import com.filenet.api.util.CmRecoveryItem;
import com.filenet.api.util.Id;
import com.filenet.api.util.UserContext;
import com.ibm.ecm.extension.PluginResponseUtil;
import com.ibm.ecm.extension.PluginService;
import com.ibm.ecm.extension.PluginServiceCallbacks;
import com.ibm.ecm.json.JSONMessage;
import com.ibm.ecm.json.JSONResponse;
import com.ibm.ecm.json.JSONResultSetResponse;
import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;

/**
 * Provides an abstract class that is extended to create a class implementing
 * each service provided by the plug-in. Services are actions, similar to
 * servlets or Struts actions, that perform operations on the IBM Content
 * Navigator server. A service can access content server application programming
 * interfaces (APIs) and Java EE APIs.
 * <p>
 * Services are invoked from the JavaScript functions that are defined for the
 * plug-in by using the <code>ecm.model.Request.invokePluginService</code>
 * function.
 * </p>
 * Follow best practices for servlets when implementing an IBM Content Navigator
 * plug-in service. In particular, always assume multi-threaded use and do not
 * keep unshared information in instance variables.
 */
public class MoveToRBService extends PluginService {
    public static final String REPOSITORY_ID = "icnRepository";
    public static final String REPOSITORY_TYPE = "serverType";

    /**
     * Returns the unique identifier for this service.
     * <p>
     * <strong>Important:</strong> This identifier is used in URLs so it must
     * contain only alphanumeric characters.
     * </p>
     * 
     * @return A <code>String</code> that is used to identify the service.
     */
    public String getId() {
        return "MoveToRBService";
    }

    /**
     * Returns the name of the IBM Content Navigator service that this service
     * overrides. If this service does not override an IBM Content Navigator
     * service, this method returns <code>null</code>.
     * 
     * @returns The name of the service.
     */
    public String getOverriddenService() {
        return null;
    }

    /**
     * Performs the action of this service.
     * 
     * @param callbacks
     *            An instance of the <code>PluginServiceCallbacks</code> class
     *            that contains several functions that can be used by the
     *            service. These functions provide access to the plug-in
     *            configuration and content server APIs.
     * @param request
     *            The <code>HttpServletRequest</code> object that provides the
     *            request. The service can access the invocation parameters from
     *            the request.
     * @param response
     *            The <code>HttpServletResponse</code> object that is generated
     *            by the service. The service can get the output stream and
     *            write the response. The response must be in JSON format.
     * @throws Exception
     *             For exceptions that occur when the service is running. If the
     *             logging level is high enough to log errors, information about
     *             the exception is logged by IBM Content Navigator.
     */
    public void execute(PluginServiceCallbacks callbacks, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        String repositoryId = request.getParameter(REPOSITORY_ID);
        String repositoryType = request.getParameter(REPOSITORY_TYPE);
        JSONResponse jsonResponse = new JSONResponse();
        ObjectStore objectStore = null;
        JSONObject jsonObject = new JSONObject();
        JSONObject finalJsonObj = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        CmRecoveryBin bin = null;
        try {
            if (repositoryType.equals("p8")) {
                Subject subject = callbacks.getP8Subject(repositoryId);
                UserContext.get().pushSubject(subject);
                System.out.println("in first if");
            }
            Object synchObject = callbacks.getSynchObject(repositoryId, repositoryType);
            if (synchObject != null) {
                synchronized (synchObject) {
                    if (repositoryType.equals("p8")) {
                        System.out.println(" synchObject Value :Ashok"+ synchObject.toString());
                        System.out.println("in synchronised block");
                        objectStore = callbacks.getP8ObjectStore(repositoryId);

                        System.out.println("ObjectStore!!!!!!!!!123" + objectStore.get_DisplayName());
                    }
                }
                SearchSQL sqlObject = new SearchSQL("select * from CmRecoveryBin");
                SearchScope searchScope = new SearchScope(objectStore);
                Integer myPageSize = new Integer(1000);
                Boolean continuable = Boolean.valueOf(true);
                IndependentObjectSet binSet = searchScope.fetchObjects(sqlObject, myPageSize, null, continuable);

                // Iterate the set of recovery bins.
                Iterator iterOuter = binSet.iterator();

                while (iterOuter.hasNext()) {
                    bin = (CmRecoveryBin) iterOuter.next();
                    System.out.println("\nRecovery bin: " + bin.get_DisplayName() + "   ID: " + bin.get_Id());
                    jsonObject.put(bin.get_DisplayName(), bin.get_Id().toString());
                    jsonArray.add(jsonObject);
                }

                finalJsonObj.put("rb", jsonArray);
                System.out.println("in cache control!!!!!!!!!!!!!!");
                response.addHeader("Cache-Control", "no-cache");
                response.setContentType("text/plain"); // must be text/plain for
                                                        // firebug
                response.setCharacterEncoding("UTF-8");
                Writer writer = response.getWriter();
                writer.write(finalJsonObj.toString());
                System.out.println("Printing results = " + finalJsonObj.toString());

            }

        } catch (Exception exc) {
            JSONMessage message = new JSONMessage(0,
                    "The document could not be retrieved.  Details have been written to the server error log.", null,
                    null, null, null);
            jsonResponse.addErrorMessage(message);
            exc.printStackTrace();
        }

    }
}


**BestDialog.html**
<div>
<select data-dojo-type="ecm/widget/ComboBox" data-dojo-attach-point="binlist"></select></div>
1
  • Sorry, I can't understand how this helps me in solving the issue that I reported. Did you by mistake post your answer to the wrong thread?
    – bajji
    Commented Aug 9, 2017 at 19:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.