#JSAccessible does not work with JRuby objects? - jruby

I use JRuby with jxBrowser. I´ve just upgraded to version 6.8 and my application stopped working. I think the problem comes with the new #JSAccessible annotation. JRuby does not allow method annotation and I inject a JRuby class into a javascript. What used to work now gives me the following message:
Unhandled Java exception: com.teamdev.jxbrowser.chromium.JSFunctionException: Uncaught TypeError: Cannot read property 'set_this' of undefined
Is it possible to not require the #JSAccessible annotation and bring back the functioning of version 6.7?

To bring back functionality of version 6.7 you just need to avoid using the #JSAccessible annotation in your code. This annotation represents an extension to the current API. If you don't use this annotation, the behavior is the same as in previous versions.

Related

Primefaces calling a javax.faces 2.2 method but 2.1 is in the path in Websphere 9

I have an application deployed in WAS 9 using custom jsf provider (set to DEFAULT in WAS). Jars are in a shared lib with an isolated class loader. Everything worked fine until we migrated from richfaces to primefaces. We use javax.faces 2.1.29 but for some reason primefaces seems to detect that we are using 2.2 and is making a call to a method that only exists in 2.2 (getPassThroughAttributes). Looking at the stack versions in play seem correct so I'm not sure why the 2.2 method call is being made. Anyone run into this?
> 3/19/19 17:19:07:671 CDT] 00000091 ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause Faces Servlet: javax.servlet.ServletException: javax/faces/component/UIComponent.getPassThroughAttributes(Z)Ljava/util/Map; (loaded from file:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar by
com.ibm.ws.classloader.CompoundClassLoader#abecddd0[library:trunkLib]
Local ClassPath: /opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpclient-4.5.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpcore-4.4.4.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/commons-codec-1.11.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-api-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-locator-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-utils-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.annotation-api-1.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jaxrs-ri-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jersey-guava-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/validation-api-1.1.0.Final.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/classes:/opt/IBM/WebSphere/AppServer_2/trunkLib/javassist-3.23.1-GA.jar
Parent: com.ibm.ws.classloader.ProtectionClassLoader#a5c5ece8
and
> Caused by: java.lang.NoSuchMethodError: javax/faces/component/UIComponent.getPassThroughAttributes(Z)Ljava/util/Map; (loaded from file:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar by
com.ibm.ws.classloader.CompoundClassLoader#abecddd0[library:trunkLib]
Local ClassPath: /opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpclient-4.5.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpcore-4.4.4.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/commons-codec-1.11.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-api-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-locator-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-utils-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.annotation-api-1.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jaxrs-ri-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jersey-guava-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/validation-api-1.1.0.Final.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/classes:/opt/IBM/WebSphere/AppServer_2/trunkLib/javassist-3.23.1-GA.jar
Parent: com.ibm.ws.classloader.ProtectionClassLoader#a5c5ece8
Delegation Mode: PARENT_LAST) called from class org.primefaces.util.Jsf22Helper (loaded from file:/opt/IBM/WebSphere/AppServer_2/profiles/server1/installedApps/loggerheadNode03Cell/trunk80_war.ear/trunk80.war/WEB-INF/lib/primefaces-6.2.jar
It looks like PrimeFaces searches the classpath for JSF 2.2 classes - and unfortunately in this case PrimeFaces must be finding the those classes in the WAS-provided JSF 2.2 bundle. Moving primefaces-6.2 out of your application trunk80.war and into the isolated shared library trunkLib should resolve this.
First lets begin that the PrimeFaces source is OPEN, it is easilly debugged. A simple search in the source (either locally in your IDE or in GitHub) will get you the source of Jsf22Helper.java. You can than inspect where this is being called. Running in debug mode is the easiest, but a search in the PrimeFaces repository in GitHub shows just one location in CoreRenderer.java
protected void renderDynamicPassThruAttributes(FacesContext context, UIComponent component) throws IOException {
if (PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf22()) {
Jsf22Helper.renderPassThroughAttributes(context, component);
}
}
Next you should inspect the
PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf22()
And the getter for this returns a property that gets its boolean value from
atLeastJsf22 = LangUtils.tryToLoadClassForName("javax.faces.flow.Flow") != null;
In here you see that for determining the 'minimal' version, they try loading a class that is only present in JSF 2.2 or up. This means that no matter whether you use parent first classloading or not or independent of where you put PrimeFaces, if javax.faces.flow.Flow is on the classpath, PrimeFaces will think JSF 2.2 is available. It does not matter if JSF 2.1 is also on the classpath and even before JSF 2.2 since this specific class is not present in JSF2.1 and will always be loaded from the JSF 2.2 jars.
To fix this you have three options
Override the PrimeFaces PrimeEnvironment.java (e.g. via reading an explicit context property from the web.xml so you can optionally manually override the version detection and create a pull request for this with PrimeFaces so they can accept it as an improvement
'Correct' the way to override the JSF version similar to How to make websphere 8.5 use mojarra not myfaces
Switch to JSF 2.2
The latter would be the best and might even just be working out of the box.

JSON Parser -java.lang.NoSuchFieldError: defaultReader

I am using a JSON parser to extract the value and I am using the following jar
json-path-2.1.0, and I am getting the following error when I invoke the use case deployed as webservice on weblogic server
I wrote a small main program to extract the value from the json string and it works fine, but the server version of the use case is giving the issue. I am not sure if there are any other jars part of my ear can negatively impact this
SEVERE: defaultReader
java.lang.NoSuchFieldError: defaultReader
at com.jayway.jsonpath.spi.json.JsonSmartJsonProvider.<init>(JsonSmartJsonProvider.java:39)
at com.jayway.jsonpath.internal.DefaultsImpl.jsonProvider(DefaultsImpl.java:21)
at com.jayway.jsonpath.Configuration.defaultConfiguration(Configuration.java:174)
at com.jayway.jsonpath.internal.JsonContext.<init>(JsonContext.java:52)
at com.jayway.jsonpath.JsonPath.parse(JsonPath.java:596)
Stumbled about the same problem.
The reason why it does not work is not the JDK 8.
The reason why you encounter this issue, is the fact that weblogic 12.2.1.X is bundling some old version of json-smart.
On my machine this would be found here:
jar:file:/C:/dev/WLS_12_2_1_2_0/oracle_common/modules/net.minidev.json-smart.jar!/net/minidev/json/JSONValue.class
Now if you are using a library like json-path that depends on json-smart, then by default the container will load the required class using one of its built-in modules.
The blowup you have, seems to be that the JSONValue class that your json-path depends on seemed to have this defaultReder field.
Here is a snipet of the clode that is blowing up.
public JsonSmartJsonProvider() {
this(JSONParser.MODE_PERMISSIVE, JSONValue.defaultReader.DEFAULT_ORDERED);
}
That
JSONValue.defaultReader
Seems not to be valid on weblogs older system class loader class.
You can tell the container to use what you are packing by putting into your weblogic.xml deployment descriptor something like this:
<wls:prefer-application-packages>
<wls:package-name>net.minidev.json.*</wls:package-name>
</wls:prefer-application-packages>
I am having quite a bit of trouble getting weblogic to swallow the fine-grained instruction above.
I found myself to force weblogic to swallog all that goes into the web-inf folder instead doing:
<wls:container-descriptor>
<wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>
</wls:container-descriptor>
I would have rather not be using a hammer like the web-inf-classes, but I am dancing with the weblogic system classloader when I do not go coarse grained...
Regards.
I too was facing this issue, It turned out some other library was using json-smart's older version, and it was getting precedence over json-path's json-smart dependency. Removing the other jar solved the issue. Or you can also downgrade your json-path's version to appropriate version such that it support json-smart's older version.
Looks like JsonParser jar is present in JVM 1.8 version and it seems to have more precedence over the JsonParser class available in Json-path.jar. Apparently the us case doesn't work in 12.2.1 version of the weblogic server but it works fine in 12.1.3
I had the same problem but I use Gradle so I had to add:
compile group: 'net.minidev', name: 'json-smart', version: '2.3' to my dependencies.

Unable to undrestand IKVM exception

I have some java code converted to .net assemblies using IKVM.
When ever I run the application, it throws an exception as below:
The type initializer for '1' threw an exception.
{"Method not found: 'System.Exception java.lang.Throwable.__<map>(System.Exception, System.Type, Boolean)'."}
What I am missing?
After a couple of hours, I could figure out the problem.
The IKVM version that made .net assemblies is important. higher versions which I got from Nuget did not work properly. I had to download IKVM version 0.42.0.3

Unable to parse JSON error using Twitterizer TwitterStatus.Show method

Running this code:
var statusResponse = TwitterStatus.Show(tweet.Id);
gives an error message: Unable to parse JSON in the statusResponse object and the ResponseObject comes back as null.
Not sure how to fix this. Any ideas?
I run into the same issue today. It seems that you reference a newer version of Newtonsoft.Json in your project (or maybe an other NuGet package included it).
The problem can be fixed by using the Newtonsoft.Json 4.0.5.0 library that is shipped with the Twitterizer project. It needs to be that exact version.

Creating bean PropertyDescriptor using JRuby

I'm trying to port some java to jruby, and it uses a beans PropertyDescriptor. The original code is:
new PropertyDescriptor("splitEvaluator", CrossValidationResultProducer.class)
which I've tried to port to:
PropertyDescriptor.new("splitEvaluator", CrossValidationResultProducer)
However, I get the error:
no constructor with arguments matching [class org.jruby.RubyString, class org.jruby.RubyClass] on object #<Java::JavaBeans::PropertyDescriptor:0x86f847> (NameError)
The PropertyDescriptor API says the second argument should be a Java Class. What do I need to pass for this to work in JRuby?
I can see an argument that it's a bug that it doesn't work the way you originally expected. Or at least that JRuby would be smart enough to convert a Ruby class representation of a Java class to a Java class argument.
As it is, using #java_class works, as you found out.
I need to use the Java class, rather than the Ruby representation of the Java class. This works.
PropertyDescriptor.new("splitEvaluator", CrossValidationResultProducer.java_class)