7

CommonJSをJava7とRhino1.7R3で動作させるためのサポートが必要です。

Rhino 1.7R3は、CommonJSモジュールをサポートしています。

また、Java7にはRhino1.7R3がバンドルされています。org.mozilla.javascript.commonjs残念ながら、Java 7のRhinoは変更されたバージョンであり、次のパッケージは含まれていません。

javax.script次のように、APIを介してRhino1.7R3のCommonJSのサポートを使用したいと思います。

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
engine.put("markdown", markdown);
engine.eval("var html = require('./Markdown.Sanitizer').getSanitizingConverter().makeHtml(markdown);");
return (String) engine.get("html");

ScriptEngineManager実際にRhino 1.7R3エンジンを使用していることを確認しました。)おそらく、クラスパスに次の依存関係を追加するだけでよいと思いました。

<dependency>
    <groupId>org.mozilla</groupId>
    <artifactId>rhino</artifactId>
    <version>1.7R3</version>
</dependency>

CommonJS(具体的には)がrequire()機能し始めます。しかし、そうではありません。使おうとするrequire()

Caused by: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "require" is not defined. (<Unknown source>#2)
    at sun.org.mozilla.javascript.internal.ScriptRuntime.constructError(ScriptRuntime.java:3773)
    at sun.org.mozilla.javascript.internal.ScriptRuntime.constructError(ScriptRuntime.java:3751)
    at sun.org.mozilla.javascript.internal.ScriptRuntime.notFoundError(ScriptRuntime.java:3836)

CommonJSサポートを利用できるようにJava7をRhino1.7R3のフルバージョンで動作させるにはどうすればよいですか?

編集:私はまったく同じトピックを扱っている次の質問を見つけました:

健全性チェック:Rhinoにはrequire関数がありませんよね?

回答者は、限定されたRhino1.7R3をCommonJSRhino 1.7R3に置き換えることは可能かもしれないと示唆していますが、それをどのように行うかについては述べていません。それが私がここで求めていることです。

4

3 に答える 3

11

編集:結局、JVMブートストラップクラスローダーを使用する必要はないようです。SunはデフォルトのRhino実装クラスを

sun.org.mozilla.javascript.*

パッケージ。ただし、ロードされたRhino実装は占有します

org.mozilla.javascript.*

したがって、それらは衝突するべきではありません。ただし、問題が発生した場合は、ブートストラップクラスローダーを使用してJDKのクラスをオーバーライドできます。2つのオプションがあります。

基本的に、Rhinoクラスが組み込みクラスではなく優先されるように、クラスパスをオーバーライドする必要があります。

  1. rhino-1.7R3.jarをyour-JRE-path\lib\extに配置するだけです。このようにして、RhinojarはJavaBootsrapクラスローダーに追加され、組み込みのJavaScriptjarの前にロードされます。
  2. または、.. / lib / extにアクセスできない場合は、コマンドラインオプションを使用できます。

    -Xbootclasspath/a:path/to/rhino-1.7R3.jar
    

Rhino自体はJavaScriptingAPIを実装していません。RhinoをJDKに統合するために、Sunは独自のScriptEngineとを実装していましたScriptEngineFactory。したがって、独自のrhino-1.7R3.jarスクリプトをロードする場合、スクリプトをロードするとCommonJSを使用できなくなります。

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");

代わりに、2つのオプションがあります。

  1. Rhino APIの上に、独自のクラスやその他の関連クラスをScriptEngine実装します。Oracleが どのようにそれを行うかをご覧ください。ただし、JDKソースはGPL 2ライセンスに基づいているため、Rhino用のカスタムスクリプトエンジンラッパーをリリースするか、これらのクラスのみを参照として使用し、コードをコピーしないでください。ScriptEngineFactory

  2. RhinoAPIを直接使用しますこのアプローチを強くお勧めします。 MozillaのWebサイトにはドキュメントと例がありますが、基本的なAPIは比較的単純です。

    // Execution environment for Rhino
    // there should be only one context in a giver thread
    Context cx = Context.enter();
    // Object.prototype, Function prototype, etc.
    Scriptable scope = cx.initStandardObjects();
    
    // Execute script from a given java.io.Reader
    Object result = cx.evaluateReader(scope, reader, 0, null);
    // If returning result isn't sufficient for your needs
    // you can do something like this:
    Object someVar = scope.get("someVar");
    
    // Don't forget to close the context when you're done
    Context.exit();
    

または、JSのみのソリューションをいくつか提供することもできます。

  1. Browserifyを見てください。これは、ソースコードを単一のバンドルに結合するJavaScriptプリプロセッサです。
  2. AMDまたはUMDのいずれかを使用するようにモジュールを書き直してから、 r.jsツールと組み合わせます。

どちらのオプションでも、ビルドプロセスにjs前処理ステップを追加する必要があり、コードのデバッグが少し難しくなる可能性があります。

于 2012-06-18T10:02:09.197 に答える
2

この質問は古いものですが、Googleからここに来る人のために、次の方法でRhinoでCommonJSサポートをセットアップできます(以下は1つの方法にすぎません)。

(JavaのScripting APIを使用せずに、Rhinoを直接呼び出しています)

List<URI> paths = Arrays.asList(new URI[] { new File("js/require/paths/here").toURI() });
Context ctx = Context.enter();
Scriptable scope = ctx.initStandardObjects();

new RequireBuilder()
    .setModuleScriptProvider(new SoftCachingModuleScriptProvider(
        new UrlModuleSourceProvider(paths, null)))
    .setSandboxed(true)
    .createRequire(ctx, scope)
    .install(scope);

//
// now you can ctx.evaluateString(...) and use require()
//

Context.exit();

これで、2つのファイルが作成される可能性があります。

main.js

require('require-test.js')()

require-test.js

module.exports = function() {
    java.lang.System.out.println('The CommonJS require function works!')
}
于 2015-05-20T16:28:07.693 に答える
0

Gradleビルドシステムを使用する場合。この依存関係をプロジェクトのgradleファイルに追加することで、この問題を正常に修正しました。(ここに基づく)

compile group: 'org.mozilla', name: 'rhino', version: '1.7.10'

また、Javaクラスファイルでインポートされたパッケージ名をからに置き換える必要がありsun.org.mozilla.javascript.internalます。org.mozilla.javascript

// import sun.org.mozilla.javascript.internal.NativeObject; // <=== Do not use this package.
import org.mozilla.javascript.NativeObject;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

そして、すべてが正常に動作します。

于 2018-11-28T05:37:29.913 に答える