AssertionError while using Scala 2.10-M3 reflection - reflection

I am trying to invoke the method typeOfInstance() in the following (simplest) code:
import scala.reflect.mirror._
class Bar
object Main extends App {
val bar = new Bar()
typeOfInstance(bar)
}
but I am receiving an AssertionError while executing it:
java.lang.AssertionError: assertion failed: no symbol could be loaded from package annotation (scala equivalent is class com.hablapps.annotation.Bar) by name Bar
The above code runs fine in the REPL (with :power mode). The problem arises while running from SBT (with Scala 2.10-M3 set). Does anybody know what could be happening?

This is a known issue with M3.
In that preview version of Scala, reflection only works with straightforward classloading schemes (e.g. when you run your application using good old java -cp <classpath> <name of the main class>). SBT is a bit more involved, and things blow up.
We've fixed this in 2.10.0-M4.

Related

Replicating a java -jar execution through rJava

I have a java file that I would normally execute by doing
java -jar jarname.jar arguments
I want to be able to run this file from R in the most system agnostic way possible. My current pipeline partially relies on rJava do identify JAVA_HOME and run the jar by doing
# path for the example file below
pathToJar = 'pdftk-java.jar'
# start up java session
rJava::.jinit()
# find JAVA_HOME
javaPath = rJava::.jcall( 'java/lang/System', 'S', 'getProperty', 'java.home' )
# get all java files
javaFiles = list.files(javaPath,recursive = TRUE,full.names = TRUE)
# find java command
java = javaFiles[grepl('/java($|\\.exe)',javaFiles)]
# run the jar using system
system(glue::glue('{shQuote(java)} -jar {shQuote(pathToJar)} arguments'))
This does work fine but I was wondering if there was a reliable way to replicate execution of a jar through rJava itself. I want to do this because
I want to avoid any possible system dependent issues when finding the java command from JAVA_HOME
I already started an rJava session just to get the JAVA_HOME. I might as well use it since .jinit isn't undoable
I not that familiar with what calling a jar through -jar does and I am curious. Can it be done in a jar independent way? If not what should I look for in the code to know how to do this.
This is the file in I am working with. Taken from https://gitlab.com/pdftk-java/pdftk/tree/master
Executing JAR file is (essentially) running class file that is embedded inside JAR.
Instead of calling system and executing it as external application, you can do following:
make sure to add your JAR file to CLASSPATH
rJava::.jaddClassPath(pathToJar)
check inside JAR file what is the main class. Look into META-INF/MANIFEST.MF file to identify the main class. (In this case com.gitlab.pdftk_java.pdftk)
instantiate class inside R.
newObj = rJava::.jnew('com/gitlab/pdftk_java/pdftk')
run the class following way: http://www.owsiak.org/running-java-code-in-r/
Update
Running JAR file (calling main method of Main-class) is the same things as calling any other method inside Java based class. Please note that main method takes array of Strings as argument. Take a look here for sample: http://www.owsiak.org/running-jar-file-from-r-using-rjava-without-spawning-new-process/
newObj$main(rJava::.jarray('--version'))
For this specific case if you look at the source code for this class, you'll see that it terminates the session
public static void main(String[] args) {
System.exit(main_noexit(args));
}
This will also terminate your R session. Since all main function does it to call main_noexit then exit, you can replace main with main_noexit in the code above.
newObj$main_noexit(rJava::.jarray('--version'))

command line compiling generates bigger file than the online version

I am testing google closure compiler on command line.
I took the latest version :
java -jar closure-compiler.jar --version
Closure Compiler (http://github.com/google/closure-compiler)
Version: v20190618
Built on: 2019-06-21 17:24
I am generating a compressed version of my javascript like this :
java -jar closure-compiler.jar my_script.js > out.js
The problem is that the generated code is bigger than the one I get when I use the online service at https://closure-compiler.appspot.com/home
I noticed that the command line version added, at the beginning, the following code :
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(a,c,b){a instanceof String&&(a=String(a));for(var d=a.length,e=0;e<d;e++){var f=a[e];if(c.call(b,f,e,a))return{i:e,v:f}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,c,b){a!=Array.prototype&&a!=Object.prototype&&(a[c]=b.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(a,c,b,d){if(c){b=$jscomp.global;a=a.split(".");for(d=0;d<a.length-1;d++){var e=a[d];e in b||(b[e]={});b=b[e]}a=a[a.length-1];d=b[a];c=c(d);c!=d&&null!=c&&$jscomp.defineProperty(b,a,{configurable:!0,writable:!0,value:c})}};$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(a,b){return $jscomp.findInternal(this,a,b).v}},"es6","es3");
I do not have such a code in my script: Where does it come from ?
how can I produce the same output as the online version ?
To get the compiler command line work as the web service, I just added an option :
--language_out=ECMASCRIPT_2015
This is likely a discrepancy between the settings on the web service and the ones you're using locally.
Have a look at a Closure Compiler: Flags and Options to see what settings you might prefer.
If you'd share your source, it'd be possible to try and help you narrow down the options.
As for the extra code, I believe it is at least partially a polyfill for Array.prototype.find (aka [].find), which I assume is in your code?
If so, that's Closure injecting code to improve your cross browser compatibility.

How to get sbt to pick up tests written in groovy?

I've found the sbt-groovy plugin and it properly compiles both the test and the main sources just fine. However, the definedTests key is always empty; SBT never discovers any groovy tests. I've verified this with a very simple single src/test/groovy/Test.groovy with a single method annotated #Test which should be picked up by the junit-interface.
I think the root of the issue is that the sbt-groovy plugin needs to define the task "definedTests" in its own plugin source code. This task provides a Seq[TestDefinition].
Looking at how SBT itself populates the sequence reveals it uses additional output from the scala compiler (which also happens to compile java files, so it works out of the box for java) in an Analysis class which is populated by output from the IncrementalCompiler
I've fiddled around with the taskdef, but I'm not sure I'm even on the right path. Documentation on this stuff is pretty sparse, or heavily connected to the IncrementalCompiler.
What code do I need in sbt-groovy to produce a Seq[TestDefinition] that satisfies SBT so that I can run tests (picked up by the junit-interface) that are written in Groovy?
The test detection code is in Tests.discover, which you might be interested in.
It seems like all you need is the list of methods with annotations and list of subclasses.
If you have some way of finding them out, you probably could mimic what's going on in the code.
The discovery code, as you mentioned, relies on the the Analysis datatype, which is the inner gut of
the incremental compiler. You might be able to take advantage of the fact that it is
sbt (not Scala or Java compiler) that is responsible for incremental compilation.
For Java compilation, AnalyzingJavaCompiler.compile calls the compiler and then does the analysis.
In theory, you could define an AnalyzingGroovyCompiler that uses the same mechanism
as the one used for the Java compilation. This is not exactly a walk in the park since
some of the parts are hidden behind private[sbt].
Long story short, I put together a hacky proof-of-concept that wrangles the incremental compiler into generating Analysis for Groovy code, and was able to detect a test.
https://github.com/eed3si9n/sbt-groovy-test
I've only tested with one simple use case
import org.junit.Test
import org.junit.Assert
class Foo {
#Test
public void foo() {
Assert.assertEquals(1, 2)
}
}
Running test from sbt yeilds the following output:
> test
[info] Start Compiling Test Groovy sources : /Users/xxx/sbt-2167-groovy/src/test/groovy
[error] Test Foo.foo failed: expected:<1> but was:<2>, took 0.062 sec
[error] Failed: Total 1, Failed 1, Errors 0, Passed 0
[error] Failed tests:
[error] Foo
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 1 s, completed Aug 23, 2015 5:05:01 AM
It might not work with future versions of sbt. Caveat emptor.

SBT configuration failed to load in Typesafe Activator

I'm currently trying to start a play-slick application through the Typesafe Activator, but it fails to load the SBT configuration and I get this error;
/play-slick/build.sbt:30: error: reference to fork is ambiguous;
it is imported twice in the same scope by
import _root_.play.Project._
and import Keys._
fork in run := true
^
Type error in expression
Failed to load project.
Does this mean I have SBT downloaded twice and what can I do to resolve it? Thanks.
Just wanted to say that I came across this exact same issue when trying to use the Play-Slick example linked from the Play Tutorials page.
The solution to get it working seems to have indeed been to follow the suggestion in the Github link that Seth Tisue included in a comment above, where corruptmemory suggested removing the following line from build.sbt:
fork in run := true
In my case, this was enough to convince IntelliJ to open the project and let me tinker with it. (Just in case this is the first result for anyone else coming across this problem)
just remove
fork in run := true
from build.sbt and hit activator clean run from cmd

Instantiating RInScala results in NoSuchMethodError

I'm trying to integrate R into Scala using JVMR. I am getting a NoSuchMethodError when attempting to instantiate RInScala.
I'm working on a Windows 7 machine with R installed under C:\Program Files\R\R-3.1.1 and Scala version 2.11.1 is installed under C:\Program Files (x86)\scala. I'm developing in IntelliJ with the Scala plugin and am using the Scala worksheet just to test this out as a POC. My Scala project does show JVMR 2.11-2.11.1.1.jar as an included library. The worksheet is very basic at present - just the import and the instantiation attempt.
import org.ddahl.jvmr.RInScala
val R = RInScala()
When running the worksheet in IntelliJ, I see the following output, so I can tell that it's successfully importing the class, but can't instantiate.
import org.ddahl.jvmr.RInScala
java.lang.NoSuchMethodError: scala.runtime.ObjectRef.create(Ljava/lang/Object;)Lscala/runtime/ObjectRef;
at org.ddahl.jvmr.RInScala$.findROnWindows(RInScalaTest.sc2318647708135405919.tmp:804)
at org.ddahl.jvmr.RInScala$.defaultExecutable$lzycompute(RInScalaTest.sc2318647708135405919.tmp:822)
at org.ddahl.jvmr.RInScala$.defaultExecutable(RInScalaTest.sc2318647708135405919.tmp:821)
at org.ddahl.jvmr.RInScala.<init>(RInScalaTest.sc2318647708135405919.tmp:28)
at org.ddahl.jvmr.RInScala$.apply(RInScalaTest.sc2318647708135405919.tmp:838)
at com.xxxx.r_in_scala.A$A1$A$A1.R$lzycompute(RInScalaTest.sc2318647708135405919.tmp:2)
at com.xxxx.r_in_scala.A$A1$A$A1.R(RInScalaTest.sc2318647708135405919.tmp:2)
at com.xxxx.r_in_scala.A$A1$A$A1.get$$instance$$R(RInScalaTest.sc2318647708135405919.tmp:2)
at #worksheet#.#worksheet#(RInScalaTest.sc2318647708135405919.tmp:10)
I've drilled into the code for findROnWindows and my installation should be found based on the values of the registry keys that are being read. I'm sure I'm missing something simple, but am at that "I've been looking at the problem for too long without figuring it out and just need a new set of eyes" stage.
To my knowledge this is currently some kind of bug in the worksheet implementation by IntelliJ or indeed a misconfiguration. To verify:
Put your code in an object
package starter
object Test extends App {
import org.ddahl.jvmr.RInScala
val R = RInScala()
println("works")
}
and try to run it as a scala app and not from the worksheet.

Resources