Drools - Changing the Java compiler level - jboss

I want to change the java compiler level to 1.6 but it doesn't seem to work for me. I am trying to use generics in the consequence part.
Following is my code that I used to change the compiler level.
Drools Version: 5.2.1 GA
*JDK Version : 1.6*
final Properties properties = new Properties();
properties.setProperty("drools.dialect.java.compiler", "JANINO");
properties.setProperty("drools.dialect.default", "java");
properties.setProperty("drools.compiler.lnglevel", "1.6");
PackageBuilderConfiguration packageBuilderConfiguration =
new PackageBuilderConfiguration(properties,(ClassLoader[]) null);
final KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory
.newKnowledgeBuilder(packageBuilderConfiguration);
Let me know where I am going wrong.
Thanks for the help.

Janino intentionally does not support generics. It appears to be a conscious decision, so there's not likely to be a change in that with new versions. They're also not going to support the enhanced for() loop and enums, both of which I've also grown to miss in Drools.
Check out the Janino webpage, near the bottom right in what they do not support.
If you take out the "JANINO" line from your example, I'd be curious if you could start using them. (The default compiler is the eclipse compiler, at least it was the last time I checked.

Related

Kaitai Struct Parameter Type

I am trying to pass a parameter to ksy file. The parameter is of type another ksy file. The reason is that i need to access all the fields from the ksy file passed as parameter.
Is that possible?
If yes, would you please provide me with syntax code snippet so I can mimic it.
If no, what would be another solution?
Thank You.
Affiliate disclaimer: I'm a Kaitai Struct maintainer (see my GitHub profile).
First, I recommend always using the development version of the Kaitai Struct Web IDE (https://ide.kaitai.io/devel/), not the stable one. The stable IDE deployed at https://ide.kaitai.io/ has KS compiler of version 0.8, which is indeed the latest stable version, but already 2 years old at the moment. But the project is under active development, new bug fixes and improvements are coming every week, so the stable Web IDE is pretty much outdated. And thanks to the recent infrastructure enhancement, the devel Web IDE now gets rebuilt every time the compiler is updated, so you can use even the most recent features.
However, you won't be able to simulate the particular situation you describe in the Web IDE, because it can't currently handle top-level parameteric types (there is no hook where you can pass your own values as arguments). But it should work in a local environment. You can compile the commontype.ksy and pty.ksy specs in the Web IDE to the target language you want to use (the manual shows how to do it). The code putting it together could look like this (Java):
Commontype ct = new Commontype(new ByteBufferKaitaiStream(new byte[] { 80, 75 }));
Pty r = new Pty(
new ByteBufferKaitaiStream(new byte[] { 80 }), // IO stream
ct // commonword
);
Note that the actual parameter order of the Pty constructor may be different, e.g. in Python come the custom params (commonword) first and then the IO object. Check the generated code in your particular language.

In Scala.JS is there a call to get the platform I'm running on?

I have some Scala code for a library which I compile for both the JVM and ScalaJS.
Right now I have a "pure" project, without special code in the js and jvm proojects, and I'd like to keep it that way due to intellij integration and some other factors.
However, I do have a small bit of code (1-2 lines) that needs to change based on whether I'm in the JVM or JS. I'd like an easy way to accomplish this that doesn't require me changing my whole project structure.
Basically I'd like a call "isJS" that returns true if I'm on JavaScript and false otherwise.
There is nothing standard, as it would require to extend the API available on the JVM, which Scala.js cannot do.
You can build it yourself easily with a tiny object Platform with two different implementations in the js/ and jvm/ subprojects. For example for JS it would be:
object Platform {
final val isJS = true
final val isJVM = false
}
Of course that requires to be non-pure. You could also abstract that in a tiny library offering only that feature. That is what the platform project of catalysts does, for example.
If you want to keep completely pure and no dependency, you have to resort to a hack:
val isJS = 1.0.toString == "1"
This works because, on the JVM, 1.0.toString returns "1.0", but on JS it returns "1".
You can do:
val isJS = System.getProperty("java.vm.name") == "Scala.js"

Java 8: Spliterator, Iterator, Collection and "default" implemenations in Interfaces (Duplicate methods named spliterator)

Have an interesting situation following the release of Java 1.8.0_25 into the wilds... I believe the root of my issue is related primarily to the new (to 1.8) features of "default" implementations within Interfaces.
The application I am working on is currently targeted at 1.7, which until now has been working well. Until users started updating to 1.8. Now that our users have started updating to 1.8, our hand is forced somewhat into moving to 1.8 support.
We have fixed most of the issues (mainly relating to changes to the JavaFX packages between 1.7 and 1.8) but have one vexing issue remaining.
In my wisdom, or lack thereof, I, some time ago, decided to create a SortedList<T> which extends from AbstractList<T>. Until now, this class has worked fine, however when running on a 1.8 runtime, I get:
Duplicate methods named spliterator with the parameters () and () are inherited
from the types Collection<T> and Iterable<T>
This, to me, appears to be caused by the "default" implementations in some of the Interfaces that are implemented by AbstractList<T> (my SortedList<T> class does not implement any additional Interfaces other than Serializable). Implementing Serializable is another problem for us, as we need to support deserialisation of SortedList<T> objects, there's no way around that!).
I can get rid of the error by providing an override implementation of spliterator() in my SortedList<T> class. However, if this is built, it no longer runs on a Java 1.7 environment. If I attempt to use SortedList<T> with a 1.7 runtime, I get:
Problem:
Error: Unresolved compilation problems:
The import java.util.Spliterator cannot be resolved
Spliterator cannot be resolved to a type
com.xxxx.xxxx.util.SortedList.<init>(SortedList.java:13)
This error is pretty obvious, since we've now overridden the spliterator() method in SortedList<T> it needs to include java.util.Spliterator, but that doesn't exist in 1.7.
Ideally we would like to NOT require our customers to update to Java 1.8 if they don't want to.
Is our hand being forced here? Do we need to force users to update to 1.8 and also roll out a new version to any users who have updated to 1.8 by themselves?
Does anyone know a way around this issue?
On a more philosophical note, why has Interface been corrupted with with implementation :-(. Might be a nifty new feature, but they really should have avoided doing anything that would result in breaking changes to existing code, particularly in something so fundamental as lists/collections etc.
Any help or suggestions regarding this predicament would be greatly appreciated.
Cheers,
Mark
The whole point of default methods is to avoid the situation you describe. The code below compiles and runs as expected with Java 7 and 8:
public class SortedList<T> extends AbstractList<T> implements Serializable {
#Override public T get(int index) { return null; }
#Override public int size() { return 0; }
public static void main(String[] args) {
SortedList<String> s = new SortedList<> ();
System.out.println(s.size());
}
}
Ok, so both of you (#Holger and #assylias) were correct... But, our situation is a little more complicated.
The environment we're working in is Eclipse 3.8.1 which doesn't support Java 8 (and won't in the future to my knowelege). So we can't just change to a Java 8
compiler to fix the issues.
Our product is a sizeable Eclipse RCP application. Upgrading our IDE is not currently an option, as there would be major rework involved. We will need to continue
to develop under a Java 1.7 environment for this reason.
If anyone is interested, we have resolved the issue by:
Creating fragments (one per Java version that causes issues, so three in our case) for our main plugin. These fragments are configured as patch fragments.
Added the Java FX JARs into the fragments (This was done to resolve some issues with Java FX in an earlier release and again for the 1.8.0_25 release).
Also in the fragments, in the same namespace as the main plugin, we added the implementation of the SortedList class. The code is identical for each case, but
the fragment for Java 8 is compiled specifically with a Java 8 compiler. Overriding the spliterator() method wasn't necessary in the end (when compiled with the Java 8
compiler, it works ok and still compiles with the 1.7 compiler as there is no reference to the Spliterator class anymore).
This is probably not an ideal solution, but it will work we think :-).
Thanks for your input & suggestions, much appreciated.
try Creating an abstract class that overrides the spliterator() with the prefered behaviour definition i.e.
abstract class Java8_AbstractCollection<E> extends AbstractCollection<E> {
/* (non-Javadoc)
* #see java.util.Collection#spliterator()
*/
public Spliterator<E> spliterator() {
return (Spliterator<E>) super.spliterator();
}
}

Eclipse finds syntax errors that netbeans doesn't

I have recently switched from Netbeans to Eclipse, and Eclipse is finding syntax errors in my Project lot's of places that Netbeans doesn't and I cannot figure out why. As far as can tell both IDE's are set to use java 1.6. An example of this problem would be as follows (which is actually horrible code but I am working with legacy stuff):
Map map;
map = new Hashtable();
... add some stuff to map
int number = 5;
int status = 7;
assertTrue(number == map.get(status));
The above comes back with "Incompatable operand types int and Object" whereas Netbeans does not complain at all. I do not actually following why this doesn't work (does the int object not get autoboxed to an Integer?) as it works at run time from Netbeans. I am presuming there is a configuration setting somewhere in eclipse?
It looks like autoboxing is disabled. Check that Window->Preferences->Java->Compiler->Errors/Warnings Boxing and unboxing conversion is not set to Error. Also check that Window->Preferences->Java->Installed JRE use JDK\JRE that is at least 1.5.
You can setup compiler-warnings under Window->Preferences->Java->Compiler->Errors/Warnings.
Make also sure you're compiling against the correct Java Version (check if your 1.6 Java is in the build-path and check the JDK Compilance level, see Preferences->Java->Compiler)
Change declaration to
Map<Integer,Integer> map;
map = new Hashtable<Integer,Integer>();
and this will solve you problem.
Alternatively, you can change this line
assertTrue(Integer.valueOf(number) == map.get(status));
Comparing Integer with == is not good practice. It is working just occasionally. You really should use equals() instead.
I don't why autoboxing in your case doesn't occurs automatically, maybe somebody that know spec better could provide answer.
P.S. Even better change this to
assertEquals(number, map.get(status));
and this will work as expected.
After clarifications that it is legacy code, my advice is the following. Change your code to:
Map map;
map = new Hashtable();
... add some stuff to map
Integer number = Integer.valueOf(5);
Integer status = Integer.valueOf(7);
assertEquals(number, map.get(status));
(I would even define temporary variable of type Integer where I put result of map.get(status), but it is question of the style whether to do this; This will help compiler though). Here, no new features is used.
Why you don't have problem with the Netbeans? My guess is because your version of JRE (or vendor) or your project settings.

Why am I getting NullPointerException in the CompilationUnit instances returned from ASTParser.createASTs()

I am working on an Eclipse JDT plugin that requires parsing large numbers of source files,
so I am hoping to use the batch method ASTParser.createASTs(). The parsing executes without errors, but within the CompilationUnit instances it produces, many of the org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding instances have had their scope field set to null. This setting to null is occurring in the CompilationUnitDeclaration.cleanUp() methods, which are invoked on a worker thread that is unrelated to my plugin's code (i.e., my plugin's classes do not appear on the cleanUp() method call stack).
My parsing code looks like this (all rawSources are within the same project):
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setResolveBindings(true);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
parser.setIgnoreMethodBodies(false);
parser.setProject(project);
parser.createASTs(rawSources.values().toArray(new ICompilationUnit[0]), new String[0], this, deltaAnalyzer.progressMonitor);
Alternatively, I can execute the parsing this way, and no such problems occur:
for (ICompilationUnit source : rawSources.values())
{
parser.setResolveBindings(true);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
parser.setIgnoreMethodBodies(false);
parser.setProject(project);
parser.setSource(source);
CompilationUnit ast = (CompilationUnit)parser.createAST(deltaAnalyzer.progressMonitor);
parsedSources.add(deltaAnalyzer.createParsedSource(source, ast));
}
This issue occurs in both Helios and Indigo (the very latest release build). I filed a bug in Eclipse Bugzilla, but if anyone knows of a way to work around this--or if I am using the API wrong--I would greatly appreciate your help.
Byron
Without knowing exactly what your exception is, I can still offer 2 suggestions:
Have a look at org.eclipse.jdt.ui.SharedASTProvider. If you are not making any changes to ASTs, this class may provide a more robust way of getting the ASTs.
Play around with some of the settings that you are using. Do you really need bindingsRecovery set to true? What about statementRecovery? Setting these to false may help you.