This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Re: Scala/Java interop

7 replies
Justin Johansson
Joined: 2008-12-14,
User offline. Last seen 3 years 45 weeks ago.

Hello Liam,

I have created a test package called interop and therein 4 Scala classes
and 1 Java class in Eclipse (using the Scala plugin) called ScalaFoo1,
ScalaFoo2, ScalaFoo3, ScalaFoo4 and JavaFoo respectively.

JavaFoo looks like this, and, yes, in Eclipse there are lots of compilation
errors as you indicated in your post.

public class JavaFoo {
public static void Main( String args[]) {
Object foo1 = new interop.ScalaFoo1( 11);
Object foo2 = new interop.ScalaFoo2( 12);
Object foo3 = new interop.ScalaFoo3( 13);
Object foo4 = new interop.ScalaFoo4( 14);
}
}

The 4 Scala classes are variations on your example, class B(var a:Int).
JavaFoo is the Java class which attempts to access the constructors of the
ScalaFoox classes.
Using the javap utility which comes with the JDK, you can get a feel for
what is going on interop-wise. This tip is courtesy of Chapter 29 of the
book. For help on running javap, try typing javap -help in a console box
and you will get:

Usage: javap ...

where options include:
-c Disassemble the code
-classpath Specify where to find user class files
-extdirs Override location of installed extensions
-help Print this usage message
-J Pass directly to the runtime system
-l Print line number and local variable tables
-public Show only public classes and members
-protected Show protected/public classes and members
-package Show package/protected/public classes
and members (default)
-private Show all classes and members
-s Print internal type signatures
-bootclasspath Override location of class files loaded
by the bootstrap class loader
-verbose Print stack size, number of locals and args
for methods
If verifying, print reasons for failure

Ok, now run javap on the Scala classes,
e.g. javap interop.ScalaFoo1 >scalafoo1.txtpackage interop
and see what turns up in scaafoo1.txt.

I did that for each of the (Scala) classes, The results are shown below
and are food for further analysis & interpretation.

Note in particular that ScalaFoo4 is a case class.

/*
Compiled from "ScalaFoo1.scala"
public class interop.ScalaFoo1 extends java.lang.Object implements
scala.ScalaObject{
public interop.ScalaFoo1(int);
public int $tag() throws java.rmi.RemoteException;
}
*/
class ScalaFoo1( a: Int) {
}

/*
Compiled from "ScalaFoo2.scala"
public class interop.ScalaFoo2 extends java.lang.Object implements
scala.ScalaObject{
public interop.ScalaFoo2(int);
public int a();
public int $tag() throws java.rmi.RemoteException;
}
*/
class ScalaFoo2( val a: Int) {
}

/*
Compiled from "ScalaFoo3.scala"
public class interop.ScalaFoo3 extends java.lang.Object implements
scala.ScalaObject{
public interop.ScalaFoo3(int);
public void a_$eq(int);
public int a();
public int $tag() throws java.rmi.RemoteException;
}
*/
class ScalaFoo3( var a: Int) {
}

/*
Compiled from "ScalaFoo4.scala"
public class interop.ScalaFoo4 extends java.lang.Object implements
scala.ScalaObject,scala.Product,java.io.Serializable{
public interop.ScalaFoo4(int);
public java.lang.Object productElement(int);
public int productArity();
public java.lang.String productPrefix();
public boolean equals(java.lang.Object);
public java.lang.String toString();
public int hashCode();
public int $tag();
public int a();
}
*/
case class ScalaFoo4( a: Int) {
}

So using javap you can begin to answer your own question.

Hope this helps to you get started on solving your interop problem.

Regards

Justin Johansson

At 03:54 PM 21/12/2008 +1300, you wrote:
>Hi all,
>
>I'm trialling Scala at the moment for a future personal project, but
>also with a view towards a possible use at work - however, if this is
>going to happen, Java code would have to be able to make use of any
>work done in Scala, and so I'd like to demonstrate Java code
>seamlessly using Scala.
>
>I'm aware that chapter 29 of the Programming in Scala book covers
>this, but at this early stage I'm not able to purchase the book, so I
>was wondering if anyone had some basic hints on writing Scala that
>Java can use.
>
>So far I've noted two things, the first is probably an IDE problem -
>when calling a Scala class from Java, my IDE (IDEA 8) does not
>recognise the Scala class' constructor - that is, for class Foo (a:
>Int), the IDE only recognises a constructor with nil arguments - but
>the code compiles correctly, has anyone had this problem in other
>IDEs?
>
>The second thing I've noted is that for a class
>
>class B(var a: Int)
>
>B.a is a public field when being called within Scala, but attempting
>to compile Java that accesses this field causes an error, with the
>message that field a of class B is non-public. I'm not sure why it
>happens, but I'm guessing that using the @BeanProperty annotation to
>create getters/setters for the Java code to use would fix it, as all
>my public methods are accessible.
>
>Are there any other gotchas I should be aware of?
>
>Regards,
>
>Liam Clarke
>
>

Liam Clarke-Hut...
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala/Java interop

Thanks for that, I shall avail myself of javap. :) From the looks of
the generated mutators, it'd probably be better to create them
manually to avoid method names like a_$eq, but I'll have a play.

Regards,

Liam Clarke

On 12/21/08, Justin Johansson wrote:
> Hello Liam,
>
> I have created a test package called interop and therein 4 Scala classes
> and 1 Java class in Eclipse (using the Scala plugin) called ScalaFoo1,
> ScalaFoo2, ScalaFoo3, ScalaFoo4 and JavaFoo respectively.
>
> JavaFoo looks like this, and, yes, in Eclipse there are lots of compilation
> errors as you indicated in your post.
>
> public class JavaFoo {
> public static void Main( String args[]) {
> Object foo1 = new interop.ScalaFoo1( 11);
> Object foo2 = new interop.ScalaFoo2( 12);
> Object foo3 = new interop.ScalaFoo3( 13);
> Object foo4 = new interop.ScalaFoo4( 14);
> }
> }
>
>
> The 4 Scala classes are variations on your example, class B(var a:Int).
> JavaFoo is the Java class which attempts to access the constructors of the
> ScalaFoox classes.
> Using the javap utility which comes with the JDK, you can get a feel for
> what is going on interop-wise. This tip is courtesy of Chapter 29 of the
> book. For help on running javap, try typing javap -help in a console box
> and you will get:
>
> Usage: javap ...
>
> where options include:
> -c Disassemble the code
> -classpath Specify where to find user class files
> -extdirs Override location of installed extensions
> -help Print this usage message
> -J Pass directly to the runtime system
> -l Print line number and local variable tables
> -public Show only public classes and members
> -protected Show protected/public classes and members
> -package Show package/protected/public classes
> and members (default)
> -private Show all classes and members
> -s Print internal type signatures
> -bootclasspath Override location of class files loaded
> by the bootstrap class loader
> -verbose Print stack size, number of locals and args
> for methods
> If verifying, print reasons for failure
>
> Ok, now run javap on the Scala classes,
> e.g. javap interop.ScalaFoo1 >scalafoo1.txtpackage interop
> and see what turns up in scaafoo1.txt.
>
> I did that for each of the (Scala) classes, The results are shown below
> and are food for further analysis & interpretation.
>
> Note in particular that ScalaFoo4 is a case class.
>
>
> /*
> Compiled from "ScalaFoo1.scala"
> public class interop.ScalaFoo1 extends java.lang.Object implements
> scala.ScalaObject{
> public interop.ScalaFoo1(int);
> public int $tag() throws java.rmi.RemoteException;
> }
> */
> class ScalaFoo1( a: Int) {
> }
>
>
> /*
> Compiled from "ScalaFoo2.scala"
> public class interop.ScalaFoo2 extends java.lang.Object implements
> scala.ScalaObject{
> public interop.ScalaFoo2(int);
> public int a();
> public int $tag() throws java.rmi.RemoteException;
> }
> */
> class ScalaFoo2( val a: Int) {
> }
>
>
> /*
> Compiled from "ScalaFoo3.scala"
> public class interop.ScalaFoo3 extends java.lang.Object implements
> scala.ScalaObject{
> public interop.ScalaFoo3(int);
> public void a_$eq(int);
> public int a();
> public int $tag() throws java.rmi.RemoteException;
> }
> */
> class ScalaFoo3( var a: Int) {
> }
>
>
> /*
> Compiled from "ScalaFoo4.scala"
> public class interop.ScalaFoo4 extends java.lang.Object implements
> scala.ScalaObject,scala.Product,java.io.Serializable{
> public interop.ScalaFoo4(int);
> public java.lang.Object productElement(int);
> public int productArity();
> public java.lang.String productPrefix();
> public boolean equals(java.lang.Object);
> public java.lang.String toString();
> public int hashCode();
> public int $tag();
> public int a();
> }
> */
> case class ScalaFoo4( a: Int) {
> }
>
>
> So using javap you can begin to answer your own question.
>
> Hope this helps to you get started on solving your interop problem.
>
> Regards
>
> Justin Johansson
>
>
>
>
> At 03:54 PM 21/12/2008 +1300, you wrote:
>>Hi all,
>>
>>I'm trialling Scala at the moment for a future personal project, but
>>also with a view towards a possible use at work - however, if this is
>>going to happen, Java code would have to be able to make use of any
>>work done in Scala, and so I'd like to demonstrate Java code
>>seamlessly using Scala.
>>
>>I'm aware that chapter 29 of the Programming in Scala book covers
>>this, but at this early stage I'm not able to purchase the book, so I
>>was wondering if anyone had some basic hints on writing Scala that
>>Java can use.
>>
>>So far I've noted two things, the first is probably an IDE problem -
>>when calling a Scala class from Java, my IDE (IDEA 8) does not
>>recognise the Scala class' constructor - that is, for class Foo (a:
>>Int), the IDE only recognises a constructor with nil arguments - but
>>the code compiles correctly, has anyone had this problem in other
>>IDEs?
>>
>>The second thing I've noted is that for a class
>>
>>class B(var a: Int)
>>
>>B.a is a public field when being called within Scala, but attempting
>>to compile Java that accesses this field causes an error, with the
>>message that field a of class B is non-public. I'm not sure why it
>>happens, but I'm guessing that using the @BeanProperty annotation to
>>create getters/setters for the Java code to use would fix it, as all
>>my public methods are accessible.
>>
>>Are there any other gotchas I should be aware of?
>>
>>Regards,
>>
>>Liam Clarke
>>
>>
>

Victor NOEL
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala/Java interop

On Sun, Dec 21, 2008 at 02:52:30PM +1000, Justin Johansson wrote:
> /*
> Compiled from "ScalaFoo1.scala"
> public class interop.ScalaFoo1 extends java.lang.Object implements
> scala.ScalaObject{
> public interop.ScalaFoo1(int);
> public int $tag() throws java.rmi.RemoteException;
> }
> */
> class ScalaFoo1( a: Int) {
> }

What are these java.rmi.RemoteException doing here ?
Is it only looking strange to me ?

Justin Johansson
Joined: 2008-12-14,
User offline. Last seen 3 years 45 weeks ago.
Re: Scala/Java interop

Hey, please don't shoot the messenger (not that I thought you were).

That's the generated output from javap from my sample Scala class input.

I don't know either; though it doesn't look strange to me, just mysterious.
:-)

Victor NOEL
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala/Java interop

On Sun, Dec 21, 2008 at 11:34:02PM +1000, Justin Johansson wrote:
> Hey, please don't shoot the messenger (not that I thought you were).

Sorry, that was not wanted :)

>
> That's the generated output from javap from my sample Scala class input.
>
> I don't know either; though it doesn't look strange to me, just mysterious.
> :-)

I guess there should be a good explanation, we just have to wait
for someone who know it.

Victor

>

Justin Johansson
Joined: 2008-12-14,
User offline. Last seen 3 years 45 weeks ago.
Re: Scala/Java interop

Victor,

>Sorry, that was not wanted :)

Sorry I don't have a better answer for you yet.

The Sun/Java documentation on RemoteExceptions

http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html

doesn't give me any clues on how Scala might need/use it.

Best suggestion next is to try a web search on keywords
Scala RemoteException
and see what that throws up.

If you happen to find out the answer, please share it.

Thanks, Justin

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Scala/Java interop

The $tag method is generated by the Scala compiler. It's used in
pattern matching, as a hash to speed up the case where there are many
alternatives in a match. It has to have a throws RemoteException
because java.rmi demands that remotable objects have only methods that
include RemoteException in their throws clause. Because every Scala
object ends up with a $tag method, and some objects might be
remotable, we need to add this throws clause to the interface.

That said, we are currently thinking of eliminating $tag altogether
for Scala 2.8, as modern VM's seem to be able to cope well with large
sequences of instanceOf tests, so hash support might not be needed
anymore.

Cheers

Victor NOEL
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala/Java interop

On Sun, Dec 21, 2008 at 02:57:41PM +0100, martin odersky wrote:
> The $tag method is generated by the Scala compiler. It's used in
> pattern matching, as a hash to speed up the case where there are many
> alternatives in a match. It has to have a throws RemoteException
> because java.rmi demands that remotable objects have only methods that
> include RemoteException in their throws clause. Because every Scala
> object ends up with a $tag method, and some objects might be
> remotable, we need to add this throws clause to the interface.
>
> That said, we are currently thinking of eliminating $tag altogether
> for Scala 2.8, as modern VM's seem to be able to cope well with large
> sequences of instanceOf tests, so hash support might not be needed
> anymore.

Thanks you for this clear explanation :)

>
> Cheers
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland