Re: [scala-ide-user] Can't use "case classes" from Java in Eclipse

1,518 views
Skip to first unread message

Mirco Dotta

unread,
May 20, 2013, 4:55:22 AM5/20/13
to scala-i...@googlegroups.com
Hi Rubén,

If you want to instantiate a case class from Java code, you should simply call the class' constructor. For instance, here is how you can do it from a Java class

public class J {

  public GetIP createIP() {
    return new GetIP();
  }
}

In your example, the GetIP case class could actually be declared as a case object, because no arguments are passed to its constructor. If you do so, then you can access any member of GetIP by calling GetIP.<type-the-member-name-here>. Basically, you should never need to use the $ class, or the MODULE$ member, unless you need to get a handle on the actual instance behind the singleton (in this case, and this case only, you should call GetIP$.MODULE$, which returns an instance of type GetIP$).

If you see no completion proposals when hitting CTRL/CMD+Space, then the likely reason is that "Java Proposals" are OFF in the plug-in preferences. Please check Eclipse Preferences > Java > Editor > Content Assist > Advanced, and make sure to enable "Java Proposals". 

Cheers,
  Mirco

On May 20, 2013, at 2:59 AM, Rubén Pérez wrote:

Hi,

I have something like this in Scala:

 
import com.messages 
sealed trait BasicMessage
case class GetIP() extends BasicMessage 



And I know that if I want to use GetIP from Java, I have to do something like:

import com.messages.GetIP$;
GetIP$.MODULE$ 

However, Eclipse stay saying  error on the import statement in the Java code. And so when I'm accesing to GetIP$ later on.

I think it is a bug from Eclipse, and not from Scala-IDE, but is there anything that I can do? I'm using Eclipse 4.2

Thanks!
 

--
You received this message because you are subscribed to the Google Groups "Scala IDE User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-ide-use...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Rubén Pérez

unread,
May 20, 2013, 5:47:19 PM5/20/13
to scala-i...@googlegroups.com
Hi Mirco,

Thank you very much for your response.


What I'm trying to do is basically using akka for a demo.... I have an actor defined in Scala, and I'm passing its context to a java code, and trying to send a message to its parent from the Java code,

So, what you said works fine so far, just doing something like this in Scala:

sealed trait BasicMessage { def instance = this }
case object GetIP extends BasicMessage 
 

then I can send the message in Java as:

viewActorCtx.parent().tell(GetIP.instance(), viewActorCtx.self());


On that way I avoid the usage of the $, so far, so good.... But what if I have to send a message with parameters, so a case class? If I do something like:

viewActorCtx.parent().tell(new GetIP(), viewActorCtx.self());

it is not recognized by the match of the receiving actor (it goes into the "case _=>" instead)

Why is that? On the other hand, if I use anyway as GetIP$.MODULE$ then it works fine (besides the problem with Eclipse that I commented before).

Then, it is still not very clear to me if the fact that I can't import the class with the $ at the end, is a bug or not.


Thanks again!

Roland Kuhn

unread,
May 21, 2013, 2:26:07 AM5/21/13
to scala-i...@googlegroups.com
Hi Rubén,

I think your questions are possibly better suited to the akka-user mailing list, but see more comments inline.

20 maj 2013 kl. 23:47 skrev Rubén Pérez:

Hi Mirco,

Thank you very much for your response.


What I'm trying to do is basically using akka for a demo.... I have an actor defined in Scala, and I'm passing its context to a java code

You should never ever pass context() around, it is not thread-safe and must not leave the actor. If you want to send to the parent, then pass context.parent around, which is an ActorRef and completely fine.

, and trying to send a message to its parent from the Java code,

So, what you said works fine so far, just doing something like this in Scala:

sealed trait BasicMessage { def instance = this }
case object GetIP extends BasicMessage 
 

then I can send the message in Java as:

viewActorCtx.parent().tell(GetIP.instance(), viewActorCtx.self());


On that way I avoid the usage of the $, so far, so good.... But what if I have to send a message with parameters, so a case class?

On the Scala side:

case class X(x: Int)
def receive = {
  case X(x) => println(x)
}

On the Java side:

target.tell(new X(42), getSelf());


If I do something like:

viewActorCtx.parent().tell(new GetIP(), viewActorCtx.self());

If GetIP is your case object from above then this—while unfortunately legal—does not do anything useful. Do not call “new” in connection with “object”s. Your “instance” method is how we also do it in Akka, BTW.


it is not recognized by the match of the receiving actor (it goes into the "case _=>" instead)

Why is that? On the other hand, if I use anyway as GetIP$.MODULE$ then it works fine (besides the problem with Eclipse that I commented before).

You should not ever need to use methods which contain $, especially not when using Akka.


Regards,

Roland



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Empowering professional developers to build amazing apps.
twitter: @rolandkuhn

See you at Scala Days 2013 in NYC!
June 10th - June 12th
www.scaladays.org

Stephan Ewen

unread,
Jan 5, 2015, 4:36:58 PM1/5/15
to scala-i...@googlegroups.com
Hi!

I hope I can post a follow-up question on this (slightly older) thread.

I have a very similar problem, and I have not found a good way around it that works in the newest version of the Scala IDE.

We have messages that are case objects, since they have no parameters. When trying to send the messages from Java, I use the following construct

<pre>
target.tell(myMessages.RequestTasks$.MODULE$), getRef());
</pre>

The Java compiler cannot resolve that reference to the case object, it claims that "RequestTasks$" does not exist. In the class files, this class does exist, but it seems that the java presentation compiler does not really look into the class files.

Is there a good workaround to allow accessing the case object instance?

Greetings,
Stephan

Simon Schäfer

unread,
Jan 6, 2015, 6:17:42 AM1/6/15
to scala-i...@googlegroups.com

On 01/05/2015 10:36 PM, Stephan Ewen wrote:
> Hi!
>
> I hope I can post a follow-up question on this (slightly older) thread.
>
> I have a very similar problem, and I have not found a good way around
> it that works in the newest version of the Scala IDE.
>
> We have messages that are case objects, since they have no parameters.
> When trying to send the messages from Java, I use the following construct
>
> <pre>
> target.tell(myMessages.RequestTasks$.MODULE$), getRef());
> </pre>
What is myMessages? Are you sure that RequestTasks is part of it (just
because it is part of it in Scala doesn't mean that it is part of it in
Java)?

Stephan Ewen

unread,
Jan 6, 2015, 8:49:55 AM1/6/15
to scala-i...@googlegroups.com
Hi!

Sorry, here "MyMessages" is just an object that holds all the message case classes and case objects.

object MyMessages {

    case class SomeMessage(x: Int)

    case class AnotherMessage(y: Double, z: String)

    case object Ping

    case object RequestTasks
}

Greetinigs,
Stephan

Stephan Ewen

unread,
Jan 6, 2015, 8:52:02 AM1/6/15
to scala-i...@googlegroups.com
The code is actually correct, it compiles both with Maven and when I do a "clean all" -> "build".

It only causes problems when the Java code is incrementally recompiled.

Thanks for getting back!
Stephan

Simon Schäfer

unread,
Jan 6, 2015, 3:22:11 PM1/6/15
to scala-i...@googlegroups.com

On 01/06/2015 02:52 PM, Stephan Ewen wrote:
The code is actually correct, it compiles both with Maven and when I do a "clean all" -> "build".

It only causes problems when the Java code is incrementally recompiled.
We can't fix bugs in JDT (better: we don't want to). I noticed that some errors are shown in the editor, but don't break the build, this is something one can at least live with. Maybe someone else nows workarounds, I don't.
--
You received this message because you are subscribed to the Google Groups "Scala IDE User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-ide-use...@googlegroups.com.

Stephan Ewen

unread,
Jan 7, 2015, 9:23:02 AM1/7/15
to scala-i...@googlegroups.com
Hi!

Just out of curiosity: It seems as if the incremental JDT compiler does not refer to scala classes through the class files generated by the Scala compiler, but sort of directly tries to go against the AST of the code (or another intermediate representation), so it gets confused with the name of the case object and the class-name that is suffixed with the $.

If that is true, it may be possibly to create a rather simple patch for JDT team or so. Anyone has more insights into the workings of JDT?

Greetings,
Stephan

iulian dragos

unread,
Jan 11, 2015, 8:45:59 AM1/11/15
to scala-i...@googlegroups.com
I vaguely remember that the JDT compiler does not consider names with '$' in them.

IMO the cleanest way would be for you to define an explicit method that returns the current instance (in Scala code), for Java clients. A bit verbose, but no longer at the mercy of JDT compiler issues.

In the long run, it would be good for the Scala compiler to auto-generate an `instance()` method for objects to ease Java interop.

iulian






--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais
Reply all
Reply to author
Forward
0 new messages