Page 1 of 1

JS Plugin causes java.lang.ClassCastException when Oxygen is closed.

Posted: Wed Jun 05, 2019 3:59 pm
by AndreasM
Hello,
i've been noticing an odd exception while testing a JS plugin I wrote.
The plugin handles a custom save behaviour (using the editorAboutToBeSavedVeto method). The plugin itself works as expected and without errors.
But, when Oxygen XML Editor is closed while this plugin is active(no matter if an editor is still open or not), this exception is thrown:

Code: Select all

java.lang.ClassCastException: org.mozilla.javascript.UniqueTag cannot be cast to org.mozilla.javascript.Function
	at ro.sync.exml.plugin.WorkspaceAccessOverJSPluginExtension.callFunction(Unknown Source)
	at ro.sync.exml.plugin.WorkspaceAccessOverJSPluginExtension.applicationClosing(Unknown Source)
	at ro.sync.exml.MainFrame$54.applicationWillBeClosedOrHidden(Unknown Source)
	at ro.sync.exml.MainFrame.ecn(Unknown Source)
	at ro.sync.exml.MainFrame.kcn(Unknown Source)
	at ro.sync.exml.MainFrame.kbn(Unknown Source)
	at ro.sync.exml.MainFrame.jjf(Unknown Source)
	at ro.sync.exml.MainFrame.handleQuit(Unknown Source)
	at ro.sync.ui.application.b.hif(Unknown Source)
	at ro.sync.ui.application.b.njf(Unknown Source)
	at ro.sync.ui.application.b$2.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
	at java.awt.Window.processWindowEvent(Unknown Source)
	at javax.swing.JFrame.processWindowEvent(Unknown Source)
	at java.awt.Window.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$500(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)
I can not figure out what it is in my plugin that causes this. Maybe someone can help.
Here the full code of my plugin:

Code: Select all


function applicationStarted(pluginWorkspaceAccess) {
   Packages.java.lang.System.err.println("Application started " + pluginWorkspaceAccess);
   var edChangedListener = {
      editorOpened: function (editorLocation) {        
         var editor = pluginWorkspaceAccess.getEditorAccess(editorLocation, Packages.ro.sync.exml.workspace.api.PluginWorkspace.MAIN_EDITING_AREA);
         
         preSaveListener = {

            /* Called when a document is about to be Saved */
            editorAboutToBeSavedVeto: function (operationType) {
               if (operationType == Packages.ro.sync.exml.workspace.api.listeners.WSEditorListener.SAVE_OPERATION) {
                  /* Access root Element of Document and read oxyFramework attribute*/
                  str = editor.createContentInputStream();
                  reader = new Packages.java.io.InputStreamReader(str, "UTF-8");
                  is = new Packages.org.xml.sax.InputSource(reader);
                  is.setEncoding("UTF-8");
                  dbf = new Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
                  db = dbf.newDocumentBuilder();
                  doc = db.parse(is);
                  rootElement = doc.getDocumentElement();
                  OxyFrame = rootElement.getAttribute("hal:oxyFramework");
                  ID = rootElement.getAttribute("xml:id")
                  IDarr = ID.split("_");

                  //javax.swing.JOptionPane.showMessageDialog(null, ID);
                  /* If document is not part of hallerNet, abort and return to default save behaviour */
                  if (OxyFrame != "true") {
                     //"return 'true'" triggers default save function
                     return true;
                  }

                  /* Ask the User if customSave should be performed, otherwise return to deault save behaviour */
                  if (javax.swing.JOptionPane.showConfirmDialog(null,
                        "Dokument auf data.hallernet.org speichern?", "Warning", javax.swing.JOptionPane.YES_NO_OPTION) == javax.swing.JOptionPane.NO_OPTION) {
                     // Wenn "Nein" ausgewählt wird. "return 'true'" triggers default save function
                     return true;
                  } else {
                     // perform save operation at determined path
                     dirType = IDarr[0] + "s";
                     dirNum = IDarr[1].substring(0, 3);
                     chosenURL = new Packages.java.net.URL("http://data.hallernet.org/db-sandbox-cceh/" + dirType + "/" + dirNum + "/" + ID + ".xml");
                     editor.saveAs(chosenURL);

                    
                     return false;
                  }
               }
               return true;
            }
         }




         preSaveListener = new JavaAdapter(Packages.ro.sync.exml.workspace.api.listeners.WSEditorListener, preSaveListener);
         if (editor != 0) {
            editor.addEditorListener(preSaveListener);

         }
      }
   }
   var edChangedListenerAdapter = new JavaAdapter(Packages.ro.sync.exml.workspace.api.listeners.WSEditorChangeListener, edChangedListener);
   /* Add the editor changed listener */
   pluginWorkspaceAccess.addEditorChangeListener(
      edChangedListenerAdapter,
      Packages.ro.sync.exml.workspace.api.PluginWorkspace.MAIN_EDITING_AREA);
}


Thank you

Re: JS Plugin causes java.lang.ClassCastException when Oxygen is closed.

Posted: Thu Jun 06, 2019 10:52 am
by Radu
Hi Andreas,

Please add to your Javascript file also this function:

Code: Select all

function applicationClosing(pluginWorkspaceAccess) {
}
because Oxygen tries to call it when it is closing and as it is not there, it issues that error.
I will make changes in our code so that we never throw that strange error when that particular method is missing from the Javascript file.

Regards,
Radu