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

How is the Scala signature stored?

3 replies
Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.

After running my application through ProGuard, I find that I can no
longer use my Scala classes from the Scala interpreter:

scala> classOf[org.nlogo.lab.ProtocolLoader]
error: error while loading ProtocolLoader, Scala signature ProtocolLoader has wrong version
expected: 4.1
found: 0.0

I imagine ProGuard is stripping out this information to save space.
Perhaps I can tell ProGuard not to do that (its behavior is configurable
in about a million different ways), but I'll need to know how this
"Scala signature" information is stored in the classfiles...?

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: How is the Scala signature stored?

On Sat, Feb 21, 2009 at 09:00:08PM -0600, Seth Tisue wrote:
> I imagine ProGuard is stripping out this information to save space.
> Perhaps I can tell ProGuard not to do that (its behavior is configurable
> in about a million different ways), but I'll need to know how this
> "Scala signature" information is stored in the classfiles...?

It's a classfile attribute called "ScalaSig" which you can see with javap (albeit not in a form that'll make
much sense.)

$ javap -verbose A
Compiled from "a.scala"
public class A extends java.lang.Object implements scala.ScalaObject
SourceFile: "a.scala"
ScalaSig: length = 0xE3
04 01 29 06 08 01 02 FFFFFF84 FFFFFF80 FFFFFF80 FFFFFF80 00 05 02 01 41
0A 01 03 01 07 3C 65 6D 70 74 79 3E 03 00 13 03
00 06 0E 10 02 07 0C 0D 01 08 0A 02 09 0A 01 04
6C 61 6E 67 0A 01 0B 01 04 6A 61 76 61 09 02 0D
[etc]

Recent trunk has a scalap that'll decode it, not sure how complete it is yet:

$ scalap A
CLASSPATH = .
FILENAME = ./A.class
class A extends java.lang.Object with scala.ScalaObject {
def this(i : scala.Int, i : scala.Int) = { /* compiled code */ }
val q : scala.Int = { /* compiled code */ }
val r : scala.Int = { /* compiled code */ }
}

tolsen77
Joined: 2008-10-08,
User offline. Last seen 1 year 38 weeks ago.
Re: How is the Scala signature stored?
There was an error in Proguard that resulted in the ScalaSig data being nulled out. It's been fixed for the next 4.4 release by the author of Proguard.

On Sun, Feb 22, 2009 at 4:20 AM, Paul Phillips <paulp [at] improving [dot] org> wrote:
On Sat, Feb 21, 2009 at 09:00:08PM -0600, Seth Tisue wrote:
> I imagine ProGuard is stripping out this information to save space.
> Perhaps I can tell ProGuard not to do that (its behavior is configurable
> in about a million different ways), but I'll need to know how this
> "Scala signature" information is stored in the classfiles...?

It's a classfile attribute called "ScalaSig" which you can see with javap (albeit not in a form that'll make
much sense.)

$ javap -verbose A
Compiled from "a.scala"
public class A extends java.lang.Object implements scala.ScalaObject
 SourceFile: "a.scala"
 ScalaSig: length = 0xE3
  04 01 29 06 08 01 02 FFFFFF84 FFFFFF80 FFFFFF80 FFFFFF80 00 05 02 01 41
  0A 01 03 01 07 3C 65 6D 70 74 79 3E 03 00 13 03
  00 06 0E 10 02 07 0C 0D 01 08 0A 02 09 0A 01 04
  6C 61 6E 67 0A 01 0B 01 04 6A 61 76 61 09 02 0D
  [etc]

Recent trunk has a scalap that'll decode it, not sure how complete it is yet:

$ scalap A
CLASSPATH = .
FILENAME = ./A.class
class A extends java.lang.Object with scala.ScalaObject {
 def this(i : scala.Int, i : scala.Int) = { /* compiled code */ }
 val q : scala.Int = { /* compiled code */ }
 val r : scala.Int = { /* compiled code */ }
}

--
Paul Phillips      | If this is raisin, make toast with it.
Apatheist          |
Empiricist         |
pp: i haul pills   |----------* http://www.improving.org/paulp/ *----------

tolsen77
Joined: 2008-10-08,
User offline. Last seen 1 year 38 weeks ago.
Re: How is the Scala signature stored?
The fix from the author (http://sourceforge.net/forum/message.php?msg_id=6210097)

Change proguard/classfile/io/ProgramClassWriter.java:

Change (from about line 281):
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
        // Write the unknown information.
        byte[] info = new byte[unknownAttribute.u4attributeLength];
        dataOutput.write(info);
        unknownAttribute.info = info;
}

To:
public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
{
        // Write the unknown information.
        dataOutput.write(unknownAttribute.info);
}


On Sun, Feb 22, 2009 at 4:00 AM, Seth Tisue <seth [at] tisue [dot] net> wrote:

After running my application through ProGuard, I find that I can no
longer use my Scala classes from the Scala interpreter:

scala> classOf[org.nlogo.lab.ProtocolLoader]
error: error while loading ProtocolLoader, Scala signature ProtocolLoader has wrong version
 expected: 4.1
 found: 0.0

I imagine ProGuard is stripping out this information to save space.
Perhaps I can tell ProGuard not to do that (its behavior is configurable
in about a million different ways), but I'll need to know how this
"Scala signature" information is stored in the classfiles...?

--
Seth Tisue / http://tisue.net
lead developer, NetLogo: http://ccl.northwestern.edu/netlogo/


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