Enforce compiler error when naming a parameter of a java method when called from scala - scala

I have a java class like the following:
public class Foo {
public void foo(boolean flag) {}
}
And a scala class like the following:
class Bar {
def bar(): Unit = {
val foo = new Foo()
foo.foo(flag = true)
}
}
This causes a compiler error to be displayed inside intellij (as it should, since there are no parameter names stored in java classes), but when building from the command line with maven, there is no compiler error. Is there a setting to cause this to be an error in the maven build?

Related

Overriden method can call on inherited private getter, but not inherited private setters

I think this could apply to both Java and Scala, but - a week in to learning Scala so trying that out. I have this:
class myBaseClass {
private var member: Int = 100
def doStuff(): Unit ={
checkMember()
alterMember(5)
}
private[this] def checkMember(): Unit = {
//throws exception if member < 0
}
private[this] def alterMember(i : Int): Unit = {
member -= i
}
}
And then I have a class which inherits the lot, overriding just one method as to call alterMember with a different value:
class mySubClass extends myBaseClass {
override def doStuff(): Unit ={
checkMember() // gives compiler error
alterMember(10) // gives compiler error AND IntelliJ says "alterMember inaccessible from this place"
}
}
checkMember() and alterMember are acting like private getters and setters. (I do only want doStuff to be able to change member , and are both inherited. WRONG - IGNORE THIS I don't understand why mySubClass is clearly able to access the private member as checkMember is just fine, but it seems it cannot alter it. Why would there be this variance? IGNORE UP TO HERE
Erasing the [this] makes no difference, but making alterMember public "fixes" it - but gives a level of access to member that I do not want.
The answer here, based on #MuratMustafin 's suggestion is to make the member and the two private methods protected.
What was also throwing, was that I needed to compile myBaseClass before attempting to compile mySubClass , otherwise it will say mySubClass cannot find those protected methods. Perhaps it's something with the Scala compiler that differs from the Java compiler in that it won't automatically know to compile them all, or compile them in order.

Scala interop with Java questionmark generics

EDIT I have made the example self-contained.
Suppose in java I have
src/main/java/FooFactory.java
interface FooFactory {
Foo<?> create();
<T> void enhance(Foo<T> foo, FooEnhancer<? super T> enhancer);
}
and src/main/java/Foo.java
interface Foo<T> {}
and src/main/java/FooEnhancer.java
interface FooEnhancer<T> {}
(and you can't change these interfaces because they belong to someone else.)
Then in scala you have
object DummyFooEnhancer extends FooEnhancer[Any]
trait FooHdlr {
def fooFactory: FooFactory
val foo = fooFactory.create
fooFactory.enhance(foo, DummyFooEnhancer)
}
This doesn't compile because FooEnhancer and Foo are invariant but foo is a Foo<?> whereas DummyFooEnhancer is a Foo[Any]. Changing Any to AnyRef doesn't work for the same reason.
Then I reasoned that, well, ? is a specific type that is certainly not known at compile time and that may not necessarily be AnyRef/Object, so what if I do this?
case class DummyFooEnhancer[T] extends FooEnhancer[T]
trait FooHdlr {
def fooFactory: FooFactory
val foo = fooFactory.create
fooFactory.enhance(foo, new DummyFooEnhancer)
}
But this causes scalac to stackoverflow! It's looping with
at scala.reflect.internal.Types$TypeVar.isGround(Types.scala:3082)
calling itself.
Interestingly if I replace ? super T with T it works fine, but in real life I can't do this because it's in code I don't control

Why can't I use this.getClass in auxiliary constructor in scala?

Why can't I use this.getClass in auxiliary constructor in scala? Are there any alternatives?
More specifically, I am trying to call LoggerFactory.getLogger of slf4j in the auxiliary constructor. I have an hack now where I am forced to pass a logger object to the constructor.
A simple contrived example (does not compile) which shows what I am trying to do:
class A (numbers : Double) {
val logger = LoggerFactory.getLogger(this.getClass)
def this(numbersAsStr: String) = this (try { s.toDouble) } catch { case _ => LoggerFactory.getLogger(this.getClass).error("Failed to convert"); 0 }
}
This is actually a limitation of the JVM rather than specifically a Scala problem. Here's a similar example in Java:
public class ThisTest {
public final String name;
public ThisTest(String n) {
name = n;
}
public ThisTest() {
// trying to use `this` in a call to the primary constructor
this(this.getClass().getName());
}
}
When you try to compile it you get an error:
$ javac ThisTest.java
ThisTest.java:10: error: cannot reference this before supertype constructor has been called
this(this.getClass().getName());
^
1 error
The problem is that you're trying to reference this before this any of the super-constructors for this have been called. You will have the restriction that you can't use a this reference in a super() or this() call no matter what JVM language you use, because that's the way classes work on the JVM.
However, you can totally avoid this problem by restructuring your code to put the reference to this after the this() call:
class A (numbers: Double) {
val logger = LoggerFactory.getLogger(this.getClass)
def this(numbersAsStr: String) = {
this ( try { numbersAsStr.toDouble } catch { case _ => 0 } )
LoggerFactory.getLogger(this.getClass).error("Failed to convert");
}
}
You might actually want access to the thrown exception for your log info. In that case, I'd just use LoggerFactory.getLogger(classOf[A]). That won't give you the actual class name if you're using inheritance (which I was assuming was the case here), but if you include the stack trace in the log then you should be able to figure it out.
Not sure I understand the question. Here is a guess:
class Foo(val c: Class[_]) {
def this() = this(classOf[Foo])
}
new Foo().c // -> class Foo

using inherited method from Java class in Scala [duplicate]

This question already has an answer here:
Calling a protected static Java method from Scala
(1 answer)
Closed 8 years ago.
I'm trying to compile a Scala class file that extends a Java class. Here is the class definition, it's as basic as it gets. On load, in the host application, the object should write "Hello from Scala" to the host's output window, using the superclass's method 'post'.
import com.cycling74.max.MaxObject;
public class FirstClass extends MaxObject{
public FirstClass{
post("Hello From Java");
}
}
This compiles and runs fine in the application.
Here is my translation to Scala (to be honest I'm not 100% sure I completely understand constructors in Scala):
import com.cycling74.max._
class FirstClass() extends MaxObject {
super.post("Hello from Scala")
}
But, when I try to compile with scalac, I receive the following error:
dm$ scalac -cp max.jar FirstClass.scala
FirstClass.scala:3: error: value post is not a member of com.cycling74.max.MaxObject with ScalaObject
super.post("Hello from Scala")
^
one error found
I'm not sure why the compiler is telling me that 'post' is not a member function, I'm certain that I've botched the Scala syntax, but cannot determine what is wrong.
Thanks!
EDIT
here's the output from the Max window, in addition to changing the code as prescribed below, i just added the Scala libs to Max's dynamic loadpath. This is exciting
MXJ System CLASSPATH:
/Applications/Max 6.1/Cycling '74/java/lib/jitter.jar
/Applications/Max 6.1/Cycling '74/java/lib/jode-1.1.2-pre-embedded.jar
/Applications/Max 6.1/Cycling '74/java/lib/max.jar
MXJClassloader CLASSPATH:
/Applications/Max 6.1/Cycling '74/java/classes/
/Users/dm/maxmsp/classes
/Users/dm/maxmsp/jars/jline.jar
/Users/dm/maxmsp/jars/scala-compiler.jar
/Users/dm/maxmsp/jars/scala-dbc.jar
/Users/dm/maxmsp/jars/scala-library.jar
/Users/dm/maxmsp/jars/scala-partest.jar
/Users/dm/maxmsp/jars/scala-swing.jar
/Users/dm/maxmsp/jars/scalacheck.jar
/Users/dm/maxmsp/jars/scalap.jar
Jitter initialized
Jitter Java support installed
Hello from Scala
Assuming the definitioin of post method in MaxObject as..
public class MaxObject {
public static void post(java.lang.String message){
System.out.println("printing from MaxObject.post :: " + message);
}
}
you can directly call the post method in scala as -
class FirstClass extends MaxObject {
MaxObject.post("Hello from Scala")
}
Infact, if you are not compelled to extend the MaxObject.. you can also use it as..
class FirstClass{
MaxObject.post("Hello from Scala")
}
Consuming it as :
val fc = new FirstClass //> printing from MaxObject.post :: Hello from Scala

How to implement intermediate types for implicit methods?

Assume I want to offer method foo on existing type A outside of my control. As far as I know, the canonical way to do this in Scala is implementing an implicit conversion from A to some type that implements foo. Now I basically see two options.
Define a separate, maybe even hidden class for the purpose:
protected class Fooable(a : A) {
def foo(...) = { ... }
}
implicit def a2fooable(a : A) = new Fooable(a)
Define an anonymous class inline:
implicit def a2fooable(a : A) = new { def foo(...) = { ... } }
Variant 2) is certainly less boilerplate, especially when lots of type parameters happen. On the other hand, I think it should create more overhead since (conceptually) one class per conversion is created, as opposed to one class globally in 1).
Is there a general guideline? Is there no difference, because compiler/VM get rid of the overhead of 2)?
Using a separate class is better for performance, as the alternative uses reflection.
Consider that
new { def foo(...) = { ... } }
is really
new AnyRef { def foo(...) = { ... } }
Now, AnyRef doesn't have a method foo. In Scala, this type is actually AnyRef { def foo(...): ... }, which, if you remove AnyRef, you should recognize as a structural type.
At compile time, this time can be passed back and forth, and everywhere it will be known that the method foo is callable. However, there's no structural type in the JVM, and to add an interface would require a proxy object, which would cause some problems such as breaking referential equality (ie, an object would not be equal with a structural type version of itself).
The way found around that was to use cached reflection calls for structural types.
So, if you want to use the Pimp My Library pattern for any performance-sensitive application, declare a class.
I believe 1 and 2 get compiled to the same bytecode (except for the class name that gets generated in case 2).
If Fooable exists only for you to be able to convert implicitly A to Fooable (and you're never going to directly create and use a Fooable), then I would go with option 2.
However, if you control A (meaning A is not a java library class that you can't subclass) I would consider using a trait instead of implicit conversions to add behaviour to A.
UPDATE:
I have to reconsider my answer. I would use variant 1 of your code, because variant 2 turns out to be using reflection (scala 2.8.1 on Linux).
I compiled these two versions of the same code, decompiled them to java with jd-gui and here are the results:
source code with named class
class NamedClass { def Foo : String = "foo" }
object test {
implicit def StrToFooable(a: String) = new NamedClass
def main(args: Array[String]) { println("bar".Foo) }
}
source code with anonymous class
object test {
implicit def StrToFooable(a: String) = new { def Foo : String = "foo" }
def main(args: Array[String]) { println("bar".Foo) }
}
compiled and decompiled to java with java-gui. The "named" version generates a NamedClass.class that gets decompiled to this java:
public class NamedClass
implements ScalaObject
{
public String Foo()
{
return "foo";
}
}
the anonymous generates a test$$anon$1 class that gets decompiled to the following java
public final class test$$anon$1
{
public String Foo()
{
return "foo";
}
}
so almost identical, except for the anonymous being "final" (they apparently want to make extra sure you won't get out of your way to try and subclass an anonymous class...)
however at the call site I get this java for the "named" version
public void main(String[] args)
{
Predef..MODULE$.println(StrToFooable("bar").Foo());
}
and this for the anonymous
public void main(String[] args) {
Object qual1 = StrToFooable("bar"); Object exceptionResult1 = null;
try {
exceptionResult1 = reflMethod$Method1(qual1.getClass()).invoke(qual1, new Object[0]);
Predef..MODULE$.println((String)exceptionResult1);
return;
} catch (InvocationTargetException localInvocationTargetException) {
throw localInvocationTargetException.getCause();
}
}
I googled a little and found that others have reported the same thing but I haven't found any more insight as to why this is the case.