Importing Groovy classes in a GWT module in Intellij - gwt

Basically I can't even import Groovy classes in a regular GWT EntryPoint:
import com.google.gwt.core.client.EntryPoint; // OK
import groovy.lang.Binding; // NOT OK
import groovy.util.GroovyScriptEngine; // NOT OK
Intellij 8.0's inspector keeps telling me this:
Class 'groovy.lang.Binding' is not present in JRE Emulation Library so it cannot be used in client code
Class 'groovy.util.GroovyScriptEngine' is not present in JRE Emulation Library so it cannot be used in client code
Obviously I end up having problems at runtime as well:
[ERROR] Line 11: No source code is available for type groovy.util.GroovyScriptEngine; did you forget to inherit a required module?
[ERROR] Line 12: No source code is available for type groovy.lang.Binding; did you forget to inherit a required module?
I've checked several times my module's dependencies, and groovy-all-1.6.1.jar is correctly defined in there. I'm probably missing something elsewhere...
Any idea?

Attempting to use Groovy makes no sense as the Gwt compiler only understands the Java language syntax along it it's subset of Java libraries. The compiler works on source not byte code. One reason includes the magic comments necessary to stash javascript (JSNI). The compiler is actually scanning the source path for *.java not *.class files.
Read the doco fir a more in depth understanding.

In some sense it would be pretty cool to have a groovy language gwt.
But then why go from one dynamic language to another? The point of gwt I thought was to get static typing and easy debugging of java.

Related

Referring to a non-existent class java.io.File

This question appears fundamentally the same as Linker error in ScalaJS: "Referring to non-existent class", but seems to differ in specifics. I don't specify a JVM version in build.sbt.
I'm trying to access a file in my scalajs app using scala.io.Source, or java.io.File. As soon as I attempt to use either I get a link fail:
...
[info] Fast optimizing C:\Users\Tim\Documents\GitHub\binpack\target\scala-2.11\binpack-fastopt.js
[error] Referring to non-existent class java.io.File
[error] called from client.jsClient$.onFileChosen(japgolly.scalajs.react.SyntheticEvent)scala.Function0
...
Is there a method by which I can diagnose what's going on here? I'm assuming the problem is not specific to java.io.File, but don't know what the next step would be.
This is scala 2.11.8, with sbt 0.13.7.
java.io.File is not portable to Scala.js because it's specifically tied to the JVM. See http://www.lihaoyi.com/hands-on-scala-js/#PortingJavaAPIs (just scroll to the very bottom) for a little more detail.
So, if you want to do filesystem IO in Scala.js, you'll need to use a solution specifically implemented for JavaScript, like io.js. Here's an example: http://bchazalet.github.io/2015/07/20/scalajs-electron-skeleton-part-2/

Working with Linux shared objects in Scala

How can I access *.so object and it's methods in Scala? Here is a Python example: https://github.com/soulseekah/py-libgfshare/blob/master/gfshare.py where ctypes library is used to interact with libgfshare.so. What tools do I need to use to achieve the same in Scala?
If you would like to interact with a native library which doesn't support JNI (Java Native Interface) (that is, not designed especially for interacting with Java VM), try JNA (Java Native Access). There's also Scala Native Access project on Google Code, which seems to provide more "scala-friendly" API, but it seems inactive (last commit was in 2010).
The previous answer is quite correct that JNI is the way to go but getting it all to work requires a little perseverance. An example of a multi-platform Scala interface to a real world native library can be found here. As a summary, the steps you need to take are detailed below.
First, define the Scala interface that you want to use to access your native library with. An example of a native interface declaration in Scala is:
package foo.bar
object NativeAPI {
#native def test(data: Array[Byte]): Long
}
Compile this file using scalac and then use javah to output a suitable C/C++ header file for the JNI native stub. The javah header generator (part of Java SDK) needs to be invoked as
javah -classpath <path-to-scala-libs> foo.bar.NativeAPI$
Note that the $ is added to Scala objects by the Scala compiler. The functions generated in this header will be called when you call the API from the JVM. For this example, the javah generated C header's declaration for this function would look like this:
JNIEXPORT jlong JNICALL Java_foo_bar_NativeAPI_00024_test(JNIEnv *, jobject, jbyteArray);
At this point, you need to create a C file which then maps this function from your JVM api to the native library you intend to use. The resulting C file needs to be compiled to a shared library (.so in Linux) which references the native library you want to call. The C interface into the JVM is described here.
For this example, lets call this library libjni-native.so and assume it references a 3rd party library called libfoo.so.0. If both these libraries are available in the dynamic library search path of your OS, then you need to instruct the JVM to load the library and call the function as follows:
System.loadLibrary("libjni-native.so")
val data = new Array[Byte](100)
// Populate 'data'
NativeAPI.test(data)
On Linux and OSX machines, the dynamic linker will know that libfoo.so.0 (.dylib for OSX) is a dependency of libjni-native.so and will load it automatically. You can now call the test function from Scala. You should now be able to make a call to foo.bar.Native.test() and have the native function executed.
In the real world, you probably need to bundle the .so libraries into a JAR file for distribution. To do this, you can place the shared libraries in a suitable directory in the resources directory of your project. These libraries need to be copied from the JAR file to a temporary directory at run time and then loaded using System.load("/tmppath/libjni-native.so"). LibLoader from the example shows one way how this can be achieved.

No source code is available for type in GWT (abstract class)

I have a business object (called Expense) that I am trying to use in my GWT application. I have it imported in the class, but when I compile, I get the following error:
[ERROR] Line 67: No source code is available for type com.app.pojo.Expense; did you forget to inherit a required module?
Is there anything special that I have to do (addition to gwt.xml?) to use it?
I dont' know how your Expense class looks like, but you can't use either Gson or SimpleDateFormat in GWT code. See the JRE emulation list of the only available types. You have to use both on the server. You can use DateTimeFormat on client/shared sides.
I'm assuming you have already added com.app.pojo as a translatable package (i.e., using source-path in your XML module).
Apparently I cannot use the gson library, nor the SimpleDateFormat class with gwt?

JDK 1.7 compiler does not recognize generic class

I have a class which uses a class from Eclipse OSGI jar (org.eclipse.osgi_3.7.2.v20120110-1415.jar) and which is well compiled within Eclipse IDE and it's compiler. But if I try to compile this class with Ant and JDK 1.7 compiler, the compiler outputs these errors:
[javac] /data/ant/sw_jdk1.7/test-Java7/com.tsystems.favbg.ui.core/src/com/
tsystems/favbg/ui/core/job/AbstractLoader.java:24:
error: type CopyOnWriteIdentityMap does not take parameters
[javac] private final CopyOnWriteIdentityMap<LoaderListener, String>
eventListenerMap = new CopyOnWriteIdentityMap<>();
and
error: cannot infer type arguments for CopyOnWriteIdentityMap;
[javac] private final CopyOnWriteIdentityMap<LoaderListener, String>
eventListenerMap = new CopyOnWriteIdentityMap<>();
[javac] reason: cannot use '<>' with non-generic class CopyOnWriteIdentityMap
Obviously javac does not recognize the class as using generics. But when I open it with Java Decompiler generic parameters are well recognized.
Does anybody know this problem and have a solution?
I would say that the problem is in the way that you are using CopyOnWriteIdentityMap class. I'm assuming that you are using this class:
org.eclipse.osgi.framework.eventmgr.CopyOnWriteIdentityMap
If you look at the javadocs, you will see that it is not a generic class. I also get the impression (from its package location) that it is not intended to be a general purpose utility class.
Perhaps you are using a different version of the JAR when you are compiling in Eclipse ... one that is a generic class. Either way, the compiler you are using via Ant thinks it is not generic.
I am finding discrepancies when reading a certification book for SCJP based on JDK 1.6, and, trying to write (copy and paste) code, compiling within JDK 1.7.
Perhaps, I am making the same mistakes all over, however they seem hard to comprehend. For example see my posts at http://www.coderanch.com/forums/posts/list/80/467890#2679297. I am not an expert, however, I find the curriculum of Angelika Langer (http://www.angelikalanger.com/Publications.html), to be appealing for consulting, given the tutorials available on the website relating to Java Generics.
What is your advice on the matter?

Import customization in Groovy-Eclipse for DSL

I'm using Groovy for a calculation engine DSL and really like the support we now have in Eclipse with STS and the Groovy-Eclipse plug-in (I'm on STS 2.8.0M2 with latest milestone of Groovy-Eclipse 2.5.2).
One issue I have is I don't know how to get the Groovy editor to 'know' the automatic imports I've added to my script runner, meaning Eclipse gives me a whole bunch of false errors. If you use the Groovy class loader, you can add additional import for 'free', so you avoid needing to do imports in your script.
I've had a play with the DSLD support in Groovy-Eclipse (which can be used to add auto-completion support) but it's not obvious to me that this is something I could do with it - I don't find the DSLD documentation the simplest to follow.
The inferencing settings for Groovy in Eclipse didn't look like the right thing either.
For example:
def result = new CalculationResult()
gives me an error on the CalculationResult class as it's not imported, but the script will execute correctly in my environment because of the customized imports on the Groovy class loader. I'm using the standard import customization provided by Groovy, for example:
import org.codehaus.groovy.control.customizers.ImportCustomizer
import org.codehaus.groovy.control.CompilerConfiguration
def importCustomizer = new ImportCustomizer()
importCustomizer.addImport 'CalculationResult', 'ch.hedgesphere.core.type.CalculationResult'
def configuration = new CompilerConfiguration()
configuration.addCompilationCustomizers(importCustomizer)
...
Any pointers appreciated.
This seems to be in their bugtracker as coming in the 2.6 release of the plugin.
But the comment from Andrew Eisenberg doesn't bode well:
Unfortunately, this is not something that DSLDs can do. Since a
missing import could mean compile errors, we would need a way to
augment the compiler lookup for this. There might be a way to specify
this information inside of a DSLD, but that would mean hooking into
DSLDs in a very different way. More likely, this will have to be
specified through an Eclipse plugin (like the gradle tooling).
Another possibility is that we can ensure that certain kinds of AST
Transforms are applied during a reconcile and so the editor would just
"magically" know about these extra imports. We will have to look into
the feasibility of this, however.
Still, maybe a vote on that issue wouldn't go amiss?