Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'class file is broken' error when extending Java static inner classes #2464

Closed
scabug opened this issue Oct 13, 2009 · 21 comments
Closed

'class file is broken' error when extending Java static inner classes #2464

scabug opened this issue Oct 13, 2009 · 21 comments
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Oct 13, 2009

The Scala compiler gives an erroneous 'class file broken' error when trying to use classes that inherit from static Java inner classes. This is particularly a problem when integrating with Java code generated by the [http://incubator.apache.org/thrift/ Apache Thrift] compiler. Below are the files and steps needed to reproduce the problem.

!ClassOne.java:

public class ClassOne {
	public interface Iface {
		public void func1();
	}
	public static class Child implements Iface {
		public void func1() {return ;}
	}
}

!ClassTwo.java:

public class ClassTwo {
	public interface Iface extends ClassOne.Iface  {
		public void func2();
	}
	public static class Child extends ClassOne.Child implements Iface {
		public void func2() {return ;}
	}
}

!ScalaClasses.scala:

class ScalaClassOne extends ClassTwo.Child {
	def func4() = {
		func1
		func2
	}	
}

class ScalaClassTwo extends ClassTwo.Iface {
	def func1() = null
	def func2() = null
}

Bug.scala:

object Test {
	val c2 = new ScalaClassTwo
	val c1 = new ScalaClassOne
}

And the following compilation sequence:

	javac *.java
	scalac ScalaClasses.scala
	scalac Bug.scala

The compilation of Bug.scala will fail with the following error on 2.7.5:

error: error while loading ScalaClassOne, class file './ScalaClassOne.class' is broken
(package <empty> does not have a member ClassThree$$Child)
User.scala:3: error: ScalaClassOne does not have a constructor
	val c1 = new ScalaClassOne
                 ^
two errors found

And this error on 2.8.0-b20090919135825:

scala.tools.nsc.FatalError: package <empty> does not have a member ClassTwo$$Child
	at scala.tools.nsc.symtab.Definitions$$definitions$$.getMember(Definitions.scala:406)
	at scala.tools.nsc.symtab.classfile.ClassfileParser.lookupClass$$1(ClassfileParser.scala:382)
	at scala.tools.nsc.symtab.classfile.ClassfileParser.classNameToSymbol(ClassfileParser.scala:394)
	at scala.tools.nsc.symtab.classfile.ClassfileParser$$ConstantPool.getClassSymbol(ClassfileParser.scala:180)
	at scala.tools.nsc.symtab.classfile.ClassfileParser$$ConstantPool.getSuperClass(ClassfileParser.scala:317)
	at scala.tools.nsc.symtab.classfile.ClassfileParser.parseClass(ClassfileParser.scala:415)
	at scala.tools.nsc.symtab.classfile.ClassfileParser.parse(ClassfileParser.scala:92)
	at scala.tools.nsc.symtab.SymbolLoaders$$ClassfileLoader$$$$anonfun$$doComplete$$4.apply(SymbolLoaders.scala:291)
	at scala.tools.nsc.symtab.SymbolLoaders$$ClassfileLoader$$$$anonfun$$doComplete$$4.apply(SymbolLoaders.scala:291)
	at scala.tools.nsc.symtab.SymbolLoaders.completeClassfile(SymbolLoaders.scala:278)
	at scala.tools.nsc.symtab.SymbolLoaders$$ClassfileLoader.doComplete(SymbolLoaders.scala:290)
	at scala.tools.nsc.symtab.SymbolLoaders$$SymbolLoader.complete(SymbolLoaders.scala:55)
	at scala.tools.nsc.symtab.SymbolLoaders$$SymbolLoader.load(SymbolLoaders.scala:75)
	at scala.tools.nsc.symtab.Symbols$$Symbol.exists(Symbols.scala:600)
	at scala.tools.nsc.typechecker.Typers$$Typer.qualifies$$1(Typers.scala:3316)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedIdent$$1(Typers.scala:3332)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3697)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3768)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedTypeConstructor(Typers.scala:3866)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedTypeConstructor(Typers.scala:3874)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedNew$$1(Typers.scala:2854)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3599)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3768)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedQualifier(Typers.scala:3835)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3685)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3768)
	at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$typedApply$$1$$1.apply(Typers.scala:3045)
	at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$typedApply$$1$$1.apply(Typers.scala:3045)
	at scala.tools.nsc.typechecker.Typers$$Typer.silent(Typers.scala:698)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedApply$$1(Typers.scala:3045)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3663)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3768)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3826)
	at scala.tools.nsc.typechecker.Typers$$Typer.computeType(Typers.scala:3877)
	at scala.tools.nsc.typechecker.Namers$$Namer.typeSig(Namers.scala:1141)
	at scala.tools.nsc.typechecker.Namers$$Namer$$$$anonfun$$typeCompleter$$1.apply(Namers.scala:509)
	at scala.tools.nsc.typechecker.Namers$$Namer$$$$anonfun$$typeCompleter$$1.apply(Namers.scala:507)
	at scala.tools.nsc.typechecker.Namers$$$$anon$$1.complete(Namers.scala:1288)
	at scala.tools.nsc.symtab.Symbols$$Symbol.info(Symbols.scala:728)
	at scala.tools.nsc.symtab.Symbols$$Symbol.initialize(Symbols.scala:837)
	at scala.tools.nsc.symtab.Symbols$$Symbol.annotations(Symbols.scala:111)
	at scala.tools.nsc.typechecker.Typers$$Typer.addGetterSetter(Typers.scala:1277)
	at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$10.apply(Typers.scala:1385)
	at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$10.apply(Typers.scala:1385)
	at scala.collection.TraversableLike$$$$anonfun$$flatMap$$1.apply(TraversableLike.scala:167)
	at scala.collection.TraversableLike$$$$anonfun$$flatMap$$1.apply(TraversableLike.scala:167)
	at scala.collection.LinearSequenceLike$$class.foreach(LinearSequenceLike.scala:85)
	at scala.collection.immutable.List.foreach(List.scala:27)
	at scala.collection.TraversableLike$$class.flatMap(TraversableLike.scala:167)
	at scala.collection.immutable.List.flatMap(List.scala:27)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedTemplate(Typers.scala:1385)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedModuleDef(Typers.scala:1256)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3498)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3768)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3813)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedStat$$1(Typers.scala:1815)
	at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$20.apply(Typers.scala:1872)
	at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$20.apply(Typers.scala:1872)
	at scala.collection.immutable.List.loop$$2(List.scala:123)
	at scala.collection.immutable.List.mapConserve(List.scala:140)
	at scala.tools.nsc.typechecker.Typers$$Typer.typedStats(Typers.scala:1872)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3491)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3768)
	at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:3813)
	at scala.tools.nsc.typechecker.Analyzer$$typerFactory$$$$anon$$2.apply(Analyzer.scala:57)
	at scala.tools.nsc.Global$$GlobalPhase.applyPhase(Global.scala:329)
	at scala.tools.nsc.typechecker.Analyzer$$typerFactory$$$$anon$$2$$$$anonfun$$run$$1.apply(Analyzer.scala:51)
	at scala.tools.nsc.typechecker.Analyzer$$typerFactory$$$$anon$$2$$$$anonfun$$run$$1.apply(Analyzer.scala:51)
	at scala.collection.Iterator$$class.foreach(Iterator.scala:525)
	at scala.collection.mutable.ListBuffer$$$$anon$$1.foreach(ListBuffer.scala:281)
	at scala.tools.nsc.typechecker.Analyzer$$typerFactory$$$$anon$$2.run(Analyzer.scala:51)
	at scala.tools.nsc.Global$$Run.compileSources(Global.scala:799)
	at scala.tools.nsc.Global$$Run.compile(Global.scala:882)
	at scala.tools.nsc.Main$$.process(Main.scala:91)
	at scala.tools.nsc.Main$$.main(Main.scala:105)
	at scala.tools.nsc.Main.main(Main.scala)
error: fatal error: package <empty> does not have a member ClassTwo$$Child
make: *** [all] Error 1
@scabug
Copy link
Author

scabug commented Oct 13, 2009

Imported From: https://issues.scala-lang.org/browse/SI-2464?orig=1
Reporter: Michael Armbrust (marmbrus)
Attachments:

@scabug
Copy link
Author

scabug commented Nov 25, 2009

@dragos said:
(In r19874) Fixed ticket 2464

@scabug
Copy link
Author

scabug commented Nov 30, 2009

@dragos said:
(In r19945) Closed #2726 and added test for #2464 (refs #2464)

@scabug
Copy link
Author

scabug commented Dec 16, 2009

@paulp said:
My new officemates ran into this bug, also as a consequence of code generated by thrift. The test case given in this ticket works, but the bug is definitely still in trunk. I will work on getting a reproduction but please trust me for the moment. BTW incredibly I overlooked this ticket while researching this exact issue, because there are something like a dozen open or should-be-open tickets relating to inner classes.

I am going on a bytecode-tool-writing kick right now. Reconciling all the java and scala factors in the tricky interdependent attribute areas like InnerClasses is simply too hard. We're not going to get it right without validating the result.

@scabug
Copy link
Author

scabug commented Jan 13, 2010

@paulp said:
See #2896 for what should be a concrete example of this (or failing that, something similar.)

@scabug
Copy link
Author

scabug commented Jan 22, 2010

@paulp said:
...and also #2940.

@scabug
Copy link
Author

scabug commented Mar 26, 2010

Brian Hsu (brianhsu) said:
Just FYI, I think the following is another concrete example of this bug (or similar to this, I'm not very sure).

This is a code that use Google Mpas API in Android. In Google Maps API, MapView class has a static inner class witch extends from android.view.ViewGroup.LayoutParams which in turns another static inner class of ViewGroup.

Here is the sample code:

import android.os.Bundle
import android.widget.LinearLayout

import com.google.android.maps.MapActivity
import com.google.android.maps.MapView

class TestMap extends MapActivity
{
    type F = MapView.LayoutParams  // This will caused compiler crash
    override def isRouteDisplayed () = false

    override def onCreate(savedInstanceState: Bundle)
    {
        val mapView: MapView = null // This line also crash compiler
    }
}

When using the following commands to compile

/opt/scala-svn/bin/scalac -cp android.jar:maps.jar Test.scala

The compiler will complain

error: error while loading MapView, Missing dependency 'class android.view.ViewGroup$$LayoutParams', required by /opt/android-sdk-update-manager/add-ons/google_apis-7_r01/libs/maps.jar(com/google/android/maps/MapView.class)
error: error while loading LayoutParams, Missing dependency 'class android.view.ViewGroup$$LayoutParams', required by /opt/android-sdk-update-manager/add-ons/google_apis-7_r01/libs/maps.jar(com/google/android/maps/MapView$$LayoutParams.class)
two errors found

The scala compiler version is svn trunk at 2010-03-26

@scabug
Copy link
Author

scabug commented Jul 5, 2010

papamitra said:

Maybe maps.jar (Google Maps API in Android) is broken.
Because it seems that maps.jar in Android SDK is created by "mkstubs" in Android source tree(development/tools/mkstubs)

And, it writes in mkstubs's README.txt,

The generated constructors are not proper. They do not invoke the matching super() before the generated throw exception. Any attempt to load such a class should trigger an error from the byte code verifier or the class loader.

I replace MapView.class and MapController.class in maps.jar with the following files.

http://gist.github.com/454723
http://gist.github.com/454727

And, work it.

@scabug
Copy link
Author

scabug commented Jul 5, 2010

@paulp said:
Replying to [comment:16 papamitra]:

The generated constructors are not proper. They do not invoke the matching super() before the generated throw exception. Any attempt to load such a class should trigger an error from the byte code verifier or the class loader.

Well that's an interesting thing to find out at this stage of the game. Thanks. But even if we exclude maps.jar from consideration there are other examples of the issue with no such excuse.

@scabug
Copy link
Author

scabug commented Jul 26, 2010

@michelou said:
Case 1 (from marmbrus) is ok with 2.8.0.final.

Case 2 (from brianhsu) is fixed in rev22630. That case did in particular affect Android code (I had myself to disable Android examples such as MapsDemo, Wiktionary, Panoramio, WindWaves, see rev22631).

@scabug scabug closed this as completed May 18, 2011
@scabug
Copy link
Author

scabug commented Feb 24, 2013

Stefan Endrullis (xylo) said (edited on Feb 24, 2013 7:50:14 PM UTC):
I know this bug is already 2 years old. However, today I got the same error or at least a very similar one using the Scala 2.10.0 and Scala 2.10.1-RC1 compiler:
error: error while loading com.vaadin.ui., class file '/home/stefan/.m2/repository/com/vaadin/vaadin/6.8.8/vaadin-6.8.8.jar(com/vaadin/ui/ClientWidget$LoadStyle.class)' is broken

It's easy to reproduce. I bundled a tiny example project into the attached zip archive. To compile it just run
$ mvn compile

The only Scala file included in the project is a one-liner:
class PortalLayout extends org.vaadin.sasha.portallayout.PortalLayout

Obviously it's not even necessary to refer to the "broken" class directly in the Scala code in order to let the compiler fail. And there is unfortunately nothing I can do to work around this except to avoid the class org.vaadin.sasha.portallayout.PortalLayout in my project completely.

Regards,
Stefan

@scabug
Copy link
Author

scabug commented Apr 25, 2013

Stefan Endrullis (xylo) said (edited on Apr 25, 2013 4:15:48 PM UTC):
Same in 2.10.1 and 2.11.0-M2. The Scala compiler fails to compile the vaadin project (attached).

Scala seems to be no longer compatible with vaadin. That's very disappointing. :(

@scabug
Copy link
Author

scabug commented Apr 25, 2013

@paulp said:
Stefan, I'll make you a deal - I fixed the bug you're hitting, but I do not have time to dredge out a test case. If you can manage the test case (no maven, no downloading giant jars - small self-contained java and scala) you'll see this fixed in 2.10.2.

Here's the code part: https://github.com/paulp/scala/tree/issue/2464

@scabug
Copy link
Author

scabug commented Apr 30, 2013

John Nestor (nestorpersist) said:
I am not sure about building a test case without the Vaadin jar.
Although the best guess is that Java inner classes are involved I don't know how to easily extract
all the potentially problematic code out of Vaadin.

If you have a fix I would be happy to try out your snapshot scala compiler with the fix on my project if you can make it available.

@scabug
Copy link
Author

scabug commented Apr 30, 2013

@paulp said:
I am not sure what you mean by "make it available" but the code is right there. I know it fixes the problem; I need a test case not to convince myself it works but to get the code into the compiler.

@scabug
Copy link
Author

scabug commented May 2, 2013

Stefan Endrullis (xylo) said (edited on May 2, 2013 10:35:15 AM UTC):
I already tried to write a small test case with the inner class that could not be parsed by scalac (ClientWidget$LoadStyle), but I did not manage to reproduce the error that occurs in the example vaadin project. It seems to be complicated. I bundled a smaller test project with one Scala file and two jar files (vaadin and portletlayout). I attached it as tiny-vaadin.tar.bz2.

Compilation:
scalac -classpath vaadin-6.8.8.jar:portallayout-1.3.1.jar PortalLayout.scala

@scabug
Copy link
Author

scabug commented May 2, 2013

Stefan Endrullis (xylo) said:
smaller vaadin project without maven

@scabug
Copy link
Author

scabug commented Jun 6, 2013

@retronym said:
I've debugged this.

With Paul's patch in place to change this from a crasher to a warning, we get:

sym             = {scala.reflect.internal.Symbols$TermSymbol@4573}"value EAGER"
sym.owner       = {scala.reflect.internal.Symbols$ModuleClassSymbol@4580}"module class ClientWidget$LoadStyle"
sym.owner.owner = {scala.reflect.internal.Symbols$PackageClassSymbol@4582}"package ui"
sym.owner.owner.info.decl(this.global.newTermName("ClientWidget")).info.decls.toList(1).moduleClass
                = {scala.reflect.internal.Symbols$ModuleClassSymbol@5792}"module class LoadStyle"

I think the root bug is the existence of module class ClientWidget$LoadStyle.

I haven't managed yet to distill the essence of Stefan's test case to something independent from those JARs.

@scabug
Copy link
Author

scabug commented Jun 6, 2013

@retronym said (edited on Jun 6, 2013 4:02:06 PM UTC):
Stefan's problem with Vaadin appears to stem from a deficient InnerClasses section in org.vaadin.sasha.portallayout.PortalLayout

% qbin/scala -Ydebug -classpath /Users/jason/Downloads/tiny-vaadin/vaadin-6.8.8.jar:/Users/jason/Downloads/tiny-vaadin/portallayout-1.3.1.jar:.

% curl --silent https://vaadin-portal-layout.googlecode.com/svn-history/r10/trunk/src/org/vaadin/sasha/portallayout/PortalLayout.java | head -25
package org.vaadin.sasha.portallayout;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.vaadin.sasha.portallayout.client.ui.VPortalLayout;

import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.ClientWidget;
import com.vaadin.ui.Component;
import com.vaadin.ui.ClientWidget.LoadStyle;

/**
 * Layout that presents its contents in a portal style.
 * @author p4elkin
 */
@SuppressWarnings("serial")
@ClientWidget(value = VPortalLayout.class, loadStyle = LoadStyle.EAGER)
public class PortalLayout extends AbstractLayout {
scala> :javap org.vaadin.sasha.portallayout.PortalLayout
Compiled from "PortalLayout.java"
public class org.vaadin.sasha.portallayout.PortalLayout extends com.vaadin.ui.AbstractLayout implements com.vaadin.ui.Layout$SpacingHandler,com.vaadin.event.LayoutEvents$LayoutClickNotifier
  SourceFile: "PortalLayout.java"
  RuntimeVisibleAnnotations: length = 0x12
   00 01 02 54 00 02 02 55 63 02 56 02 57 65 02 58
   02 59
  InnerClass:
   public #605= #132 of #603; //LayoutClickEvent=class com/vaadin/event/LayoutEvents$LayoutClickEvent of class com/vaadin/event/LayoutEvents
   public abstract #606= #135 of #603; //LayoutClickListener=class com/vaadin/event/LayoutEvents$LayoutClickListener of class com/vaadin/event/LayoutEvents
   public abstract #607= #7 of #603; //LayoutClickNotifier=class com/vaadin/event/LayoutEvents$LayoutClickNotifier of class com/vaadin/event/LayoutEvents
   public #610= #608 of #176; //Event=class com/vaadin/ui/Component$Event of class com/vaadin/ui/Component
   public abstract #613= #5 of #611; //SpacingHandler=class com/vaadin/ui/Layout$SpacingHandler of class com/vaadin/ui/Layout
   public abstract #614= #468 of #63; //Entry=class java/util/Map$Entry of class java/util/Map
   public abstract #617= #615 of #1; //PortletCloseListener=class org/vaadin/sasha/portallayout/PortalLayout$PortletCloseListener of class org/vaadin/sasha/portallayout/PortalLayout
   public #618= #91 of #1; //PortletClosedEvent=class org/vaadin/sasha/portallayout/PortalLayout$PortletClosedEvent of class org/vaadin/sasha/portallayout/PortalLayout
   public #619= #106 of #1; //PortletCollapseEvent=class org/vaadin/sasha/portallayout/PortalLayout$PortletCollapseEvent of class org/vaadin/sasha/portallayout/PortalLayout
   public abstract #622= #620 of #1; //PortletCollapseListener=class org/vaadin/sasha/portallayout/PortalLayout$PortletCollapseListener of class org/vaadin/sasha/portallayout/PortalLayout
  minor version: 0
  major version: 50
  Constant pool:
...
const #596 = Asciz	Lcom/vaadin/ui/ClientWidget;;
const #597 = Asciz	value;
const #598 = Asciz	Lorg/vaadin/sasha/portallayout/client/ui/VPortalLayout;;
const #599 = Asciz	loadStyle;
const #600 = Asciz	Lcom/vaadin/ui/ClientWidget$LoadStyle;;
const #601 = Asciz	EAGER;
const #602 = Asciz	InnerClasses;
const #603 = class	#604;	//  com/vaadin/event/LayoutEvents
...

I tried to compile a stripped down version of that class:

package test;

import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.ClientWidget;
import com.vaadin.ui.ClientWidget.LoadStyle;

@ClientWidget(value = com.vaadin.terminal.gwt.client.Paintable.class, loadStyle = LoadStyle.EAGER)
public abstract class PortalLayout extends AbstractLayout {
}
% javac -version javac 1.6.0_37

% qbin/scala -Ydebug -classpath /Users/jason/Downloads/tiny-vaadin/vaadin-6.8.8.jar:/Users/jason/Downloads/tiny-vaadin/portallayout-1.3.1.jar:.

scala> :javap test/PortalLayout
Compiled from "PortalLayout.java"
public abstract class test.PortalLayout extends com.vaadin.ui.AbstractLayout
  SourceFile: "PortalLayout.java"
  RuntimeVisibleAnnotations: length = 0x12
   00 01 00 0B 00 02 00 0C 63 00 0D 00 0E 65 00 12
   00 13
  InnerClass:
   public final #16= #15 of #23; //LoadStyle=class com/vaadin/ui/ClientWidget$LoadStyle of class com/vaadin/ui/ClientWidget
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method	#3.#20;	//  com/vaadin/ui/AbstractLayout."<init>":()V
const #2 = class	#21;	//  test/PortalLayout
const #3 = class	#22;	//  com/vaadin/ui/AbstractLayout
const #4 = Asciz	<init>;
const #5 = Asciz	()V;
const #6 = Asciz	Code;
const #7 = Asciz	LineNumberTable;
const #8 = Asciz	SourceFile;
const #9 = Asciz	PortalLayout.java;
const #10 = Asciz	RuntimeVisibleAnnotations;
const #11 = Asciz	Lcom/vaadin/ui/ClientWidget;;
const #12 = Asciz	value;
const #13 = Asciz	Lcom/vaadin/terminal/gwt/client/Paintable;;
const #14 = Asciz	loadStyle;
const #15 = class	#24;	//  com/vaadin/ui/ClientWidget$LoadStyle
const #16 = Asciz	LoadStyle;
const #17 = Asciz	InnerClasses;
const #18 = Asciz	Lcom/vaadin/ui/ClientWidget$LoadStyle;;
const #19 = Asciz	EAGER;
const #20 = NameAndType	#4:#5;//  "<init>":()V
const #21 = Asciz	test/PortalLayout;
const #22 = Asciz	com/vaadin/ui/AbstractLayout;
const #23 = class	#25;	//  com/vaadin/ui/ClientWidget
const #24 = Asciz	com/vaadin/ui/ClientWidget$LoadStyle;
const #25 = Asciz	com/vaadin/ui/ClientWidget;

The JAR file containing the class in question contains:

META-INF:

Manifest-Version: 1.0
Implementation-Title: PortalLayout
Implementation-Version: 1.3.1
Vaadin-Package-Version: 1
Class-Path: 
Vaadin-Widgetsets: org.vaadin.sasha.portallayout.PortallayoutWidgetset

rebel.xml

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">

	<classpath>
		<dir name="/Users/p4elkin/Projects/PortalLayout/build/classes">
		</dir>
	</classpath>

	<web>
		<link target="/">
			<dir name="/Users/p4elkin/Projects/PortalLayout/WebContent">
			</dir>
		</link>
	</web>

</application>

The repository doesn't have an Ant/Maven build or the like. Not sure what Java compiler generated that bytecode, nor which tools had their way with it. (This is all GWT related, maybe that gets involved.)

The JVM spec offers:

The InnerClasses attribute is a variable-length attribute in the attributes table of a ClassFile structure (§4.1). If the constant pool of a class or interface C contains a CONSTANT_Class_info entry which represents a class or interface that is not a member of a package, then C's ClassFile structure must have exactly one InnerClasses attribute in its attributes table.
...
If a class has members that are classes or interfaces, its constant_pool table (and hence its InnerClasses attribute) must refer to each such member, even if that member is not otherwise mentioned by the class. These rules imply that a nested class or interface member will have 
InnerClasses information for each enclosing class and for each immediate member.

Long story short, I'll submit Paul's patch to make us resilient against such bytecode.

@scabug
Copy link
Author

scabug commented Jun 6, 2013

@retronym said:
scala/scala#2639

@scabug
Copy link
Author

scabug commented Nov 16, 2013

Hassan Sultan (hassan.sultan) said:
I encountered a similar issue that I think the fix above will not address, I think it is related to an SBT bug (sbt/sbt#987), here is a minimal repro: https://github.com/TheSultan/sbtivypublicationsbug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants