StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post here questions and problems related to oXygen frameworks/document types.
jf1
Posts: 5
Joined: Wed May 30, 2018 7:03 pm

StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by jf1 » Wed May 30, 2018 8:11 pm

I have a plugin which wishes to use its own version of Xerces rather than load the one from Oxygen's lib dir.

Code: Select all

<plugin
id="com.oxygenxml.plugin.ProblemWorkspaceAccess"
name="ProblemWorkspaceAccess"
description="Test"
version="${project.version}"
vendor="oXygen XML"
class="com.oxygenxml.sdksamples.workspace.WorkspaceAccessPlugin"
classLoaderType="preferReferencedResources">

<runtime>
<librariesFolder name="lib" />
</runtime>

<extension type="WorkspaceAccess"
class="com.oxygenxml.sdksamples.workspace.CustomWorkspaceAccessPluginExtension"/>

</plugin>
lib contains xercesImpl-2.11.0.jar and xml-apis-1.4.01.jar (I have tried excluding xml-apis).

I have a simple WorkspaceAccessPluginExtension class that adds some menu items

Code: Select all

	@Override
public void applicationStarted(final StandalonePluginWorkspace pluginWorkspaceAccess) {

// Create your own main menu and add it to Oxygen or remove one of Oxygen's
// menus...
pluginWorkspaceAccess.addMenuBarCustomizer(new MenuBarCustomizer() {
/**
* @see ro.sync.exml.workspace.api.standalone.MenuBarCustomizer#customizeMainMenu(javax.swing.JMenuBar)
*/
@Override
public void customizeMainMenu(JMenuBar mainMenuBar) {
final JMenu myMenu = getMainMenu(mainMenuBar);
myMenu.add(createAboutParserMenuAction(pluginWorkspaceAccess));
myMenu.add(createParserMenuAction(pluginWorkspaceAccess));
myMenu.add(createNewEditorMenuAction(pluginWorkspaceAccess));
}
});

}
The function that is causing problems is

Code: Select all

@SuppressWarnings("serial")
private AbstractAction createNewEditorMenuAction(final StandalonePluginWorkspace pluginWorkspaceAccess) {
return new AbstractAction("Open New editor Menu") {
@Override
public void actionPerformed(ActionEvent actionevent) {
try {
URL url = pluginWorkspaceAccess.createNewEditor(".xml", "text/xml", "<someXML/>");
pluginWorkspaceAccess.showInformationMessage("Created editor on " + url + " okay");
} catch (Exception e) {
WorkspaceAccessPlugin.Log.error("Problem executing createNewEditor action", e);
JOptionPane.showMessageDialog((Component) pluginWorkspaceAccess.getParentFrame(),
exceptionToString(e), "Problem executing parse action", JOptionPane.ERROR_MESSAGE);
}
}
};
}
When run this throws the following exception

Code: Select all

org.apache.xerces.impl.dv.DVFactoryException: DTD factory class org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl does not extend from DTDDVFactory.
at org.apache.xerces.impl.dv.DTDDVFactory.getInstance(Unknown Source)
at org.apache.xerces.impl.dv.DTDDVFactory.getInstance(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.<init>(Unknown Source)
at org.apache.xerces.parsers.XIncludeAwareParserConfiguration.<init>(Unknown Source)
at org.apache.xerces.parsers.OxygenPostDTDValidationParserConfiguration.<init>(Unknown Source)
at org.ditang.relaxng.defaults.RelaxDefaultsParserConfiguration.<init>(Unknown Source)
at org.ditang.relaxng.defaults.RelaxDefaultsParserConfiguration.<init>(Unknown Source)
at ro.sync.xml.parser.ParserCreator.newXmlParserConfiguration(Unknown Source)
at ro.sync.xml.parser.ParserCreator.newXmlParserConfiguration(Unknown Source)
at ro.sync.xml.parser.ParserCreator.newXmlParserConfiguration(Unknown Source)
at ro.sync.xml.parser.ParserCreator.e(Unknown Source)
at ro.sync.xml.parser.ParserCreator.createGrammarCachedXMLReader(Unknown Source)
at ro.sync.exml.editor.nc.<init>(Unknown Source)
at ro.sync.exml.editor.nc.<init>(Unknown Source)
at ro.sync.exml.editor.xmleditor.sb.decideInitialPage(Unknown Source)
at ro.sync.exml.editor.vc.setContent(Unknown Source)
at ro.sync.exml.editor.vc.setContent(Unknown Source)
at ro.sync.exml.editor.xmleditor.sb.setContent(Unknown Source)
at ro.sync.exml.editor.zd.ewk(Unknown Source)
at ro.sync.exml.editor.zd.newEditorWithContentType(Unknown Source)
at ro.sync.exml.workspace.b.c.k.createNewEditor(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at ro.sync.exml.workspace.b.d.b$1.invoke(Unknown Source)
at com.sun.proxy.$Proxy13.createNewEditor(Unknown Source)
at com.oxygenxml.sdksamples.workspace.CustomWorkspaceAccessPluginExtension$4.actionPerformed(CustomWorkspaceAccessPluginExtension.java:132)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
Is there any way I can use my own version of Xerces and also call ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace.createNewEditor?

Radu
Posts: 6335
Joined: Fri Jul 09, 2004 5:18 pm

Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by Radu » Thu May 31, 2018 9:45 am

Hi,

Not sure if this works but you could try something like:

Code: Select all

 public void actionPerformed(ActionEvent actionevent) {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(pluginWorkspaceAccess.getClass().getClassLoader());

URL url = pluginWorkspaceAccess.createNewEditor(".xml", "text/xml", "<someXML/>");
pluginWorkspaceAccess.showInformationMessage("Created editor on " + url + " okay");
} catch (Exception e) {
WorkspaceAccessPlugin.Log.error("Problem executing createNewEditor action", e);
JOptionPane.showMessageDialog((Component) pluginWorkspaceAccess.getParentFrame(),
exceptionToString(e), "Problem executing parse action", JOptionPane.ERROR_MESSAGE);
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
because the Xerces classes sometimes use the class loader set on the current thread and this might be the problem.

Otherwise you could avoid completely loading those JAR libraries in our plugin.xml and instead create your own URLClassLoader, load the JAR libraries in it and use it to instantiate the Xerces classes necessary for your code.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

jf1
Posts: 5
Joined: Wed May 30, 2018 7:03 pm

Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by jf1 » Thu May 31, 2018 11:54 am

Hi,

Thankyou for your suggestion about the thread classloader. I have tried it (and had tried something similar in the production code) but it did not work. Using our own classloader was where I was coming from. I had removed it but cannot make the call to createNewEditor work try as I may. I cannot debug further as I do not have your source code. Below is the code from the sample that reproduces the problem. It is derived from your workspace-access plugin and only has minimal changes. Any insights would be appreciated.

Thanks

JF

POM:

Code: Select all

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.oxygenxml.samples</groupId>
<artifactId>oxygen-plugin-workspace-access-problem</artifactId>
<version>1.1.${maven.build.timestamp}</version>

<properties>
<!-- Timestamp of build -->
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
</properties>

<repositories>
<repository>
<id>public</id>
<name>oXygen public artifacts</name>
<url>http://www.oxygenxml.com/maven</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>com.oxygenxml</groupId>
<artifactId>oxygen-sdk</artifactId>
<version>20.0.0.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.oxygenxml</groupId>
<artifactId>oxygen-xercesImpl</artifactId>
</exclusion>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/xerces/xercesImpl -->
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>

<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>

</configuration>
</plugin>

<!-- Copy the runtime dependencies to the lib folder. -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>

<!-- We only want the final JAR package in the target folder so that it's
easier for users to identify it. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<outputDirectory>${project.build.directory}/build</outputDirectory>
<archive>
<manifest>
<addClasspath>false</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>

<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}</directory>
<includes>
<include>addon.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Assembly.xml

Code: Select all

<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>plugin</id>
<formats>
<format>jar</format>
</formats>
<fileSets>
<fileSet>
<directory>target/lib</directory>
<outputDirectory>lib</outputDirectory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>

<files>
<file>
<source>target/build/${project.build.finalName}.jar</source>
<outputDirectory>/lib</outputDirectory>
</file>
<file>
<source>plugin.xml</source>
<outputDirectory>/</outputDirectory>
<filtered>true</filtered>
</file>
</files>
</assembly>

Plugin

Code: Select all

<plugin
id="com.oxygenxml.plugin.ProblemWorkspaceAccess"
name="ProblemWorkspaceAccess"
description="Test"
version="${project.version}"
vendor="oXygen XML"
class="com.oxygenxml.sdksamples.workspace.WorkspaceAccessPlugin"
classLoaderType="preferReferencedResources">

<runtime>
<librariesFolder name="lib" />
</runtime>

<extension type="WorkspaceAccess"
class="com.oxygenxml.sdksamples.workspace.CustomWorkspaceAccessPluginExtension"/>

</plugin>

Addon

Code: Select all

<xt:extensions xmlns:xt="http://www.oxygenxml.com/ns/extension"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oxygenxml.com/ns/extension http://www.oxygenxml.com/ns/extension/extensions.xsd">
<xt:extension xmlns:xt="http://www.oxygenxml.com/ns/extension"
id="com.oxygenxml.plugin.OherWorkspaceAccess">
<xt:location href="${project.build.finalName}-plugin.jar"/>
<xt:version>${project.version}</xt:version>
<xt:oxy_version>17.0+</xt:oxy_version>
<xt:type>plugin</xt:type>
<xt:author>Oxygen XML Editor</xt:author>
<xt:name>OtherCustomWorkspaceAccess</xt:name>
<xt:description><html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Other Sample Workspace Access plugin</title>
</head>
<body>
<div>
<p>This plugin installs access to the <oXygen/> workspace. That enables
<oXygen/> to open/save/close resources, access the editors content,
etc. Such a plugin must implement an WorkspacePluginExtension. </p>
<p>For more details see <a
href="http://www.oxygenxml.com/doc/ug-oxygen/index.html?q=/doc/ug-oxygen/concepts/workspace-access-plugin.html"
>http://www.oxygenxml.com/doc/ug-oxygen/index.html?q=/doc/ug-oxygen/concepts/workspace-access-plugin.html</a>
</p>
</div>
</body>
</html>
</xt:description><xt:license/>
</xt:extension>
</xt:extensions>
WorkspaceAccessPlugin code

Code: Select all

package com.oxygenxml.sdksamples.workspace;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.xerces.jaxp.SAXParserFactoryImpl;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension;
import ro.sync.exml.workspace.api.standalone.MenuBarCustomizer;
import ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace;
import ro.sync.exml.workspace.api.util.XMLUtilAccess;

/**
* Plugin extension - workspace access extension.
*/
public class CustomWorkspaceAccessPluginExtension implements WorkspaceAccessPluginExtension {

/**
* @see ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension#applicationStarted(ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace)
*/
@Override
public void applicationStarted(final StandalonePluginWorkspace pluginWorkspaceAccess) {

// Create your own main menu and add it to Oxygen or remove one of Oxygen's
// menus...
pluginWorkspaceAccess.addMenuBarCustomizer(new MenuBarCustomizer() {
/**
* @see ro.sync.exml.workspace.api.standalone.MenuBarCustomizer#customizeMainMenu(javax.swing.JMenuBar)
*/
@Override
public void customizeMainMenu(JMenuBar mainMenuBar) {
final JMenu myMenu = getMainMenu(mainMenuBar);
myMenu.add(createAboutParserMenuAction(pluginWorkspaceAccess));
myMenu.add(createParserMenuAction(pluginWorkspaceAccess));
myMenu.add(createNewEditorMenuAction(pluginWorkspaceAccess));
}
});

}

private static final String MenuName = "Problem Test Menu";

private static JMenu getMainMenu(JMenuBar mainMenuBar) {
Component[] components = mainMenuBar.getComponents();

final int index = getExistingMenuIndex(components, JMenu.class);
JMenu menu;

if (index >= 0) {
//Menu already exists
menu = (JMenu) components[index];
menu.addSeparator();
} else {
//Create new Menu
menu = new JMenu(MenuName);
menu.setName(MenuName);
// Add your menu before the Help menu
mainMenuBar.add(menu, mainMenuBar.getMenuCount() - 1);
}
return menu;
}

private static int getExistingMenuIndex(Component[] components, Class<?> cls) {
int index = -1;
if (components != null) {
for (int i = 0; index == -1 && i < components.length; i++) {
Component comp = components[i];
String name = comp.getName();
if (cls.isInstance(comp) && name != null && name.equals(MenuName)) {
index = i;
}
}
}
return index;
}

@SuppressWarnings("serial")
private AbstractAction createAboutParserMenuAction(final StandalonePluginWorkspace pluginWorkspaceAccess) {
return new AbstractAction("About Parser Menu") {
@Override
public void actionPerformed(ActionEvent actionevent) {
pluginWorkspaceAccess.showInformationMessage("Xerces version is " + getParserVersion());
}
};
}

@SuppressWarnings("serial")
private AbstractAction createParserMenuAction(final StandalonePluginWorkspace pluginWorkspaceAccess) {
return new AbstractAction("Parse Menu") {
@Override
public void actionPerformed(ActionEvent actionevent) {
try {
File f = createNewFile();
parseFile(f, pluginWorkspaceAccess);
pluginWorkspaceAccess.showInformationMessage("Parsed file " + f.getAbsolutePath() + " okay");
} catch (ParserConfigurationException | SAXException | IOException e) {
WorkspaceAccessPlugin.Log.error("Problem executing parse action", e);
JOptionPane.showMessageDialog((Component) pluginWorkspaceAccess.getParentFrame(),
exceptionToString(e), "Problem executing parse action", JOptionPane.ERROR_MESSAGE);
}
}
};
}

@SuppressWarnings("serial")
private AbstractAction createNewEditorMenuAction(final StandalonePluginWorkspace pluginWorkspaceAccess) {
return new AbstractAction("Open New editor Menu") {
@Override
public void actionPerformed(ActionEvent actionevent) {
//ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
//Thread.currentThread().setContextClassLoader(pluginWorkspaceAccess.getClass().getClassLoader());
URL url = pluginWorkspaceAccess.createNewEditor(".xml", "text/xml", "<someXML/>");
pluginWorkspaceAccess.showInformationMessage("Created editor on " + url + " okay");
} catch (Exception e) {
WorkspaceAccessPlugin.Log.error("Problem executing createNewEditor action", e);
JOptionPane.showMessageDialog((Component) pluginWorkspaceAccess.getParentFrame(),
exceptionToString(e), "Problem executing parse action", JOptionPane.ERROR_MESSAGE);
}finally {
//Thread.currentThread().setContextClassLoader(contextClassLoader);
}
}
};
}

private static String exceptionToString(Throwable t) {
try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
t.printStackTrace(pw);
pw.close();
return sw.toString();
} catch (IOException e) {
return "Unable to write stack trace from " + e.getMessage();
}
}

private static void parseFile(File file, StandalonePluginWorkspace pluginWorkspaceAccess)
throws SAXException, ParserConfigurationException, IOException {
XMLUtilAccess xmlUtil = pluginWorkspaceAccess.getXMLUtilAccess();
XMLReader r = createXMLReader();
r.setEntityResolver(xmlUtil.getEntityResolver());
InputSource source = new InputSource(file.getAbsolutePath());
r.parse(source);
//pluginWorkspaceAccess.createNewEditor("xml", "text/xml", "<stuff/>");
}

private static XMLReader createXMLReader() throws SAXException, ParserConfigurationException {
SAXParserFactoryImpl xerces = new org.apache.xerces.jaxp.SAXParserFactoryImpl();
xerces.setNamespaceAware(true);
return xerces.newSAXParser().getXMLReader();
}

private static String getParserVersion() {
return org.apache.xerces.impl.Version.getVersion();
}

private static File createNewFile() throws IOException {
File f = File.createTempFile("TestOxygen", ".xml");
f.deleteOnExit();
List<String> lines = Arrays.asList("<someXML/>");
Files.write(f.toPath(), lines, StandardCharsets.UTF_8, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
return f;
}

/**
* @see ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension#applicationClosing()
*/
@Override
public boolean applicationClosing() {
// You can reject the application closing here
return true;
}
}

Radu
Posts: 6335
Joined: Fri Jul 09, 2004 5:18 pm

Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by Radu » Thu May 31, 2018 1:28 pm

Hi,

I think that a solution which would imply creating your own class loader to load the conflicting Xerces libraries would look like this:

1) Move the "xercesImpl-2.11.0.jar and xml-apis-1.4.01.jar" JAR libraries from the "lib" folder to a special "lib_xerces" folder (which is not referenced anymore by the plugin's plugin.xml descriptor).

2) Create your own URLClassLoader, load in it the two Xerces libraries and then load the SAXParserFactory from it, something like:

Code: Select all

    File pluginBaseDir = Plugin.getInstance().getDescriptor().getBaseDir();
URL xercesLib1 = new File(pluginBaseDir, "lib_xerces/xercesImpl-2.11.0.jar").toURL();
URL xercesLib2 = new File(pluginBaseDir, "lib_xerces/xml-apis-1.4.01.jar").toURL();
URLClassLoader cl = new URLClassLoader(new URL[] {xercesLib1, xercesLib2}, null);
Class saxParserClazzz = cl.loadClass("org.apache.xerces.jaxp.SAXParserFactoryImpl");
SAXParserFactory factory = saxParserClazzz.newInstance();
//And so on....
By the way, why do you want to use your own Xerces libraries?

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

jf1
Posts: 5
Joined: Wed May 30, 2018 7:03 pm

Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by jf1 » Thu May 31, 2018 3:48 pm

I tried running with -Djaxp.debug=1 -Dxerces.debug=true and looking at the stack trace and looking at the Xerces code.

The bit of the code that is exceptioning is

Code: Select all


    public static final DTDDVFactory getInstance(String factoryClass) throws DVFactoryException {
try {
// if the class name is not specified, use the default one
return (DTDDVFactory)
(ObjectFactory.newInstance(factoryClass, ObjectFactory.findClassLoader(), true));
}
catch (ClassCastException e) {
throw new DVFactoryException("DTD factory class " + factoryClass + " does not extend from DTDDVFactory.");
}
}
so it appears that DTDDVFactory has been loaded from a different classloader than DTDDVFactoryImpl.

The code in org.apache.xerces.impl.dv.ObjectFactory.newInstance reports the classloader it uses, when calling createNewEditor only the load of org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl is reported by Xerces so it looks like it is being called by an XIncludeAwareParserConfiguration instance which was loaded sometime back presumably by a completely different classloader

If I try setting the context classloader to something like Oxygen's ro.sync.basic.classloader.LateDelegationClassLoader using ClassLoader.getParent() or even ClassLoader.getSystemClassLoader() it makes no difference to what is reported by ObjectFactory.newInstance.

So that's it, I guess I will have to return to ignoring Oxygen's class loaders and go back to using our old custom classloader mechanism.

In answer to your question about why we use our own version of Xerces (and Saxon). We do this because our code is tested using particular versions and sometimes has workarounds for those versions. Our code base is large and is mostly called from outside Oxygen. The plugin is an aid for customers who like to work from within oxygen. We cannot control Oxygen's versions therefore we cannot depend on them.

Thanks for your help

JF

jf1
Posts: 5
Joined: Wed May 30, 2018 7:03 pm

Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by jf1 » Fri Jun 01, 2018 12:15 pm

For anyone else with similar problems;

As a last resort (because elsewhere these have proved problematic - xml-apis is an interface which is used by OXyegn and a plugin to pass classes between their 'class worlds', resolver because it completes the classwork of xerces use for the plugin)

[*]I tried making sure that xml-apis was loaded from Oxygen (though the problem class should not be effected by this)
[*]I tried added and removing resolver (again the problem class should not be effected by this)

Code: Select all


<dependencies>
<dependency>
<groupId>com.oxygenxml</groupId>
<artifactId>oxygen-sdk</artifactId>
<version>20.0.0.1</version>
<scope>provided</scope>
<exclusions>
<!-- Compile time exclusions -->
<exclusion>
<groupId>com.oxygenxml</groupId>
<artifactId>oxygen-xercesImpl</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/xerces/xercesImpl -->
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
<exclusions>
<!--Don't package this jar with the plugin; get it from Oxygen -->
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency><!-- https://mvnrepository.com/artifact/xerces/resolver -->
<!-- <dependency>
<groupId>xerces</groupId>
<artifactId>resolver</artifactId>
<version>2.9.1</version>
</dependency> -->
</dependencies>
The only real way to debug this is to have the Oxygen source.

Radu
Posts: 6335
Joined: Fri Jul 09, 2004 5:18 pm

Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by Radu » Mon Jun 04, 2018 2:07 pm

Hi John,

We are planning to release Oxygen 20.1 in a few weeks, I will add an internal issue to find more time after the release to reproduce this on my side, add extra logging in our code and see what causes the problem and if we can fix this on our side.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

jf1
Posts: 5
Joined: Wed May 30, 2018 7:03 pm

Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by jf1 » Mon Jun 04, 2018 2:11 pm

Thanks

Radu
Posts: 6335
Joined: Fri Jul 09, 2004 5:18 pm

Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces

Post by Radu » Thu Mar 14, 2019 2:55 pm

Hi,

Just to update this older discussion thread, I worked on reproducing this problem and in Oxygen 21 if in the plugin.xml you specify this new custom system property:

Code: Select all

<property name="com.oxygenxml.prefer.plugin.classloader.context.loader" value="false"/>
the problem should no longer be reproduce-able.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

Post Reply