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

Can't use BodyInfo in Scrimmage #403

Open
revalo opened this issue Jan 15, 2017 · 3 comments
Open

Can't use BodyInfo in Scrimmage #403

revalo opened this issue Jan 15, 2017 · 3 comments

Comments

@revalo
Copy link

revalo commented Jan 15, 2017

battlecode.instrumenter.InstrumentationException: ILLEGAL Illegal class: battlecode/schema/BodyType
    this class cannot be referenced by player code.

Can't use Polymorphism.

Edit: mistake in title.

@Pear0
Copy link
Contributor

Pear0 commented Jan 16, 2017

Why do you need BodyType? Player code can only rely on battlecode/common, you shouldn't need anything in battlecode/schema.

As far as polymorphishm goes, Robotinfo, BulletInfo, and TreeInfo all implement BodyInfo.

@omelkonian
Copy link

This really needs to be solved ASAP, as it really slows down the development process.

Polymorphism in general works as this example shows:

def testPolymorphism[T](array: Array[T]): Boolean = true

def minimalExample() = {
   val trees: Array[TreeInfo] = rc.senseNearbyTrees()
   assert(testPolymorphism(array)))
   // No exception whatsoever
}

But there is something wrong as this example shows:

def minimalExample() = {
   System.out.println(
      rc.senseNearbyTrees() ++  rc.senseNearbyRobots() // InstrumentationException!
   )
   // This also throws an exception
   (rc.senseNearbyTrees(): Array[BodyInfo]) ++ (rc.senseNearbyRobots(): Array[BodyInfo])
   // The following work fine
   (rc.senseNearbyTrees(): Array[TreeInfo]) ++ (rc.senseNearbyRobots(): Array[TreeInfo])
   (rc.senseNearbyTrees(): Seq[BodyInfo]) ++ (rc.senseNearbyRobots(): Seq[BodyInfo])   
}

Running it results in this stack trace:

Stack trace: 
battlecode.instrumenter.InstrumentationException: ILLEGAL Illegal class: scala/reflect/ClassTag$
    this class cannot be referenced by player code.
        at battlecode.instrumenter.bytecode.ClassReferenceUtil.classReference(ClassReferenceUtil.java:172)
        at battlecode.instrumenter.bytecode.InstrumentingMethodVisitor.classReference(InstrumentingMethodVisitor.java:78)
        at battlecode.instrumenter.bytecode.InstrumentingMethodVisitor.visitFieldInsnNode(InstrumentingMethodVisitor.java:251)
        at battlecode.instrumenter.bytecode.InstrumentingMethodVisitor.visitMaxs(InstrumentingMethodVisitor.java:108)
        at org.objectweb.asm.ClassReader.a(Unknown Source)
        at org.objectweb.asm.ClassReader.b(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at battlecode.instrumenter.TeamClassLoaderFactory$Loader.instrument(TeamClassLoaderFactory.java:522)
        at battlecode.instrumenter.TeamClassLoaderFactory$Loader.loadClass(TeamClassLoaderFactory.java:443)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

@Pear0
Copy link
Contributor

Pear0 commented Jan 17, 2017

These are really two separate issues.

For @revalo's issue:

Make sure your code doesn't rely on (even import) any battlecode code that isn't in battlecode/common.

For @omelkonian's issue:

To fix this, the devs need to whitelist scala/reflect/ClassTag$ and possibly scala/reflect/ClassTag, but as a workaround, you can convert to any other collection and it should work just fine:

object RobotPlayer {
  def run(rc: RobotController) {
    
    val things = rc.senseNearbyRobots().toList ++ rc.senseNearbyTrees().toList // this works

    println(things)
  }
}

Explanation:

For historical reasons, all container types except arrays undergo type erasure. A side effect of this is that in Java, generic arrays new E[] cannot be instantiated while other containers can. Scala gets around that by using ClassTag objects which store the Class object and can use reflection to instantiate new arrays of a generic type.

Edit: reformatted some things

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

3 participants