Scala 'this' and 'self' not working in simple App - scala

New to scala (using version 2.12.1) obviously from the title. I'm writing my first app in IntelliJ. I've read about the Scala equivalent in Java to this. I've tried this, self, classOf[] and IntelliJ is complaining and the code is not compiling even if I ignore IntelliJ. Here's what I have:
import ch.qos.logback.classic.Logger
object Main extends App {
val logger = Logger[Main]
}
Logger package is importing correctly in SBT. However it cannot resolve the symbol Main. I tried sticking it in a package to make it less ubiquitous and then doing something like Logger[me.justin.Main] but that also doesn't work.
I also thought maybe extending App was causing some problems but I think that's fixed in the scala version I'm using? Maybe it's not even applicable?
I'm all Googled out. Help please!

You're getting tripped up by how Scala's objects work. Let's say we had a class Foo and a companion object for same:
class Foo
object Foo
If we wanted a logger for the class, we'd do the obvious thing:
val logger = Logger[Foo] // `Foo` here is the type of the class.
But what if we wanted to refer to the type of the object? We have to disambiguate from the type of the class. The answer is to use the special type member on the object:
val logger = Logger[Foo.type] // `Foo.type` here is the type of the object.
So in your case:
val logger = Logger[Main.type]

Related

AbstractMethodError on obscure method name when upgrading from Scala 2.12 to 2.13

I am getting the following error:
java.lang.AbstractMethodError: Receiver class com.pack.ReceiverDAO does not define or inherit an implementation of the resolved method 'abstract void com$pack$proj$dao$JSDAO$_setter_$jsDAOApi_$eq(slick.jdbc.JdbcProfile$API)' of interface com.pack.proj.dao.JSDAO.
when I try to promote my code to Scala 2.13 from 2.12 (the dependency that's giving me issues, com.pack.proj, is compiled by Scala 2.12). I thought an easy way to get rid of this error is to implement a stub for it. However, at the moment, I don't have the source code for com.pack.proj.dao.JSDAO (which is what I extends in my "receiver", com.pack.ReceiverDAO) so I am not sure how to override com$pack$proj$dao$JSDAO$_setter_$jsDAOApi_$eq(slick.jdbc.JdbcProfile$API) w/o compilation errors like "overrides nothing". How can I override this inherited abstract method or otherwise get rid of this runtime error?
For the sake of completeness, I'd like to add that I needed to exclude some of the Scala_2.12-compiled Slick libraries when I declared the troublesome library, com.pack.proj as a dependency:
("com.pack.proj" % "js-dao_2.12" % ProjVer)
.exclude("com.typesafe.slick", "slick-hikaricp_2.12")
.exclude("com.github.tminglei", "slick-pg_2.12")
.exclude("com.typesafe.slick", "slick_2.12")
You simply cannot use a library that is compiled with 2.12 in a 2.13 project. It will inevitably break.
There is no real remedy other than use a version of that library that is compiled with 2.13, or not use it at all.
Make sure you're initialising your database in the same format as recommended. I.e. use a trait to define which extensions you wish to use and then extend this trait on a companion object.
import com.github.tminglei.slickpg._
trait MyPostgresProfile extends ExPostgresProfile
with PgArraySupport {
override val api = MyAPI
object MyAPI extends API with ArrayImplicits {
}
object MyPostgresProfile extends MyPostgresProfile
You can see a more complete example in the slick-pg README

Is it possible to automatically load an implicit def if included as a dependency (no importing)

I'm working on a commons library that includes a config library (https://github.com/kxbmap/configs).
This config library uses "kebab-case" when parsing configuration files by default and it can be overridden by an implicit def in scope.
However, I don't want to force that on the users of my commons library when they get access to the config library transitively.
So without me forcing users to import this implicit, like:
import CommonsConfig._
can I somehow override the naming strategy via an implicit that gets into scope by only including my commons library on the classpath. I'm guessing no but I just have to ask :)
So if not, is someone aware of another approach?
kxbmap/configs isn't that well documented to explain this.
Thanks!
Implicits work in compile time, so they cannot get magically present if something is included and then disappear if it isn't.
The closest thing would be something like:
main library
package my.library
// classes, traits, objects but no package object
extension
package my
package object library {
// implicits
}
user's code
import my.library._
however that would only work if there were no package object in main library, only one extension library could pull off this trick at once (Scala doesn't like more than one package object) and user would have to import everything available with a package, always.
In theory you could create a wrapper around all you deps, with your own configs:
final case class MyLibConfig(configsCfg: DerivationConfig)
object MyLibConfig {
implicit val default: MyLibConfig = ...
}
and then derive using this wrapper
def parseThings(args...)(implicit myLibConfig: MyLibConfig) = {
implicit val config: DerivationConfig = myLibConfig.config
// derivation
}
but in practice it would not work (parseThings would have to already know the target type or would need to have the already derived implicits passed). Unless you are up to writing your own derivation methods... avoid it.
Some way of making user just import all relevant stuff is the most maintainable strategy. E.g. you could pull off the same thing authors did and add type aliases for all types that you use, do the same for companion objects and finally put some implicits there:
package my
package object library {
type MyType = some.library.Type
val MyType = some.library.Type
implicit val derivationConfig: DerivationConfig = ...
}

Scala Reflection: instantiating a singleton object

I'm using the following code to instantiate a scala object. This works, but there seems to be one problem: the println is printed out twice, each time with another hashcode.
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}
object Test2 { println("init"+hashCode())}
val mirror = ru.runtimeMirror(getClass.getClassLoader)
val m = ru.typeOf[Test2.type].members.filter(_.isConstructor).head.asMethod
val m2 = mirror.reflectClass(typeOf[Test2.type].typeSymbol.asClass)
val cm = m2.reflectConstructor(m)
val e = cm.apply()
Results in:
init472467991
init2051378291
e: Any = Test2$#7a458c73
the hashCode of e is equal to the latter one (2051378291). I'm wondering why this is because as far as I know there should be only one?
EDIT: using scala version 2.12.4
JVM has no singletons*
You're invoking a private constructor of a class. Scala reflection allows it. And when you invoke a constructor, you get a new instance back.
It's actually pretty hard to make a singleton in plain Java because there are ways to construct an instance except using new Something. For instance, de-serialization might not call any constructors besides one of Object. And there's sun.misc.Unsafe#allocateInstance that can conjure new instances of any class sans java.lang.Class without calling any constructor code.
Scala object does some job behind the hood to ensure you don't accidentally create a second instance during any normal usage (e.g. it hides the constructor and handles de-serialization), but it cannot protect you from deliberately creating one. When you start using reflection, you do exactly that.
Even Java enums can be instantiated at runtime using reflection. You cannot call Class#newInstance on an enum directly (the implementation forbids it), but knowing a bit of internal details can get you there**
import java.nio.file.StandardOpenOption // first std enum I could remember for a quick dirty sample
val ctor = classOf[StandardOpenOption].getDeclaredConstructors.head
val aac = ctor.getClass.getDeclaredMethod("acquireConstructorAccessor")
aac.setAccessible(true) // unlimited power!
val ctorAccess = aac.invoke(ctor)
val newInstanceCall = ctorAccess.getClass.getDeclaredMethod("newInstance", classOf[Array[AnyRef]])
newInstanceCall.setAccessible(true)
// note that it does not throw ClassCastException, so it's a fine instance
val uhOh = newInstanceCall.invoke(ctorAccess, Array("UhOh", 42)).asInstanceOf[StandardOpenOption]
assert(uhOh.name == "UhOh")
assert(uhOh.ordinal == 42)
(interactive version # Scastie)
To get the "default" instance, you can access a public static field named MODULE$ using reflection. You can also run whole scala compiler at runtime
It's likely to be the best bet for you to not rely on reflection in whatever you're trying to achieve.
BTW, it is possible to get ScalaReflectionException trying to run your code in IntelliJ worksheet or Scastie in worksheet mode, because these things wrap your code in another object with main method
* Only tested on few versions of HotSpot JVM
** Please don't do this in any serious code! I only use this to prove a point. This is also pretty useless because it does not change values or valueOf. And yes, I only checked it on HotSpot that comes with JDK8.

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]

Use `#annotation.varargs` on constructors

I want to declare a class like this:
class StringSetCreate(val s: String*) {
// ...
}
and call that in Java. The problem is that the constructor is of type
public StringSetCreate(scala.collection.Seq)
So in java, you need to fiddle around with the scala sequences which is ugly.
I know that there is the #annotation.varargs annotation which, if used on a method, generates a second method which takes the java varargs.
This annotation does not work on constructors, at least I don't know where to put it. I found a Scala Issue SI-8383 which reports this problem. As far as I understand there is no solution currently. Is this right? Are there any workarounds? Can I somehow define that second constructor by hand?
The bug is already filed as https://issues.scala-lang.org/browse/SI-8383 .
For a workaround I'd recommend using a factory method (perhaps on the companion object), where #varargs should work:
object StringSetCreate {
#varargs def build(s: String*) = new StringSetCreate(s: _*)
}
Then in Java you call StringSetCreate.build("a", "b") rather than using new.