How do I access Java enums from Scala? - scala

My java class is as follows
public class Test {
protected enum TestEnum {A, B, C};
public Test(TestEnum te) {
}
}
here is my Scala
class ScalaEnum(myEnum: TestEnum) extends Test(myEnum) {
}
I receive the following error message
class TestEnum in object Test cannot be accessed in object Test Access to protected class TestEnum not permitted because enclosing class class ScalaEnum in package XXX is not a subclass of object Test in package YYY where target is defined

As #Alex and #Jean-Phillipe said, this has not much to do with the fact that you're trying to access an enum and more to do with the fact that inner-class enums are implicitly static: see this answer, for example.
That means that you're running up against this limitation. Changing TestEnum to be public works around the problem for me with Scala 2.9.1.
Having said all that, despite Martin's vehement objections to removing the limitation, your code works as expected with Scala 2.10.

It sounds like the enum class is implicitly static, because Scala calls it "object Test". Try qualifying it in the constructor (e.g. Test.TestEnum), and if that doesn't work, relaxing the visibility to package access might.

Related

Why does Scala place a dollar sign at the end of class names?

In Scala when you query an object for either its class or its class name, you'll get a rogue dollar sign ("$") at the tail end of the printout:
object DollarExample {
def main(args : Array[String]) : Unit = {
printClass()
}
def printClass() {
println(s"The class is ${getClass}")
println(s"The class name is ${getClass.getName}")
}
}
This results with:
The class is class com.me.myorg.example.DollarExample$
The class name is com.me.myorg.example.DollarExample$
Sure, it's simple enough to manually remove the "$" at the end, but I'm wondering:
Why is it there?; and
Is there anyway to "configure Scala" to omit it?
What you are seeing here is caused by the fact that scalac compiles every object to two JVM classes. The one with the $ at the end is actually the real singleton class implementing the actual logic, possibly inheriting from other classes and/or traits. The one without the $ is a class containing static forwarder methods. That's mosty for Java interop's sake I assume. And also because you actually need a way to create static methods in scala, because if you want to run a program on the JVM, you need a public static void main(String[] args) method as an entry point.
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
object Main { def main(args: Array[String]): Unit = ??? }
// Exiting paste mode, now interpreting.
scala> :javap -p -filter Main
Compiled from "<pastie>"
public final class Main {
public static void main(java.lang.String[]);
}
scala> :javap -p -filter Main$
Compiled from "<pastie>"
public final class Main$ {
public static Main$ MODULE$;
public static {};
public void main(java.lang.String[]);
private Main$();
}
I don't think there's anything you can do about this.
Although all answer that mention the Java reflection mechanism are correct this still doesnot solve the problem with the $ sign or the ".type" at the end of the class name.
You can bypass the problem of the reflection with the Scala classOf function.
Example:
println(classOf[Int].getSimpleName)
println(classOf[Seq[Int]].getCanonicalName)
=> int
=> scala.collection.Seq
=> Seq
With this you just have the same result as you have in for example Java
There are several problems with your approach:
You are using Java Reflection. Java Reflection doesn't know anything about Scala.
Furthermore, you are using Java Reflection on a Singleton Object, a concept that doesn't even exist in Java.
Lastly, you are using Java Reflection to ask for the class of a Singleton Object, but in Scala, Singleton Objects aren't instances of a class.
So, in other words: you are asking the wrong language's reflection library to reflect on something it doesn't understand and return something that doesn't even exist. No wonder you are getting nonsense results!
If you use Scala Reflection instead, the results become a lot more sensible:
import scala.reflect.runtime.{universe => ru}
def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
object Foo
val theType = getTypeTag(Foo).tpe
//=> theType: reflect.runtime.universe.Type = Foo.type
As you can see, Scala Reflection returns the correct type for Foo, namely the singleton type (another thing that doesn't exist in Java) Foo.type.
In general, whereas Java Reflection deals mainly in classes, Scala Reflection deals in Types.
Using Scala Reflection instead of Java Reflection is not only better because Java Reflection simply doesn't understand Scala whereas Scala Reflection does (in fact, Scala Reflection is actually just a different interface for calling into the compiler, which means that Scala Reflection knows everything the compiler does), it also has the added benefit that it works on all implementations of Scala, whereas your code would break on Scala.js and Scala-native, which simply don't have Java Reflection.
This is a result of compiling to the JVM. To make an object in scala requires two classes. The "base" class and the class to make the singleton object. Because these classes can't both have the same name, the $ is appended. You could probably modify the compiler so that it won't make a $ but you will still need some way to name the generated class names.

what does this extra private[class]() in scala class definition mean?

I'm reading over someone elses code on Scala in order to learn the language a little better, but I'm stumped at what the following means "privateutil" If I just saw the [util] I would suspect that it was some sort of specific generic? but its got it's own private modifier?
class RPGPluginProperties private[util]() extends Properties {
From http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#private:
A private modifier can be qualified with an identifier C (e.g.
private[C]) that must denote a class or package enclosing the
definition. Members labeled with such a modifier are accessible
respectively only from code inside the package C or only from code
inside the class C and its companion module.
So in this case the private modifier is making the no-args constructor private to the util class/package.
To declare the class private to the scope util, it would be private[util] class RPGPluginProperties...

How can I provide a scala companion object's class to Java?

I have a Java code that looks for annotations in static methods of a class.
processor.readStatics( MyClass.class ); // Takes Class<?>
How can I provide the methods of a scala companion object to this function from within scala?
class MyClass {
}
object MyClass {
def hello() { println("Hello (object)") }
}
I seems that:
MyClass$.MODULE$.getClass()
should be the answer. However, MyClass$ seems to be missing from scala (in 2.10, at least) and only visible to Java.
println( Class.forName("MyClass$.MODULE$") )
also fails.
Class name is MyClass$ (with the appropriate package name prepended).
println(Class.forName("MyClass$")) will print out "class MyClass$".
MyClass$.MODULE$ is the instance of the class, referencing the singleton object.
println(MyClass$.MODULE$ == MyClass) will print out "true" even though, when compiling, you will get a warning that this comparison always yields false :)
Note, that none of this works in repl for some reason. You need to actually create a .scala file, compile it with scalac, and run.
So, in java, use MyClass$ to reference the class of MyClass object statically, use MyClass$.MODULE$ to reference the singleton instance of MyClass object, use MyClass$.class or MyClass$.MODULE$.getClass() to reference the class of the singleton object dynamically, use Class.forName("MyClass$") to access it at runtime by name.
The shortest and type-safest solution is to simply use
MyClass.getClass
I would have hoped the following to work, but apparently scalac is not happy with it:
classOf[MyClass.type]

I can haz no package-private class in Scala?

Sorry for the catchy title. ;-)
I want to create a package-private class with a package-private method in Scala, so my class looks somewhat like this:
package net.java.truevfs.ext.pace
import ...
private[pace] abstract class AspectController(controller: FsController)
extends FsDecoratingController(controller) {
private[pace] def apply[V](operation: => V): V
... // lots of other stuff
}
However, if I use javap to check what the Scala compiler effectively creates, I get something like this:
$ javap -classpath target/classes net.java.truevfs.ext.pace.AspectController
Compiled from "AspectController.scala"
public abstract class net.java.truevfs.ext.pace.AspectController extends net.java.truevfs.kernel.spec.FsDecoratingController implements scala.ScalaObject{
public abstract java.lang.Object apply(scala.Function0);
...
}
This means that although the Scala compiler might respect the access restrictions, I could still call this class from any Java code, which is a clear encapsulation violation.
Am I missing something?
Is there a way to make this work as intended?
In addition to #RĂ©gis' answer, the reason Scala compiler doesn't make the class package-private is because by Scala rules it can be accessed from other packages: namely, subpackages of net.java.truevfs.ext.pace. E.g.
package net.java.truevfs.ext.pace.subpackage
import net.java.truevfs.ext.pace.AspectController
class Subclass extends AspectController { ... }
is legal in Scala, but in Java classes from net.java.truevfs.ext.pace.subpackage can't access package-private classes from net.java.truevfs.ext.pace.
You are not missing anything.
Many of the access restricitons in scala have no equivalent in java nor at the jvm level. The additional information is obviously right there in the .class file, but is there as custom annotations that only the scala compiler will interpret.
The scala object model can only partly be matched to the jvm object model, and a java compiler will only see this partial model.
I'd say that the match is pretty close and the scala compiler does a very good job at java interoperability, but nothings's perfect.
Not really a 100% correct answer...
You can make a package object if I want to do some fancy stuff in there with a private class. The package object is accessed like any other package.
The class MyClass is package private to that package object.
It's not package private however.
package object com.jasongoodwin.foo {
private class MyClass
class AnotherClass {
val myClass = new MyClass
}
}

How do you access variables of super class of passed class in Groovy Script Engine?

I'm dynamically running groovy scripts from scala. And there are some instances of some class passed to groovy scripts via setProperty(). For example, say you have a class named TestA and class TestB inherits class TestA. And you are passing an instance of class B to groovy script like this
setProperty("testB", testB) // testB is an instance of class TestB
and running the groovy script, I can access variables declared in TestB. but when I try to access variables of TestA, which is super class of TestB, the groovy gives an error saying " No such property for class".
I can still call methods of both TestA and TestB from the given instance. So if you just write setter and getter, I can access to TestA's variables but I don't want to do it.
Is there anyway to access TestA's variables without using setter/getter? like using Expando or something?
Since you don't want to write the getters/setters yourself (which would be ugly boilerplate in Scala), you can simply add the scala.reflect.BeanProperty annotation (or scala.reflect.BooleanBeanProperty) to any fields you'd like to access from another JVM language. This will give you a more accessible API.
#scala.reflect.BeanProperty // generates getStatus() and setStatus() methods
var status = ""
Actually, after giving it more thought, you could simply access the accessor methods that Scala generates for itself. You may be able to access Scala's accessor methods from Groovy, but accessing the setter variable_$eq may look a bit weird.
[dlee#dlee-mac scala]$ cat Prop.scala
class Prop {
var variable = "foo"
val constant = "bar"
}
[dlee#dlee-mac scala]$ scalac Prop.scala
[dlee#dlee-mac scala]$ javap Prop
Compiled from "Prop.scala"
public class Prop extends java.lang.Object implements scala.ScalaObject{
public java.lang.String variable();
public void variable_$eq(java.lang.String);
public java.lang.String constant();
public Prop();
}