Avoiding UnsupportedOperationException by unwrapping externalPtr?

4 views
Skip to first unread message

Per Nyfelt

unread,
Mar 8, 2020, 8:22:34 AM3/8/20
to Renjin
Hi,

I am trying to use more complex java java libraries directly in Renjin but are running into issues with UnsupportedOperationExceptions.

The following example results in a java.lang.UnsupportedOperationException. It looks like this is because the comment object that was created looks like an externalPtr to the rootElement$addContent() method and hence it is not recognized:

import(org.jdom2.Document)
import(org.jdom2.Element)
import(org.jdom2.Comment)

doc
<- Document$new()
rootElement
<- Element$new("Root");
doc$setRootElement
(rootElement);

comment
<- Comment$new("This is a comment");
rootElement$addContent
(comment);

Is is possible to explicitly unwrap the comment object so that the java method can be called directly?

I looked in the code and found org.renjin.invoke.reflection.converters.ObjectConverter.

This makes it work more often:
rootElement$addContent(ObjectConverter$INSTANCE$convertToJava(comment))

What is even more wonderful (but strange) is that the mere presence of 
import(org.renjin.invoke.reflection.converters.ObjectConverter)

...magically makes the code work!

import(org.jdom2.Document)
import(org.jdom2.Element)
import(org.jdom2.Comment)
import(org.jdom2.Attribute)

import(org.renjin.invoke.reflection.converters.ObjectConverter)

doc
<- Document$new()
print("#Create root element")
rootElement
<- Element$new("Root");
doc$setRootElement
(rootElement);

print("#add a comment")
comment
<- Comment$new("This is a comment");
# No need for this as the import is enough
#rootElement$addContent(ObjectConverter$INSTANCE$convertToJava(comment))
rootElement$addContent
(comment);

print("# add child")
child1
<- Element$new("child");
child1$addContent
("This is child 1");

print("# add attribute")
attr1
<- Attribute$new("key1", "value1");
child1$setAttribute
(attr1);
rootElement$addContent
(child1);

I verified it on both 0.9.2726 and 3.5-beta76 and the behavior seems to be identical.

However the behavior is intermittent in the sense that "sometimes" I see get the UnsupportedOperationException but if I just do "mvn clean install" a few times the problem goes away. It looks like some kind of timing issue since the UnsupportedOperationException occurs on different places from one time to another and sometimes not at all. 

When adding more code the chance of getting an UnsupportedOperationException increases.

Using the renjin-maven-plugin and executing this code as a test almost always works fine (not sure why). The issue is much more frequent when directly invoking the RenjinScriptEngine with this type of code directly.

Is the magic import effect intended functionality? 
Any ideas about why the UnsupportedOperationException would show up some times?

The full code is available here: https://github.com/Alipsa/rjdom

Best regards,
Per

Bertram, Alexander

unread,
Mar 9, 2020, 4:29:57 PM3/9/20
to renji...@googlegroups.com
Do you get a stack trace?

--
You received this message because you are subscribed to the Google Groups "Renjin" group.
To unsubscribe from this group and stop receiving emails from it, send an email to renjin-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/renjin-dev/52e0f1dd-5b1a-4ae3-897c-f978c2a74dc8%40googlegroups.com.


--
Alexander Bertram
Technical Director
BeDataDriven BV

Web: http://bedatadriven.com
Email: al...@bedatadriven.com
Tel. Nederlands: +31(0)647205388
Skype: akbertram

Per Nyfelt

unread,
Mar 10, 2020, 4:47:39 AM3/10/20
to Renjin
org.renjin.eval.EvalException: java.lang.UnsupportedOperationException

at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:89)
at org.renjin.primitives.special.AssignLeftFunction.assignLeft(AssignLeftFunction.java:58)
at org.renjin.primitives.special.AssignLeftFunction.apply(AssignLeftFunction.java:42)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.sexp.ExpressionVector.eval(ExpressionVector.java:85)
at org.renjin.eval.Context.evaluate(Context.java:280)
at org.renjin.script.RenjinScriptEngine.eval(RenjinScriptEngine.java:174)
at org.renjin.script.RenjinScriptEngine.eval(RenjinScriptEngine.java:133)
at test.alipsa.rjdom.CreateXmlTest.testJdomCreation(CreateXmlTest.java:60)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: java.lang.UnsupportedOperationException
at org.renjin.invoke.reflection.converters.CollectionConverter.acceptsSEXP(CollectionConverter.java:60)
at org.renjin.invoke.reflection.AbstractOverload.accept(AbstractOverload.java:132)
at org.renjin.invoke.reflection.FunctionBinding.invoke(FunctionBinding.java:171)
at org.renjin.invoke.reflection.FunctionBinding.evaluateArgsAndInvoke(FunctionBinding.java:154)
at org.renjin.invoke.reflection.MethodFunction.apply(MethodFunction.java:58)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
... 33 more

On Monday, March 9, 2020 at 9:29:57 PM UTC+1, Alexander Bertram wrote:
Do you get a stack trace?

To unsubscribe from this group and stop receiving emails from it, send an email to renji...@googlegroups.com.

Per Nyfelt

unread,
Mar 10, 2020, 4:53:18 AM3/10/20
to Renjin
Another attempt on the same code which blew up a bit earlier (when adding a comment). Stack trace is similar:

org.renjin.eval.EvalException: java.lang.UnsupportedOperationException

at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:89)
... 30 more

Per Nyfelt

unread,
Mar 10, 2020, 4:56:10 AM3/10/20
to Renjin
I ran the R script in the simplest way possible i.e:
RenjinScriptEngine engine = new RenjinScriptEngineFactory().getScriptEngine();
engine
.eval(script);

see here: https://github.com/Alipsa/rjdom/blob/master/src/test/java/test/alipsa/rjdom/CreateXmlTest.java for details
Reply all
Reply to author
Forward
0 new messages