You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
But there is something wrong as this example shows:
defminimalExample() = {
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)
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:
objectRobotPlayer {
defrun(rc: RobotController) {
valthings= 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.
Activity
Pear0 commentedon Jan 16, 2017
Why do you need
BodyType? Player code can only rely onbattlecode/common, you shouldn't need anything inbattlecode/schema.As far as polymorphishm goes,
Robotinfo,BulletInfo, andTreeInfoall implementBodyInfo.omelkonian commentedon Jan 16, 2017
This really needs to be solved ASAP, as it really slows down the development process.
Polymorphism in general works as this example shows:
But there is something wrong as this example shows:
Running it results in this stack trace:
Pear0 commentedon Jan 17, 2017
These are really two separate issues.
For @revalo's issue:
Make sure your code doesn't rely on (even import) any
battlecodecode that isn't inbattlecode/common.For @omelkonian's issue:
To fix this, the devs need to whitelist
scala/reflect/ClassTag$and possiblyscala/reflect/ClassTag, but as a workaround, you can convert to any other collection and it should work just fine: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 usingClassTagobjects which store theClassobject and can use reflection to instantiate new arrays of a generic type.Edit: reformatted some things