loading data from REST API fails in action

Post here questions and problems related to oXygen frameworks/document types.
np18
Posts: 11
Joined: Tue Mar 16, 2021 10:01 pm

loading data from REST API fails in action

Post by np18 »

Hi,
I try to write a custom action that allows me to load data into oxygen for further processing by accessing an xquery file on an existdb database using REST. Basically, the xquery returns an xml encoded list of information as tei:list/tei:items that is then displayed in a JDialog. I already used this REST approach in a plugin for oxygenXML and it worked pretty well. But now I want to create an action that can be linked to a button by css.

I am using the following code for querying the information (I only included the relevant parts here):

Code: Select all

...
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
 ...
public class synchWitnesses implements AuthorOperation{
	public void doOperation(AuthorAccess authorAccess, ArgumentsMap args)
			throws IllegalArgumentException, AuthorOperationException {

		HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder()
                    .nonPreemptive()
                    .credentials("User", "PW")
                    .build();
                    
		final Client client = ClientBuilder.newClient();
		client.register(feature);
		String url = "https://url/to/file.xquery";
		WebTarget target = client.target(url);
		String xmlAnswer = target.request().accept(MediaType.TEXT_XML).get(String.class);
			
		// ... ( the rest of the action works fine so I have not included it here)
Now, if I output the received data in the eclipse console where I am developing, everything works and the data is displayed. However, in OxygenXML, the action failed with a 'couldn't load operation' error pop up. I specifically checked multiple times, the rest of the script works, so it must be related to this rest query which works if used in a plug in. Any help or suggestion would be greatly appreciated!
Radu
Posts: 8092
Joined: Fri Jul 09, 2004 5:18 pm

Re: loading data from REST API fails in action

Post by Radu »

Hi,

If in the Oxygen Preferences->"Document Type Associations" page you edit your framework configuration, there is a "Classpath" tab where you should have a reference to the additional JAR libraries necessary for the custom AuthorOperation to work. Did you add references there?
Also, when you run the operation from Eclipse, with what java version do you run it? Is it the same Java version that is used when running Oxygen separately? In the Oxygen main menu Help->About there is a "System properties" tab where you can find out the Java version.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
np18
Posts: 11
Joined: Tue Mar 16, 2021 10:01 pm

Re: loading data from REST API fails in action

Post by np18 »

Dear Radu,
thanks for your reply!

1) I did add the jar file that contains my action (as well as dependencies) to the classpath.
2) The action was compiled using java 8, my Oxygenxml is using 15.0.1. However, switching compilation to java15 did not solve the issue.

Also, the rest of the action works fine, even compiled with java8! If I replace the code above with some hardcoded list of strings, the operation is loaded properly and the pop up dialog is displayed with this list. Only if I include this REST query above, the operation cannot be loaded.

Maybe it has something to do how the dependencies are packaged in my jar file? I just included

Code: Select all

<plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-shade-plugin</artifactId>
      <version>3.0.0</version>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>shade</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
in my pom file to provide all necessary files. Is there a special way, these dependencies have to be packaged?

If you have any further idea, I would be most grateful as I am very much at loss
Radu
Posts: 8092
Joined: Fri Jul 09, 2004 5:18 pm

Re: loading data from REST API fails in action

Post by Radu »

Hi,

About this:
1) I did add the jar file that contains my action (as well as dependencies) to the classpath.
What exact JAR libraries did you refer in the "Classpath" tab from the document type association configuration dialog? Can you list them here?

We need to find out more about what caused that "couldn't load operation" error reported by Oxygen.
What version of Oxygen are you using? On what operating system? Are you using Oxygen XML Editor or XML Author?
In the Oxygen installation folder besides the executable files there should be also files like "oxygen.bat" or "oxygenAuthor.bat", or on Linux/Mac named "oxygen.sh". If you start Oxygen from a Command Prompt (Windows) or Terminal (Mac) or console on Linux using such a scripting file, then try to reproduce the problem you should have in the console which started Oxygen more details about the failure, a stack trace of the exception which caused the problem. If you can paste that stack trace here I could have more details to work with.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
np18
Posts: 11
Joined: Tue Mar 16, 2021 10:01 pm

Re: loading data from REST API fails in action

Post by np18 »

First of, thanks a lot for taking you time to look at this, it is very much appreciated!

So in the classpath I have currently one added the jar file that includes the classes needed for my action which is called 'SyncWitnesses'. The jar file itself is called 'bdd-actions.jar'. This jar file also includes all dependencies.

Now if I include the REST query in my class, I cannot even find the action in the document associations author action panel when trying to create the action in Oxygenxml. If I comment the query part out and repackage, I can choose my class properly and create and use the action in authormode (just without the important data query part). If I then reinclude the query and repackage again, oxygen gives me the following console output when trying to invoke the action:

Code: Select all

13:19:06.002 [AWT-EventQueue-0] ERROR ro.sync.ecss.extensions.j - ro.sync.ecss.extensions.api.ExtensionException: The specified class is not an implementation of ro.sync.ecss.extensions.api.Extension: org.bdd.framework.actions.SyncWitnesses
ro.sync.ecss.extensions.api.ExtensionException: The specified class is not an implementation of ro.sync.ecss.extensions.api.Extension: org.bdd.framework.actions.SyncWitnesses
	at ro.sync.ecss.extensions.b.j(Unknown Source) ~[oxygen.jar:?]
	at ro.sync.ecss.extensions.b.d(Unknown Source) ~[oxygen.jar:?]
	at ro.sync.ecss.extensions.j.r(Unknown Source) ~[oxygen.jar:?]
	at ro.sync.ecss.extensions.j.g(Unknown Source) ~[oxygen.jar:?]
	at ro.sync.ecss.extensions.j.y(Unknown Source) ~[oxygen.jar:?]
	at ro.sync.ecss.extensions.j.performAction(Unknown Source) ~[oxygen.jar:?]
	at ro.sync.ecss.extensions.kb.gyh(Unknown Source) ~[oxygen.jar:?]
	at ro.sync.ui.application.action.r.actionPerformed(Unknown Source) ~[oxygen.jar:?]
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967) ~[?:?]
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308) ~[?:?]
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) ~[?:?]
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) ~[?:?]
	at javax.swing.AbstractButton.doClick(AbstractButton.java:369) ~[?:?]
	at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1012) ~[?:?]
	at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1056) ~[?:?]
	at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297) ~[?:?]
	at java.awt.Component.processMouseEvent(Component.java:6614) ~[?:?]
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3342) ~[?:?]
	at java.awt.Component.processEvent(Component.java:6379) ~[?:?]
	at java.awt.Container.processEvent(Container.java:2263) ~[?:?]
	at java.awt.Component.dispatchEventImpl(Component.java:4990) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2321) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4822) ~[?:?]
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4919) ~[?:?]
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4548) ~[?:?]
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4489) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2307) ~[?:?]
	at java.awt.Window.dispatchEventImpl(Window.java:2769) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4822) ~[?:?]
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:721) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:715) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) ~[?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:745) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:743) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) [?:?]
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:742) [?:?]
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:?]
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) [?:?]

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

Re: loading data from REST API fails in action

Post by Radu »

Hi,

This looks like a Java class loading problem.
So:
So in the classpath I have currently one added the jar file that includes the classes needed for my action which is called 'SyncWitnesses'. The jar file itself is called 'bdd-actions.jar'. This jar file also includes all dependencies.
Can you open that "bdd-actions.jar" JAR library containing all dependencies in Oxygen's "Archive Browser" view (which can be shown from the main menu Window->"Show view" submenu)?
What packages does it contain inside? Does it contain any Oxygen specific "ro.sync" or "com.oxygenxml" packages? If it does, they must not be present there as Oxygen's API is present in the main Oxygen libraries and must not be copied to third party jars.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
np18
Posts: 11
Joined: Tue Mar 16, 2021 10:01 pm

Re: loading data from REST API fails in action

Post by np18 »

Dear Radu,
excellent, I excluded the mentioned dependencies (and a couple of other ones that also caused an error) and now it works!
For the future, is there a way to find in advance which dependencies have to be packaged in the build and which will cause errors?
Many thanks and all the best!
Radu
Posts: 8092
Joined: Fri Jul 09, 2004 5:18 pm

Re: loading data from REST API fails in action

Post by Radu »

Hi,

In order to avoid conflicts a framework configuration's Java extensions live in their own Java class loader which has as a parent class loader the Oxygen main class loader. As you added interfaces like "ro.sync.ecss.extensions.api.Extension" in your custom JAR library, they got loaded using the custom framework class loader, meaning they were no longer considered the same with the same interfaces located in the main Oxygen libraries.
So just avoid to pack in your JAR libraries classes or interfaces which are already present in the Oxygen main libraries. You need Oxygen's classes and interfaces for your project's compilation, but not at runtime.

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