is there a way to define custom annotations in Scala without resorting the use Java interfaces?
I saw this answer which says it's not possible, but is pretty old (dates back to 2010).
But, even with a recent Scala 2.11.8 compiler, I got the usual message:
warning: Implementation restriction: subclassing Classfile does make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java.
I'm kinda puzzled: it's 2016 and yet, seems like we can't create annotations natively from Scala. Is there any reason about this, or am I doing it wrong somehow?
Thanks!
Related
I just realized I cannot have annotations in scala, that are preserved and analyzed at runtime. I also checked this question, but I didn't quite get it what are the alternatives.
DI - an answer mentions that there is no need for DI framework in scala. While that might be the case on a basic level (although I didn't quite like that example; what's the idiomatic way of handling DI?), Java DI frameworks like spring are pretty advanced and handle many things like scheduled jobs, caching, managed persistence, etc, all through annotations, and sometimes - custom ones.
ORM - I'll admit I haven't tried any native scala ORM, but from what I see in squeryl, it also makes some use of annotations, meaning they are unavoidable?
any serialization tool - how do you idiomatically customize serialization output to JSON/XML/...?
Web service frameworks - how do you define (in code) the mappings, headers, etc. for RESTful or SOAP services?
Scala users need to have a hybrid scala/java (for the annotations) project in order to use these facilities that are coming from Java?
And are the native scala alternatives for meta-data nicer than annotations? I'm not yet fully into the scala mode of thinking, and therefore most of the examples look ugly to me, compared to using annotations, so please try to be extra convincing :)
Actually, Scala does have runtime-retained annotations. The difference is that they are not stored as Java annotations but are instead encoded inside the contents of binary ScalaSignature annotation (which, by itself, is a runtime-retained Java annotation).
So, Scala annotations can be retrieved at runtime, but instead of using Java reflection, one must use Scala reflection:
class Awesome extends StaticAnnotation
#Awesome
class AwesomeClass
import scala.reflect.runtime.universe._
val clazz = classOf[AwesomeClass]
val mirror = runtimeMirror(clazz.getClassLoader)
val symbol = mirror.classSymbol(clazz)
println(symbol.annotations) // prints 'List(Awesome)'
Unfortunately, Scala reflection is still marked as experimental and is actually unstable at this point (SI-6240 or SI-6826 are examples of quite serious issues). Nevertheless, it seems like the most straightforward replacement for Java reflection and annotations in the long term.
As for now, one has to use Java annotations which I think is still a nice solution.
Regarding frameworks and libraries for DI/ORM/WS/serialization - Scala still doesn't seem to be mature in this area, at least not as Java is. There are plenty of ongoing projects targeting these problems, some of them are already really nice, others are still in development. To name a few that come to my mind: Squeryl, Slick, Spray, Pickling.
Also, Scala has some advanced features that often make annotations unneccessary. Typeclasses (implemented with implicit parameters) are probably good example of that.
i need find all subclasses which mixing some trait (i won't do this in a runtime). I know tool written in scala (ClassUtil) but this tool is slow. Also I know one tool written in java (fasters than ClassUtil), but if I have choice I wouldn't rather using external libraries - so my question is: scala 2.10 have support resolving my problem?
I would prefer using constructor injection over JavaBean property injection if I could utilize the named and default arguments feature of Scala 2.8. Any IoC-containers exists that supports that or could be easily extended to do so? (The required information is there on runtime in the scala.reflect.ScalaSignature annotation of the class.)
I also have some basic(?) expectations from the IoC container:
Auto-wiring (by target class/trait or annotation, both one-to-one and one-to-many)
Explicit injection (explicit wiring) without much hassle (like Guice is weak there). Like user is injected that way in new ConnectionPool(user="test").
Life-cycle callback for cleanup on shutdown (in the proper order)
Spring can do these, obviosuly, but it doesn't support named parameters. I have considered using FactoryBean-s to bridge Scala and Spring, but that would mean too much hassle (boilerplate or code generation), as far as I see.
PART A
I have a work-in-progress reflection library that parses the Scala signature and is currently able to resolve named parameters: https://github.com/scalaj/scalaj-reflect
Unfortunately, I haven't yet tied it back into Java reflection to be able to invoke methods, nor have I added the logic to resolve default values (though this should be trivial). Both features are very high on my to-do list :)
This isn't an IoC container per-se, but it's a pre-requisite for another project of mine: https://github.com/scalaj/scalaj-spring. Work on scalaj-spring stopped when it became blindingly obvious that I wouldn't be able to make any worthwhile further progress until I had signature-based reflection in place.
PART B
All of that stuff is intended for big enterprisey people anyway. Those with no choice but to integrate their shiny new Scala code into some hulking legacy system... If that's not your use case, then you can just do Scala DI directly inside Scala.
There's DI support provided under the Lift banner: http://www.assembla.com/wiki/show/liftweb/Dependency_Injection
You should also hunt around for references to the cake pattern
Another dependency injection framework in Scala is subcut
I have considered using FactoryBean-s to bridge Scala and Spring, but that would mean too much hassle
I am not sure I understand the complexity. Its actually quite simple to implement Spring FactoryBeans in Scala. Check this little write-up http://olegzk.blogspot.com/2011/07/implementing-springs-factorybean-in.html
I've just released Sindi, an IoC container for the Scala programming language.
http://aloiscochard.github.com/sindi/
To all -- I'm probably at best a new guy here, trying to wrap my head around scala, and I find I need to do the following:
Assume I have a scala class on disk somehwere referenced in my classpath.
I have a scala application that wants to dynamically load this class and call its constructor
Once I have that class reference, I can use it to set up values in other classes and objects.
In Java, I'd use the Java class loader and create a new instance whereupon I'd call its constructor. What is the right way to do this in Scala?
Scala classes are Java classes, so just do what you'd do in Java. The Scala Java Interoperability FAQ doesn't talk about classloaders specifically, but it might be helpful as you figure things out.
I have written a blog entry quite a long time ago on this. Unfortunately I haven't found the time to update it for Scala 2.8 .
Essentially it boils down to
do it like you would in Java
use Scala features to improve the user interface
similar to the one in Ruby
Yes, as of Scala 2.9 with the -Xexperimental option, one can use the Dynamic trait
(scaladoc). Classes that extend Dynamic get the magical method applyDynamic(methodName, args) which behaves like Ruby's method_missing.
Among other things, the Dynamic trait can be useful for interfacing with dynamic languages on the JVM.
The following is no longer strictly true with the Dynamic trait found in [experimental] Scala 2.9. See the answer from Kipton Barros, for example.
However, Dynamic is still not quite like method_missing, but rather employs compiler magic to effectively rewrite method calls to "missing" methods, as determined statically, to a proxy (applyDynamic). It is the approach of statically-determining the "missing" methods that differentiates it from method_missing from a polymorphism viewpoint: one would need to try and dynamically forward (e.g. with reflection) methods to get true method_missing behavior. (Of course this can be avoided by avoiding sub-types :-)
No. Such a concept does not exist in Java or Scala.
Like Java, all the methods in Scala are 'bound' at compile time (this also determines what method is used for overloading, etc). If a program does compile, said method exists (or did according to the compiler), otherwise it does not. This is why you can get the NoSuchMethodError if you change a class definition without rebuilding all affected classes.
If you are just worried about trying to call a method on an object which conforms to a signature ("typed duck typing"), then perhaps you may be able to get away with structural typing. Structural typing in Scala is magical access over reflection -- thus it defers the 'binding' until runtime and a runtime error may be generated. Unlike method_missing this does not allow the target to handle the error, but it does allow the caller to (and the caller could theoretically call a defined methodMissing method on the target... but this is probably not the best way to approach Scala. Scala is not Ruby :-)
Not really. It doesn't make sense. Scala is a statically-typed language in which methods are bound at compile time; Ruby is a dynamically-typed language in which messages are passed to objects, and these messages are evaluated at runtime, which allows Ruby to handle messages that it doesn't directly respond to, à la method_missing.
You can mimic method_missing in a few ways in Scala, notably by using the Actors library, but it's not quite the same (or nearly as easy) as Ruby's method_missing.
No, this is not possible in Scala 2.8 and earlier.