【问题标题】:Java as a scripting language for Java?Java 作为 Java 的脚本语言?
【发布时间】:2012-11-24 17:13:03
【问题描述】:

是否可以将 Java 用作 Java 的脚本语言?或者也许在运行时以某种方式将java脚本编译成java二进制文件?我确实尝试过搜索,但除了一些黑客之外找不到任何全面的东西......

我有使用其他语言的经验,例如对于 C#,我使用了 lua,这非常方便,但现在我需要实现最高性能,因为每帧调用脚本的次数约为 1.000.000。

所以我认为将 java 本身改编为 java 程序的脚本语言应该可以为我提供最好的性能和兼容性。

有什么建议吗?

【问题讨论】:

  • @scrappedcola 据我了解,使用 lua 不会为我提供最佳性能,但如果这是我唯一的选择,那么可以肯定,这不是问题。但首先,如果可能的话,我想尝试更快地找到一些东西。
  • Groovy 是 Sun 专门为此目的开发的:oracle.com/technetwork/articles/java/groovy-1695411.html
  • 我不认为 Groovy 是 Sun/Oracle 开发的。我认为 James Strachan 对此负责
  • @BrianAgnew - 严格来说,James Strachan 为 Apache 基金会工作,而不是 Sun。但当时 Sun 与 Apache 基金会之间有着非常密切且富有成果的关系。 Groovy 的发展得到了 Sun 的全力鼓励和支持。

标签: java performance scripting jvm


【解决方案1】:

BeanShell 是 Java 常用的脚本解决方案。它是一种非常类似于 Java 的脚本语言。

存在使用 Java 基础架构和 JVM,但使用不同语言的其他解决方案。例如Scala、Groovy 和 Jython(与 Java 兼容的 Python)。所有这些实现的重要一点是它们将与使用标准 Java 创建的 Java 库进行互操作,因此您可以简单地使用(例如)Scala 来驱动您的 Java 语言创建的解决方案。

以上都提供了一个 REPL (read-eval-print-loop),因此您可以在动态命令行环境中导入、实例化对象并与之交互。这对于测试和原型交互以及测试脚本非常有用。

【讨论】:

  • 哦,我看到这里用到了 BeanShell。查看我的post 以查看 BeanShell 中的一些脚本。
【解决方案2】:

您可以为此使用 BeanShell,但 Groovy、XTend 和 Scala 可能会做出更好的选择。

【讨论】:

  • 嗯,“Groovy 和 Scala 可能会做出更好的选择”,您能详细说明一下吗?
  • 来自我引用的链接:“Groovy 是一种在 Java 虚拟机 (JVM) 上运行的通用脚本语言,在很大程度上可以被视为 Java 的超集。”
  • @paulsm4 是的,现在我打开了那个链接,它似乎就是我想要的。我想知道为什么谷歌没有给我一些线索。不管怎样,我现在就试试看:)谢谢!
【解决方案3】:

答案是“是”,您可以在 Java 程序本身中使用 Java 作为脚本语言。此外,还有其他几种语言也可以用于此目的——Javascript、LUA、Groovy、Ruby,这个列表很长。引入 javax.scripting API 使集成变得更加容易,它标准化并极大地简化了将第三方脚本语言集成到 Java 程序中的过程。我强烈建议您阅读 API 和 Oracles 页面上的一些教程。

http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html

【讨论】:

    【解决方案4】:

    您可以使用 JANINO http://docs.codehaus.org/display/JANINO/Home ...一个轻量级的“嵌入式”JavaTM 编译器,将内存中的简单程序编译成 JavaTM 字节码,该字节码在运行程序的 JVM 中执行... 请看例子http://docs.codehaus.org/display/JANINO/Basic

    或者您可以使用 MVEL http://mvel.codehaus.org/ 它类似于 BeanShell,但速度更快。

    【讨论】:

    【解决方案5】:

    从 7.0 版开始,Java 对运行时编译有了“官方”支持(如果 SDK 中的 tools.jar 在类路径上)。大概,执行速度可以和编译的java一样高,比解释器还高。

    阅读起点(网上很多样例):

    import javax.tools.JavaCompiler;
    import javax.tools.ToolProvider;
    
    
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    if(compiler!=null) {
        .... 
    }
    

    【讨论】:

      【解决方案6】:

      Java 11 支持无需编译即可运行源代码。

      对于包含HelloWorld.java 的文件

      public class HelloWorld {
        public static void main(String[] args) {
          System.out.println("Hello World!!!");
        }
      }
      

      你可以跑

      java HelloWorld.java

      执行代码。有一个限制:必须在同一个文件中定义所有类。

      如果文件没有.java 扩展名,则需要包含--source 选项。

      例如,对于包含您需要运行的源代码的文件 HelloWorld

      java --source 11 HelloWorld.

      要直接在 shell 中运行 java“脚本”,您可以使用

      #!/usr/bin/java --source 11
      
      public class HelloWorld {
        public static void main (String[] args) {
          System.out.println("Hello World")
        }
      }
      

      其中/usr/bin/javajava 二进制文件的路径。

      【讨论】:

        【解决方案7】:

        对于简单的东西,当 groovy 等不可用时,我将 java 嵌入到 bash 脚本中,如项目 java-script-template 中所述。代码如下所示:

        #!/bin/bash
        set -e
        TEMP_DIRECTORY=/tmp
        TEMPFILE=`mktemp $TEMP_DIRECTORY/ScriptXXXXX|sed -e 's/\.//g'`
        CLASS_NAME=`basename "$TEMPFILE"`
        JAVA_SOURCE=$TEMPFILE.java
        cat <<EOF >$JAVA_SOURCE.tmp
        
        //Write your java class here with a main method
        //Be sure to leave the name of the class as Script 
        
        //import some commonly used imports
        import java.io.*;
        import java.text.*;
        import java.util.*;
        
        public class Script {
        
            public static void main(String[] args) throws Exception {
               System.out.println("Here's a test run for you");
            }
        
        }
        
        EOF
        
        ## change the name of the class to match the file
        sed "s/public class Script /public class $CLASS_NAME /g" $JAVA_SOURCE.tmp >$JAVA_SOURCE
        
        ## compile the java
        javac $JAVA_SOURCE 
        
        ## run the class using all passed in parameters from the command line
        java -classpath $TEMP_DIRECTORY $CLASS_NAME
        

        【讨论】:

          【解决方案8】:

          RelProxy 是一个运行中的 Java 编译器(在内存中),它让 Java 感觉像是一种脚本语言,但没有任何限制。它还支持在 Java 环境中使用 Groovy 时对 Groovy 类进行热类重载。

          【讨论】:

            猜你喜欢
            • 2011-09-08
            • 2011-09-22
            • 2010-11-12
            • 2011-04-20
            • 1970-01-01
            • 2020-06-04
            • 1970-01-01
            • 1970-01-01
            • 2014-03-13
            相关资源
            最近更新 更多