Drools 6.5: java.lang.RuntimeException: Illegal class for global. Expected [com.user.PersonAccount], found [com.user.PersonAccount] - drools

I'm using the "org.springframework.boot:spring-boot-devtools" dependency in my Grails application for the live reload of the application on code change. The problem is, it seems that this dependency is causing some conflict with drools.
On kieSession.setGlobal(name, value) in my code, I get the following error:
java.lang.RuntimeException: Illegal class for global. Expected [com.user.PersonAccount], found [com.user.PersonAccount]
Removing the "spring-boot-devtools" dependency fixes the issue but I need this dependency for the live reload, it's important in development.
Anyone knows why this dependency is causing this conflict? and what I can do to fix it or as a workaround?
Thanks in advance!

To whoever might have the same issue in future, the issue is already reported and described before: https://issues.redhat.com/browse/DROOLS-1540 and a fix has been included in drools starting from version 7.26.0.Final (https://github.com/kiegroup/drools/commit/85c5308031a84a0ac4086c1df363bb1b4b3c6af9)
If you don't want to upgrade to the latest version of drools, there's still a workaround to fix the issue which is already mentioned on the devtools page of spring-boot (https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools.restart.customizing-the-classload).
I added META-INF/spring-devtools.properties with the jars that I want to include in the restart classloader (mainly the drools + kie jars) & the issue is fixed.

When the devtools recompile the class, the byte code no longer matches the byte code from your rules. It's not doing a very good job of warning you, but what it's trying to say is "you are trying to give me a com.user.PersonAccount instance, but it doesn't look like what I know a com.user.PersonAccount instance should look like."
Therefore if you insist on using this tool which will recompile things on the fly, you'll need to also recompile and reload the rules on the fly. Or not use spring-boot-devtools.

Related

How can I get past "There is an error in a scoreDrl or scoreDrlFile"?

I wrote a "minimal" App using OpenJDK 11.0.11 & Optaplanner 8.7.0. I'm building it with maven and run it as a jar.
So far so good, as this works fine with a easyScoreCalculatorClass, but as soon as I move to using Drools I cannot get passed the following error:
Exception in thread "main" java.lang.IllegalStateException: There is an error in a scoreDrl or scoreDrlFile.
at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryFactory.java:323)
at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.decideMultipleScoreDirectorFactories(ScoreDirectorFactoryFactory.java:108)
at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.buildScoreDirectorFactory(ScoreDirectorFactoryFactory.java:73)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildScoreDirectorFactory(DefaultSolverFactory.java:116)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildSolver(DefaultSolverFactory.java:83)
at ch.twohundredok.compute.App.main(App.java:56)
Caused by: java.lang.NullPointerException
at org.kie.internal.utils.KieHelper.<init>(KieHelper.java:46)
at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryFactory.java:290)
... 5 more
The exception occurs as soon as solverFactory.buildSolver() is called.
This is the minimal drools file I'm trying to use:
package myapp;
dialect "java"
import myapp.domain.Employee;
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder;
global HardSoftScoreHolder scoreHolder;
rule "firstRule"
when
Employee()
then
scoreHolder.addHardConstraintMatch(kcontext, -1);
end
How can I get more information on the error?
Is is just that I have a broken Drools file?
Am I missing something else?
The unfortunate fact is that Drools isn't very good at exceptions when things go wrong. I do not see anything obviously wrong in the code you provided, and the fact that the failure comes from KieHelper is strange. That said, I do not have any information to go on, and would need access to your project to be able to find out more.
In the past, there have been several issues with people building executable JARs with Drools in Maven. See this question for one such problem, incl. the solution.
That said, if you're only just starting with your project, I suggest you use Constraint Streams instead. The programming model is very similar, but the code is plain Java, so you get all the IDE magic such as auto-completion, compiler checks etc.

Microsoft.Windows.SDK.Contracts and Must Use PackageReference

It's been a while since I've gotten into nuget hell but I'm back to this again...
I'm not exactly sure what caused this issue other than I did a visual studio 2019 update before I left on Friday. Now today, I've been fighting an issue where my library won't compile due to "Must Use PackageReference".
I've found a few articles out there on this but nothing that seems to specifically address this problem.
This issue could also be due to accidentally adding some .netcore librairies (entity framework .core) to the .netframework library. I had a hard time removing those libraries using nuget.
I also tried to reload the nuget library by:
nuget-package -reinstall Microsoft.Windows.SDK.Contracts
That reloads the package ok, but when I recompile the library the error "Must use PackageReference" comes back again.
In the output window I have this when compiling:
...\path...\packages\Microsoft.Windows.SDK.Contracts.10.0.19041.1\build\Microsoft.Windows.SDK.Contracts.targets(4,5): error : Must use PackageReference
I'm not even seeing this referenced in any of my source files so I'm not sure I even need it. However, I can't uninstall it as it seems to have octopus tentacles in numerous other libraries.
What am I running into here and how do I get this resolved?
My fix was to convert the projects to PackageReference as seen here: https://learn.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference The problem went away after doing this and I haven't seen it since. Still a little uneasy on why this happened... But I don't have time to dwell on it.

How to run GWT RequestFactory Validation Tool on Eclipse project

I've got a Android AppEngine Connected Project I'm trying to build using GWT2.4 RequestFactory and Objectify on my Eclipse IDE.
Apparently I need to run the RequestFactory Validation Tool because I'm using ServiceName and ProxyForName annotations (these are required especially when working on the Android client side). My problem is the Eclipse can't validate it and the solution provided at http://code.google.com/p/google-web-toolkit/wiki/RequestFactoryInterfaceValidation#IDE_configuration is enough to make me rip my eyes out.
Since I'm working on a Windows machine, the shell script provided is not very useful. Trying to run Validation Tool from a cmd propt returns the error message:"This tool must be run with a JDK, not a JRE"
Can someone explain how this Tool is supposed to be run? Is there a way to use it as an External Tool in eclipse?
Normally if you follow carefully the instructions in the link you show, and run the GWT Development Mode from Eclipse, the Validation should be done automatically at the time you access the development URL with your browser.
For the record, I've actually had some problems with it, but launching the application several times maked it work.
Well, I ran into the same problem as well. When I tried annotation processing (under Java Compiler-> Annotation processing )was being disabled. So RequestFactoryDeobfuscatorBuilder was not being generated. Try enabling that and rebuilding your project.
I've just recovered from two days of hunting this bug down in a project that used to run validation properly but stopped.
In my case I had a new-ish generic BaseRequestContext and a specific sub-interface that extended it. My parent interface declared a method that didn't match the Locator's exactly (e.g. getThing(T) vs get(T)) and this wasn't reported as an error but did stop the validation tool from completing.
Apt is also removed in Java 8 : http://openjdk.java.net/jeps/117 . So beware.
Switching back to Java 7 will fix the issue if you are using Java 8.
I understood why the error happens sometimes in a project: the compiler was complaining it cannot find the directory .apt . But when I tried to create it manually it was not possible (under windows). I think the validation tool mutes the exception of not being able to create the directory: try renaming .apt in your validation tool calls (do a text search in your project)

How can I fix this Android SDK build problem in Eclipse?

I am using Eclipse for Android dev and everything was going fine until I tried to incorporate the facebook SDK. Now when I tried to back it out, there appears to be an artifact left behind that Eclipse tries to link the FB library?!?
[2010-11-17 18:50:22 - Library Project] Unable to set linked path var '_android_com.facebook.android' for library /Users/mobibob/Projects/workspace/facebook-android-sdk/facebook: Path variable name cannot contain character: ..
Any clue where this command / reference is in the build configuration? I have scoured it as best that I can, but I still get the same error.
Problem solved ... as it turns out, it was not so much the Facebook SDK but something that I did in the process of configuring the library reference. I am not entirely certain of how I misconfigured, but I was tweaking the various "path" settings such that, once when the automatic build tried to build my project, an import for android.R was added to my source module. This superseded com.myproject.R and would not resolve the values for resource references.
There were other problems with path order and setting that I modified during the troubleshooting that made it worse. Recreating the project without Facebook was the first step to discovery and fixing.
Either way, the lesson I learned is that the build error messages can misdirect one to the configuration when the problem is in the source code.

GWT - occasional com.google.gwt.user.client.rpc.SerializationException

we are haunted by occasional occurences of exceptions such as:
com.google.gwt.user.client.rpc.SerializationException: Type 'xxx' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer.For security purposes, this type will not be serialized.: instance = xxx
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:610)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:129)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:152)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:534)
at com.google.gwt.user.server.rpc.RPC.encodeResponse(RPC.java:609)
at com.google.gwt.user.server.rpc.RPC.encodeResponseForSuccess(RPC.java:467)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:564)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:188)
at de.softconex.travicemanager.server.TraviceManagerServiceImpl.processCall(TraviceManagerServiceImpl.java:615)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:224)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:419)
at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:378)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1508)
at java.lang.Thread.run(Thread.java:619)
The application is normally running fine. The indicated class implements Serializable (the whole object graph).
So far the only patterns / observations are:
we seem to have the issue only when the application is used inside an iframe
the problem seems to happen when a new version of the application has been deployed
running firefox in privacy mode (disabling all caches etc.) doesn't fix the problem
Any ideas?
Holger
did you check http://code.google.com/webtoolkit/doc/latest/tutorial/RPC.html#serialize
the article says:
It has a default (zero argument) constructor with any access modifier (e.g. private Foo(){} will work)
I'm allways forgetting zeroargument const. when I am making a serializable object :D
Very possible reason - older version of client is still cached in browser. It sends rpc requests, but server is already restarted and have newer versions of rpc files (*.symbolMap)
I encountered the problem when I used Tomcat6 + Devmode in Ubuntu Lucid amd64. Using com.google.gwt.user.client.rpc.IsSerializable instead of java.io.Serializable seemed solved the problem.
I assume you're running the application on localhost and in hosted mode? If so, you might want to keep an eye on the work directory (or the equivalent directory if you're not running the application in a tomcat server). Check the webapp's folder for serialization policiy files (*.gwt.rpc).
It's possible they're not loaded correctly, the only workaround we have found so far, is to restart your server after each serialization fault.
The problem is due to the fact GWT will generate its serialization policy files at run time, assuming you're running in hosted mode. In compiled mode, GWT will generate all necessary files at compile time. AFAIK, tomcat's unable to load in the resource files at run time and hence will not include the serialization files each time they are needed for the first time.
When restarting the server, tomcat's able to pick up the previously generated file and hence you shouldn't receive the same error after restarting.
Can you verify this?
If you are running on JBoss, this might be due to the fact that the previously deployed application is not deleted when undeployed. To fix this, you must modify the following file in JBoss:
${JBOSS_HOME}/server/default/deployers/jbossweb.deployer/META-INF/war-deployers-jboss-beans.xml
and set the following attribute to true: deleteWorkDirOnContextDestroy
When the previously deployed application is not cleaned up, GWT can be confused about which RPC file it needs to load and you end up with those SerializationException
I had the same problem and I found a solution from another person:
"There is a possibility that you have a class which implements Serializable and you have an attribute field within that class which is not Serializable hence you might be getting this exception."
Many thanks to that person :)
My advice is to make all fields (which are not primitive types) in your class to implement Serializable also! This solved my problem.
This problem occurs when a GWT 2.5 application is compiled using JDK 1.7. GWT 2.5 supports JDK 1.6 and using this version of JDK will fix this issue.
So the RPC files are unique because they are loaded by servlets as well as being used in GWT. See http://code.google.com/webtoolkit/release-notes.html#Release_Notes_1_4_59 where it says "This file must be deployed to your web server as a public resource, accessible from a RemoteServiceServlet via ServletContext.getResource()"
Is it possible the new application is being reloaded dynamically and getResource is failing in some way? Does restarting the application fix things?
I've had the same error and fix this by clean the browse cache and navigation history.
I was getting a SerializationException also but I was also seeing this error showing up right before the serialization exception:
[uptimereports/2.340102563369350884].:
Example : error : cannot find template
registration-confirmation.vm
It turned out to be a problem finding my velocity template. Once I fixed that problem the SerializationException stopped showing up, so if you follow Kerem's advice and still have problems, look for other exceptions in your log.
The best way to know the exact issue is to compile your code using -logLevel DEBUG or TRACE and check inside Validating Units. I am sure you would be able to find out the exact issue with line numbers as well.
First make sure you have a 'clean' serializable class ie empty constructor, no inner classes implementing serializable and use GWT Serializable class instead of Java Serializable class.
Then simply open your site in an Incognito tab (Chrome) solves the problem. Local browser cache causes loading old rpc files.
I had this problem when running SuperDevelopmentMode with a setup where codeserver was not on the same host as tomcat server. I had codeserver on my host, while tomcat running in the docker container. It turns out in such setup app server cannot get the right serialization policy files, so quite similar as described by thomaux in one of answers above, just different setup.
I had to add -Dgwt.codeserver.port=9876 to start parameters of tomcat as described here. This causes GWT SuperDevMode to switch to mode of getting serialization policy files through network. Still the url is hardcoded in com.google.gwt.user.server.rpc.RemoteServiceServlet#getCodeServerPolicyUrl as
"http://localhost:" + codeServerPort
so you have to make sure that your tomcat can reach codeserver on that port, by tunneling or routing the traffic if necessary. Alternative is to hack GWT code to allow changing that localhost to something else too, but this doesn't look clean and secure.