在Jython中打开NetLogo模型时引发Java非法参数异常

在Jython中打开NetLogo模型时引发Java非法参数异常,netlogo,jython-2.7,Netlogo,Jython 2.7,我试图使用运行在OSX El Capitan(10.11.6)上的Jython 2.7.0(在Java1.8.0131上)来控制NetLogo的API来运行实验。在尝试运行以下代码时: import site site.addsitedir("/Users/nqe/NetLogo/NetLogo 6.0.1/Java/") import org.nlogo.headless.HeadlessWorkspace as hw workspace = hw.newInstance() workspa

我试图使用运行在OSX El Capitan(10.11.6)上的Jython 2.7.0(在Java1.8.0131上)来控制NetLogo的API来运行实验。在尝试运行以下代码时:

import site
site.addsitedir("/Users/nqe/NetLogo/NetLogo 6.0.1/Java/")
import org.nlogo.headless.HeadlessWorkspace as hw

workspace = hw.newInstance()
workspace.open("models/Sample Models/Earth Science/Fire.nlogo")
workspace.command("set density 62")
workspace.command("random-seed 0")
workspace.command("setup")
workspace.command("repeat 50 [ go ]")
print (workspace.report("burned-trees"))

workspace.dispose()
我得到以下错误:

at scala.Predef$.require(Predef.scala:264)
at org.nlogo.generate.PrimitiveCache$.read$1(PrimitiveCache.scala:22)
at org.nlogo.generate.PrimitiveCache$.$anonfun$getClassReader$1(PrimitiveCache.scala:26)
at scala.collection.mutable.AbstractMap.getOrElseUpdate(Map.scala:80)
at org.nlogo.generate.PrimitiveCache$.getClassReader(PrimitiveCache.scala:26)
at org.nlogo.generate.PeepholeSafeChecker.processClass(PeepholeSafeChecker.scala:49)
at org.nlogo.generate.PeepholeSafeChecker.isSafe(PeepholeSafeChecker.scala:42)
at org.nlogo.generate.Generator$InstructionGenerator.generateInstruction(Generator.scala:190)
at org.nlogo.generate.Generator$InstructionGenerator.generateBodyMethod(Generator.scala:124)
at org.nlogo.generate.Generator$InstructionGenerator.generate(Generator.scala:99)
at org.nlogo.generate.Generator.org$nlogo$generate$Generator$$recurse(Generator.scala:29)
at org.nlogo.generate.Generator.$anonfun$recurse$1(Generator.scala:31)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:193)
at scala.collection.TraversableLike.map$(TraversableLike.scala:234)
at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:193)
at org.nlogo.generate.Generator.org$nlogo$generate$Generator$$recurse(Generator.scala:31)
at org.nlogo.generate.Generator.$anonfun$generate$1(Generator.scala:25)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:193)
at scala.collection.TraversableLike.map$(TraversableLike.scala:234)
at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:193)
at org.nlogo.generate.Generator.generate(Generator.scala:25)
at org.nlogo.compile.CompilerMain$.assembleProcedure(CompilerMain.scala:79)
at org.nlogo.compile.CompilerMain$.$anonfun$compile$2(CompilerMain.scala:55)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.immutable.List.foreach(List.scala:378)
at scala.collection.TraversableLike.map$(TraversableLike.scala:234)
at scala.collection.immutable.List.map(List.scala:284)
at org.nlogo.compile.CompilerMain$.compile(CompilerMain.scala:55)
at org.nlogo.compile.Compiler.compileProgram(Compiler.scala:52)
at org.nlogo.headless.HeadlessModelOpener.openFromModel(HeadlessModelOpener.scala:54)
at org.nlogo.headless.HeadlessWorkspace.openModel(HeadlessWorkspace.scala:532)
at org.nlogo.headless.HeadlessWorkspace.open(HeadlessWorkspace.scala:499)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)

java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: requirement failed  
如果“导入站点”部分不清楚,我会执行以下操作:

  • 创建jython脚本,将“/Users/nqe/NetLogo/NetLogo 6.0.1/Java/”中的所有.jar文件写入.pth文件
  • 然后我将这个.pith文件与.jar文件一起放在…/Java/目录中
  • 这允许我在需要导入NetLogo的各种API功能时从sys.path访问所有.jar依赖项 我无法准确地找出导致此错误的原因,因为在python交互模式下运行时,我能够使用hw.newInstance()命令成功地创建NetLogo JVM的新实例(在运行此代码时,我可以看到弹出一个Java图标),例如,如果我没有指定url,open命令就会抛出相应的错误

    因此,我认为这可能与我的JVM配置不正确有关,所以我尝试了一些方法

    首先,我检查了我是否能够实际运行在headless模式下控制NetLogo API的java示例,在这里可以找到:。我能够使用以下命令运行此处给出的代码:

    javadir=/Users/nqe/NetLogo/ControlAPI/
    netjardir=/Users/nqe/NetLogo/NetLogo\ 6.0.1/Java/netlogo-mac-app.jar
    
    javaname=Example1
    
    javac -cp "${javadir}":"${netjardir}" $javaname.java
    java -cp "${javadir}":"${netjardir}" $javaname 
    
    无需手动更改任何JVM设置。尽管如此,在运行jython代码时,我还是继续尝试更改JVM设置,例如文档和扩展的路径,尤其是./lib目录的路径。不幸的是,指定以下JVM设置:

    -Djava.library.path=~/JRE/Contents/Home/jre/lib/
    
    对事业毫无帮助。请注意,~ here是NetLogo 6.0.1目录中的缩写,这是我能找到的唯一lib目录

    最后,我不同意这一点:当我试图运行上面的jython脚本时,仅指定netlogo-mac-app.jar的路径,我无法导入headless类内容。因此,在只指定这一个.jar类路径的情况下编译/运行java可能会以某种方式访问NetLogo工作所需的一些有用的元数据(我不知道在我的java背景水平下这是否可行)

    考虑到这一点,我在~/NetLogo 6.0.1.app/Contents/Java/中找到了一个NetLogo.cfg文件,其中包含以下信息:

    [Application]
    app.name=NetLogo
    app.mainjar=netlogo-mac-app.jar
    app.version=6.0.1
    app.preferences.id=org/nlogo/app
    app.mainclass=org/nlogo/app/MacApplication
    app.classpath=$APPDIR/../../Java/args4j-2.0.12.jar:$APPDIR/../../Java/asm-5.0.3.jar:$APPDIR/../../Java/asm-5.0.3.jar:$APPDIR/../../Java/asm-all-5.0.4.jar:$APPDIR/../../Java/asm-all-5.0.4.jar:$APPDIR/../../Java/asm-analysis-5.0.3.jar:$APPDIR/../../Java/asm-analysis-5.0.3.jar:$APPDIR/../../Java/asm-tree-5.0.3.jar:$APPDIR/../../Java/asm-tree-5.0.3.jar:$APPDIR/../../Java/asm-util-5.0.3.jar:$APPDIR/../../Java/asm-util-5.0.3.jar:$APPDIR/../../Java/behaviorsearch.jar:$APPDIR/../../Java/commons-codec-1.10.jar:$APPDIR/../../Java/commons-codec-1.10.jar:$APPDIR/../../Java/commons-logging-1.1.1.jar:$APPDIR/../../Java/commons-logging-1.1.1.jar:$APPDIR/../../Java/gluegen-rt-2.3.2.jar:$APPDIR/../../Java/gluegen-rt-2.3.2.jar:$APPDIR/../../Java/httpclient-4.2.jar:$APPDIR/../../Java/httpclient-4.2.jar:$APPDIR/../../Java/httpcore-4.2.jar:$APPDIR/../../Java/httpcore-4.2.jar:$APPDIR/../../Java/httpmime-4.2.jar:$APPDIR/../../Java/httpmime-4.2.jar:$APPDIR/../../Java/java-objc-bridge-1.0.0.jar:$APPDIR/../../Java/jcommon-1.0.16.jar:$APPDIR/../../Java/jfreechart-1.0.13.jar:$APPDIR/../../Java/jhotdraw-6.0b1.jar:$APPDIR/../../Java/jhotdraw-6.0b1.jar:$APPDIR/../../Java/jmf-2.1.1e.jar:$APPDIR/../../Java/jmf-2.1.1e.jar:$APPDIR/../../Java/jna-4.2.2.jar:$APPDIR/../../Java/jogl-all-2.3.2.jar:$APPDIR/../../Java/jogl-all-2.3.2.jar:$APPDIR/../../Java/json-simple-1.1.1.jar:$APPDIR/../../Java/json-simple-1.1.1.jar:$APPDIR/../../Java/log4j-1.2.16.jar:$APPDIR/../../Java/log4j-1.2.16.jar:$APPDIR/../../Java/macro-compat_2.12-1.1.1.jar:$APPDIR/../../Java/macro-compat_2.12-1.1.1.jar:$APPDIR/../../Java/netlogo-6.0.1.jar:$APPDIR/../../Java/netlogo-6.0.1.jar:$APPDIR/../../Java/netlogo-mac-app.jar:$APPDIR/../../Java/parboiled-core-1.1.7.jar:$APPDIR/../../Java/parboiled-core-1.1.7.jar:$APPDIR/../../Java/parboiled-java-1.1.7.jar:$APPDIR/../../Java/parboiled-java-1.1.7.jar:$APPDIR/../../Java/parboiled_2.12-2.1.3.jar:$APPDIR/../../Java/parboiled_2.12-2.1.3.jar:$APPDIR/../../Java/pegdown-1.6.0.jar:$APPDIR/../../Java/pegdown-1.6.0.jar:$APPDIR/../../Java/picocontainer-2.13.6.jar:$APPDIR/../../Java/picocontainer-2.13.6.jar:$APPDIR/../../Java/rsyntaxtextarea-2.6.0.jar:$APPDIR/../../Java/rsyntaxtextarea-2.6.0.jar:$APPDIR/../../Java/scala-library-2.12.0.jar:$APPDIR/../../Java/scala-library-2.12.1.jar:$APPDIR/../../Java/scala-library-2.12.1.jar:$APPDIR/../../Java/scala-parser-combinators_2.12-1.0.5.jar:$APPDIR/../../Java/scala-parser-combinators_2.12-1.0.5.jar:$APPDIR/../../Java/shapeless_2.12-2.3.2.jar:$APPDIR/../../Java/shapeless_2.12-2.3.2.jar
    app.runtime=$APPDIR/../../JRE
    app.identifier=org.nlogo.app
    
    [JVMOptions]
    -Dnetlogo.extensions.dir=$APPDIR/../../extensions
    -Dnetlogo.models.dir=$APPDIR/../../models
    -Dnetlogo.docs.dir=$APPDIR/../../docs
    -Xdock:name=NetLogo
    -Dorg.nlogo.mac.appClassName=org.nlogo.app.App$
    -Xmx1024m
    -Dfile.encoding=UTF-8
    -Dapple.awt.graphics.UseQuartz=true
    
    
    [JVMUserOptions]
    
    [ArgOptions]
    

    这看起来很有希望,但是通过打开应用程序/使用Control API with Java方法,删除这个文件并不会影响我运行NetLogo的能力。正因为如此,我被难倒了,所以任何帮助都将不胜感激

    NetLogo要求JVM启动时的当前工作目录是NetLogo目录。@SethTisue不幸的是,这样做不行,但我最终决定只从Java控制API,在Java中我可以更明确地控制JVM设置。然而,在这样做的过程中,我遇到了第二个小问题,这个问题可能不能保证整个帖子的正确性:当直接使用NetLogo API控制API时,NetLogo能否像在BehaviorSpace中那样在多个线程中运行,或者我现在必须作为用户显式地用Java控制线程吗?这是一个好问题-请就此提出一个新问题。@Nic您需要自己用Java控制线程