StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
Post here questions and problems related to oXygen frameworks/document types.
-
- Posts: 5
- Joined: Wed May 30, 2018 7:03 pm
StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
I have a plugin which wishes to use its own version of Xerces rather than load the one from Oxygen's lib dir.
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
The function that is causing problems is
When run this throws the following exception
Is there any way I can use my own version of Xerces and also call ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace.createNewEditor?
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>
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));
}
});
}
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);
}
}
};
}
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)
-
- Posts: 9424
- Joined: Fri Jul 09, 2004 5:18 pm
Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
Hi,
Not sure if this works but you could try something like:
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
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);
}
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
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 5
- Joined: Wed May 30, 2018 7:03 pm
Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
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:
Assembly.xml
Plugin
Addon
WorkspaceAccessPlugin code
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>
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>
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;
}
}
-
- Posts: 9424
- Joined: Fri Jul 09, 2004 5:18 pm
Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
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:
By the way, why do you want to use your own Xerces libraries?
Regards,
Radu
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....
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 5
- Joined: Wed May 30, 2018 7:03 pm
Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
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
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
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.");
}
}
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
-
- Posts: 5
- Joined: Wed May 30, 2018 7:03 pm
Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
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)
The only real way to debug this is to have the Oxygen source.
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>
-
- Posts: 9424
- Joined: Fri Jul 09, 2004 5:18 pm
Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
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
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
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 9424
- Joined: Fri Jul 09, 2004 5:18 pm
Re: StandalonePluginWorkspace.createNewEditor from Plugin with own Xerces
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:
the problem should no longer be reproduce-able.
Regards,
Radu
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"/>
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
Return to “SDK-API, Frameworks - Document Types”
Jump to
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ SDK-API, Frameworks - Document Types
- ↳ DocBook
- ↳ TEI
- ↳ XHTML
- ↳ Other Issues
- Oxygen XML Web Author
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Content Fusion
- ↳ Feature Request
- ↳ Common Problems
- Oxygen JSON Editor
- ↳ Feature Request
- ↳ Common Problems
- Oxygen PDF Chemistry
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Feedback
- ↳ Feature Request
- ↳ Common Problems
- Oxygen XML WebHelp
- ↳ Feature Request
- ↳ Common Problems
- XML
- ↳ General XML Questions
- ↳ XSLT and FOP
- ↳ XML Schemas
- ↳ XQuery
- NVDL
- ↳ General NVDL Issues
- ↳ oNVDL Related Issues
- XML Services Market
- ↳ Offer a Service