Skip to content

Can't use BodyInfo in Scrimmage #403

Open

Description

@revalo
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.

Activity

  1. Pear0 commented on Jan 16, 2017

    @Pear0
    Contributor

    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.

  2. omelkonian commented on Jan 16, 2017

    @omelkonian

    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)
    
  3. Pear0 commented on Jan 17, 2017

    @Pear0
    Contributor

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions