Drools maven plugin not understanding locally declared enums when compiling DRL files - maven

I have been struggling with drools taking long to load rules on application startup. For this reason I have been looking at using the drools maven plugin to pre-compile my rules. However, while migrating my existing DRL files, I find that some of them do not compile.
This is happening where we have declared an enum in the DRL files and using it in the rule later on in the file. The error seems to happen because it does not understand the enum. i.e. unqualified type in strict mode for: SomeEnum
I have upgraded to the latest drools release (7.23.0) and simplified the example into the simplest use case I can think of.
I have a unit test that reads the DRL file in the test as a DRL Resource and executes the rule, and this test passes. But when I try to compile the rule itself, there are compilation issues.
Also, if I remove the enum and use a hardcoded value, the test passes in both cases.
My DRL file
declare enum SomeEnum
ENUM_KEY(1234L);
key: Long
end
rule "0_SomeRule"
dialect "mvel"
salience 3
when
response : Response ()
request : Request ()
then
response.key = SomeEnum.ENUM_KEY.getKey();
end
My kmodule file
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="Test" packages="com.rawb.droolstest">
<ksession name="Test.session" type="stateless"/>
</kbase>
</kmodule>
The failing test:
public void testKJar() throws Exception {
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
StatelessKieSession kSession = kContainer.newStatelessKieSession("Test.session");
runRules(kSession);
}
private void runRules(StatelessKieSession kSession) {
List<Command> commands = new ArrayList<>();
commands.add(CommandFactory.newInsert(new Request(), "request"));
commands.add(CommandFactory.newInsert(new Response(), "response"));
commands.add(CommandFactory.newFireAllRules());
ExecutionResults executionResults = kSession.execute(CommandFactory.newBatchExecution(commands));
Response response = (Response) executionResults.getValue("response");
assertEquals(response.getKey(), 1234L);
}
The error message I recieve when running the test is as follows
[Error: unqualified type in strict mode for: SomeEnum]
[Near : {... response.key = SomeEnum.ENUM_KEY.getKey(); ....}]
^
[Line: 1, Column: 16]

Related

In gradle kotlin dsl, how to call a dynamic test extension?

I'm trying to add a new configuration option when using the gradle ScalaTest plugin:
https://github.com/maiflai/gradle-scalatest
In its source code, the config was injected into the Test class as a dynamic extension:
static void configure(Test test) {
...
Map<String, ?> config = [:]
test.extensions.add(ScalaTestAction.CONFIG, config)
test.extensions.add("config", { String name, value -> config.put(name, value) })
test.extensions.add("configMap", { Map<String, ?> c -> config.putAll(c) })
...
}
If using groovy as the dsl, calling this property is easy:
test {
configMap([
'db.name': 'testdb'
'server': '192.168.1.188'
])
}
unfortunately the kotlin dsl can't use this method due to static typing, when being invoked as a test plugin, it is clearly visible within the test scope, e.g. when using extensions.getByName:
tasks {
test {
val map = extensions.getByName("configMap")
println(map)
}
}
It yields the following output:
...
> Configure project :
com.github.maiflai.ScalaTestPlugin$_configure_closure6#45c21cac
But there is no way to retrieve or assert its type in compile time, and it ends up being useless (unless reflection is used, which is against the design philosophy of kotlin dsl). Is there a easy way for kotlin dsl to achieve the same?
I saw in the Scala test gradle plugin that the dynamic extension is defined like this:
test.extensions.add("configMap", { Map<String, ?> c -> config.putAll(c) })
The com.github.maiflai.ScalaTestPlugin$_configure_closure6#45c21cac you saw should be a closure of type (Map<String, Any>) -> Unit, which means you can do that. We'll have to change the map values so let's assume that it's also mutable.
extensions.getByName("configMap").closureOf<MutableMap<String, Any?>> {
this["db.name"] = "testdb"
this["server"] = "192.168.1.188"
}
This builds fine but I don't have Scala installed and never used Scala test. I have no idea if it actually works, so please tell me.

How to build netty by source code? I failed in test code because of assertequals ambiguous method call

I want to build netty from source code. I pull 4.1 from GitHub. When i want to run maven, I have some problem in test code.
I can run maven install -Dmaven.test.skip=true to build project. But when I want to run netty-example code, I see some error in test code.
I can not remove all test code, so I can not run code in this project.
This is for a jdk1.8, macos ,idea2019.
#Test
public void testFlushViaDisconnect() {
final AtomicInteger flushCount = new AtomicInteger();
EmbeddedChannel channel = newChannel(flushCount, false);
// Simulate read loop;
channel.pipeline().fireChannelRead(1L);
assertEquals(0, flushCount.get());
assertNull(channel.readOutbound());
channel.disconnect();
assertEquals(1, flushCount.get());
assertEquals(1L, channel.readOutbound()); // error this line.
assertNull(channel.readOutbound());
assertFalse(channel.finish());
}
Error:(150, 9) java: ambiguous method call of assertEquals
org.junit.Assert method assertEquals(long,long) and org.junit.Assert method assertEquals(java.lang.Object,java.lang.Object) is all match

Unable to generate objects for both #higherkind and #extension

I define two objects:
data class ParserK annotated with #higherkind
interface ParserKFunctor annotated with #extension
Here is the code:
#higherkind
data class ParserK<A>(val f: (String) -> Option<A>): ParserKOf<A> {
companion object
}
#extension
interface ParserKFunctor : Functor<ForParserK> {
override fun <A, B> Kind<ForParserK, A>.map(f: (A) -> B): Kind<ForParserK, B> {
...
}
}
When I execute ./gradlew :app:kaptKotlin I get:
error: "Arrow's annotations can only be used on Kotlin classes". Not valid for error.NonExistentClass
> Task :app:kaptGenerateStubsKotlin
> Task :app:kaptKotlin FAILED
e: error: Arrow's annotations can only be used on Kotlin classes. Not valid for error.NonExistentClass
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:kaptKotlin'.
> Compilation error. See log for more details
Here is what I discovered:
If I remove the functor definition then the goal completes successfully and I can see the generated code.
If I remove #higherkind from the data class ParserK and copy the generated sources into the same file where ParserK is defined then I can see the generated code for the functor.
It seems like a bug for me, correct me if I am wrong, please
UPDATED:
Here is the link to the repository with my code: repository
The issue on the bug tracker is here
(For arrow-version 0.9.1-SNAPSHOT and prior)
The Higherkinded Processor and Extension Processors have a dependency. Correctly, the extension annotation depends on the code generated by the higherkinded annotation. Why check this link.
The brief summary is, whenever you try implementing typeclasses the compiler needs the Higherkinded Types of your datatype.
#extension
interface ListKFunctor : Functor<ForListK> {
// ^^^^^^^^
// This exists after building your module
override fun <A, B> Kind<ForListK, A>.map(f: (A) -> B): Kind<ForListK, B> {
return this.fix().map(f)
}
}
The simplest answer to this question is:
Always separate your Higherkinded Types from your typeclass definitions.
But Arrow is experimenting with other options on Codegen. Meaning in future releases this problem will be solved.

Unity cannot build GRPC Project for UWP with IL2CPP Backend

Here, or here for a complete version, you can find a sample GRPC "Hello World" project for Unity. Only the first version, that is built for Unity and wrapped in a DLL is working perfectly fine in Unity IDE and on Standalone build. The Raw Grpc.Core files are referencing everything correctly in IDE but they have Marshaling problem.
Unfortunately, it cannot get build for UWP with IL2CPP backend. Unity builds the project and creates a .sln project. But Visual Studio always gives LNK2001 for GRPC properties on the final compilation.
Here are first error codes:
LNK2001 unresolved external _grpccsharp_init#0
LNK2001 unresolved external _grpccsharp_shutdonw#0
LNK2001 unresolved external _grpccsharp_version_string#0
...
Ok, thanks to #Sunius, I digged into it a little bit more. There are some points, I am going to add to the question:
There are two methods regarding referencing extern methods in GRPC C# package. They are named static and shared libs.
internal class DllImportsFromStaticLib
{
private const string ImportName = "__Internal";
[DllImport(ImportName)]
public static extern void grpcsharp_init();
[DllImport(ImportName)]
public static extern void grpcsharp_shutdown();
...
}
and
internal class DllImportsFromSharedLib
{
private const string ImportName = "grpc_csharp_ext";
[DllImport(ImportName)]
public static extern void grpcsharp_init();
[DllImport(ImportName)]
public static extern void grpcsharp_shutdown();
...
}
I tried to test it with the shared one, I got another linking error file which is a little bit different.
LNK2001 unresolved external _dlopen#8
LNK2001 unresolved external _dlsym#8
...
In two separate methods, extern methods are getting connected to the internal interface:
public NativeMethods(DllImportsFromStaticLib unusedInstance)
{
this.grpccsharp_init = DllImportsFromStaticLib.grpccsharp_init;
this.grpccsharp_shutdown = DllImportsFromStaticLib.grpccsharp_shutdonw;
...
}
and
public NativeMethods(DllImportsFromSharedLib unusedInstance)
{
this.grpccsharp_init = DllImportsFromSharedLib.grpccsharp_init;
this.grpccsharp_shutdown = DllImportsFromSharedLib.grpccsharp_shutdonw;
...
}
And which method will get called is defined here:
private static NativMethods LoadNativeMethodsUnity()
{
switch(PlatformApis.GetUnityRuntimePlatform())
{
case "IPhonePlayer":
return new NativeMethods(new NativeMethods.DllImportsFromStaticLib());
default:
return new NativeMethods(new NativeMethods.DllImportsFromSharedLib());
}
}
Some updates:
Thanks to #jsmouret, there is Stub.c file in his Grpc Github with fake methods, so Linker does not complain about Grpc_init methods anymore.
Next Error: dlopen, dlsym, dlerror:
First, I tried to use the same, Stub technique, but it did not help in this case, or maybe I did it wrong.
Thanks to #Sunius, I commented out all of "__Internal" dll import codes. So I am not getting any dlopen, dlsym, and dlerror errors.
Next Error: It happens from inside application, not the visual studio debugger. It tells me: "exception: to marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition."
exception: error loading the embedded resource "Grpc.Core.roots.pem"
and
exception: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition.
After I googled it, I know my options, but the question it, for which method should I do that?!
Thanks to my colleague Alice, #Sunius and #jsmouret, at the end, grpc works on UWP on Unity Platform through this steps:
Download Grpc.Core folder from Google Grpc Github.
Download Grpc Unity plugin from their official site.
Copy the runtime folder to your Grpc.Core folder. Please remove Grpc.Core.dll that you get from Grpc Unity Plugin, since we are using their source code.
Grpc should be in a folder called, Plugins in Unity, otherwise it will not be recognized.
Include this file in your runtime folder.
Include the Stub also from the Unity Plugin Inspector for WSA.
Find runtime .dll for Windows and include them in WSA from Unity Plugin Inspector.
By now, you should be getting _dlopen error.
Search through your Unity Solution with an IDE for "__Internal". There are not so many places, but comment them out. Also some methods that are depended on "__Internal"s, like dlopen and dlsym.
By now, you are not getting anymore build error but you need to make Grpc work.
Search for something like "DefaultSslRootsOverride" and comment out like below:
internal static class DefaultSslRootsOverride
{
const string RootsPemResourceName = "Grpc.Core.roots.pem";
static object staticLock = new object();
/// <summary>
/// Overrides C core's default roots with roots.pem loaded as embedded resource.
/// </summary>
public static void Override(NativeMethods native)
{
lock (staticLock)
{
//var stream = typeof(DefaultSslRootsOverride).GetTypeInfo().Assembly.GetManifestResourceStream(RootsPemResourceName);
//if (stream == null)
//{
// throw new IOException(string.Format("Error loading the embedded resource \"{0}\"", RootsPemResourceName));
//}
//using (var streamReader = new StreamReader(stream))
//{
// var pemRootCerts = streamReader.ReadToEnd();
// native.grpcsharp_override_default_ssl_roots(pemRootCerts);
//}
}
}
}
Search for something like "static void HandWrite" and add an attribute like something in below:
[MonoPInvokeCallback(typeof(GprLogDelegate))]
private static void HandleWrite(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr)
{
try
{
var logger = GrpcEnvironment.Logger;
string severityString = Marshal.PtrToStringAnsi(severityStringPtr);
string message = string.Format("{0} {1}:{2}: {3}",
threadId,
Marshal.PtrToStringAnsi(fileStringPtr),
line,
Marshal.PtrToStringAnsi(msgPtr));
switch (severityString)
{
case "D":
logger.Debug(message);
break;
case "I":
logger.Info(message);
break;
case "E":
logger.Error(message);
break;
default:
// severity not recognized, default to error.
logger.Error(message);
break;
}
}
catch (Exception e)
{
Console.WriteLine("Caught exception in native callback " + e);
}
}
I guess, you are done. In case, it did not work for your UWP, let me know, maybe I can help. :)
It looks like your plugin uses "__Internal" P/Invoke to call those native functions:
https://github.com/grpc/grpc/blob/befc7220cadb963755de86763a04ab6f9dc14200/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs#L542
However, the linker cannot locate those functions and thus fails. You should change that code to either specify the DLL file name where the functions are implemented, or drop the source files with definitions for those functions into your Unity project. Or, if that code path isn't actually invoked (since you said it works on the standalone player), #ifdef it out from UWP build.
You can find more information about "__Internal" P/Invoke here:
https://docs.unity3d.com/Manual/windowsstore-plugins-il2cpp.html

SONAR 3.7.3 - PMD XPath rule <my custom rule> can't be imported automatically. The rule must be created manually through the SonarQube web interface

I am working on trying to get some custom pmd rules onto our SONAR server so they will show up in our nightly tests. I have an xml file with a bunch of custom rules like so:
<rule class="net.sourceforge.pmd.rules.XPathRule" dfa="false" externalInfoUrl="" message="System.out.print is used" name="MyOrganisation_SystemPrintln" typeResolution="true">
<description>System.(out|err).print is used, consider using a logger.</description>
<priority>5</priority>
<properties>
<property name="xpath">
<value><![CDATA[
//Name[
starts-with(#Image, 'System.out.print')
or
starts-with(#Image, 'System.err.print')
]
]]></value>
</property>
</properties>
<example><![CDATA[
class Foo{
Logger log = Logger.getLogger(Foo.class.getName());
public void testA () {
System.out.println("Entering test");
// Better use this
log.fine("Entering test");
}
}
]]></example>
When I go to the Quality profiles page and make a new profile, giving it the xml file I get a bunch of errors like this:
PMD XPath rule 'MyOrganisation_SystemPrintln' can't be imported
automatically. The rule must be created manually through the SonarQube
web interface.
Which seems clear enough, however when I try and create a new rule by copying the generic xpath rule that is there already and changing it there is nowhere to put the "example" part. (There is only Name, message, xpathQuery and Description) I was wondering if I am missing something that might be the cause of this, and how I can get these rules onto the sonar server?
Thanks very much.
Edit: The PMD version is 1.3, as is the java plugin
Edit2: Another example of a rule:
<rule class="net.sourceforge.pmd.rules.UnusedPrivateFieldRule" dfa="false" externalInfoUrl="" message="Avoid unused private fields such as ''{0}''" name="MyOrganisation_UnusedPrivateField" typeResolution="true">
<description>Detects when a private field is declared and/or assigned a value, but not used.</description>
<priority>5</priority>
<example><![CDATA[
public class Something {
private static int FOO = 2; // Unused
private int i = 5; // Unused
private int j = 6;
public int addOne() {
return j++;
}
}
]]></example>
</rule>
Indeed, there is no possibility in the SonarQube custom rules to declare examples like on the PMD custom rules, you will have to put the examples in the description, e.g using blockquote elements.

Resources