System()またはIPC :: run3 Perlからのrun3コマンドは、環境変数を通過しないようです($ env {java_home})

StackOverflow https://stackoverflow.com/questions/9319745

  •  26-10-2019
  •  | 
  •  

質問

私はPerlからJavaプロセスを開始することに苦労しています。問題の根本は、Javaプロセスが欠落していることです JAVA_HOME aを引き起こす環境変数 ClassNotFoundException.

使用することから始めました IPC::Run3 Stdin/Stdoutの比較的エレガントなリダイレクトのため。

仮定します IPC::Run3 使用するだろう %ENV, 、追加してみました $ENV{JAVA_HOME}.

それがうまくいかなかったとき、私はやってみました system(). 。それはうまくいかなかったので、最後に、私はそれを使って動作させました system("JAVA_HOME=/path/to/java && /path/to/java_program");

私のテストプログラムは以下にあります。当然、適切な呼び出しをテストするための適切なブロックを除外します。

#!/usr/bin/perl -w
use strict;

use IPC::Run3;

use vars qw(%Config $nutch_stdout $nutch_stderr);

%Config = (
  'nutch_binary'       => q[/home/crawl/nutch/runtime/local/bin/nutch],
  'nutch_crawl_dir'    => q[/home/crawl/nutch-crawl/crawl/crawldb/current/part-00000],
  'nutch_seed_dir'     => q[/home/crawl/urls],
  'solr_url'           => q[http://localhost:8080/solr],
);

my @nutch_command = ("$Config{nutch_binary}",
                 "crawl $Config{nutch_seed_dir}",
                 "-solr $Config{solr_url}",
                 "-d    $Config{nutch_crawl_dir}",
                 "-threads 1",
                 "-depth 1");

$ENV{JAVA_HOME}       = '/usr/lib/jvm/java-1.6.0';

while ((my $key,my $value) = each %ENV) {
    print "$key=$value\n";
}

print "Running @nutch_command\n";

# My original code. Next few lines are shown in first batch of output below.
#run3 \@nutch_command, undef, \$nutch_stdout, \$nutch_stderr;
#print "Output from Nutch:\n";
#print $nutch_stdout;
#print "Errors from Nutch:\n";
#print $nutch_stderr;

# Second try. The next line's output is the second batch of output.
#system(@nutch_command);

# Third try. Despite setting and displaying %ENV, this is the only thing I tried that worked
system("JAVA_HOME=/usr/lib/jvm/java-1.6.0 && @nutch_command");

これがRun the Run3の出力です3:

    -bash-3.2$ ./test.pl 
    ... [snip] ...
    JAVA_HOME=/usr/lib/jvm/java-1.6.0
    ... [snip] ...
    Running /home/crawl/nutch/runtime/local/bin/nutch crawl /home/crawl/urls -solr http://localhost:8080/solr -d    /home/crawl/nutch-crawl/crawl/crawldb/current/part-00000 -threads 1 -depth 1
    Output from Nutch:
    Errors from Nutch:
    Exception in thread "main" java.lang.NoClassDefFoundError: crawl
    Caused by: java.lang.ClassNotFoundException: crawl
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    Could not find the main class: crawl. Program will exit.

最初のシステム()呼び出しの出力:

    -bash-3.2$ ./test.pl
    ... [snip] ...
    JAVA_HOME=/usr/lib/jvm/java-1.6.0
    ... [snip] ...
    Running /home/crawl/nutch/runtime/local/bin/nutch crawl /home/crawl/urls -solr http://localhost:8080/solr -d    /home/crawl/nutch-crawl/crawl/crawldb/current/part-00000 -threads 1 -depth 1
    Exception in thread "main" java.lang.NoClassDefFoundError: crawl
    Caused by: java.lang.ClassNotFoundException: crawl
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    Could not find the main class: crawl. Program will exit.

最後に、3番目のシステム呼び出し - 機能した唯一のシステム! - 環境変数がインラインに設定されています。

    -bash-3.2$ ./test.pl
    ... [snip] ...
    JAVA_HOME=/usr/lib/jvm/java-1.6.0
    ... [snip] ...
    Running /home/crawl/nutch/runtime/local/bin/nutch crawl /home/crawl/urls -solr http://localhost:8080/solr -d    /home/crawl/nutch-crawl/crawl/crawldb/current/part-00000 -threads 1 -depth 1
    crawl started in: crawl-20120216133832
    ... continue success stdout output

最後に質問:System()呼び出しで環境をインラインで設定することは別として、環境VARをIPC :: run3またはSystem()呼び出しに渡す適切な方法は何ですか?

(注:%envの出力は、関連する行のみに切り捨てられます...パス、シェル、_などの線は省略されていません。

関連性がある場合:

-bash-3.2$ uname -a
Linux hostname 2.6.18-238.el5xen #1 SMP Thu Jan 13 16:41:45 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
-bash-3.2$ perl --version
This is perl, v5.8.8 built for x86_64-linux-thread-multi
役に立ちましたか?

解決

問題の根本は、JavaプロセスにJava_home環境変数が欠落しているため、ClassNotFoundExceptionを引き起こしていることです。

改訂

それは問題の根本ではありません。実際には、 Java自体 Java_homeを設定する必要はありません。

問題の当面の原因は、次のいずれかです。

  • ラッパーは設定していません classpath あなたが実行しようとしているアプリケーションのために正しく。

  • 間違ったクラス名を使用したラッパー。クラス名「Nutch」は珍しくて疑わしいです - パッケージ名はありません。

本当の根本的な原因は、引数リストを誤って組み立てていることです。それらの中にスペースを持つこれらの議論のそれぞれは、本当に2つの議論でなければなりません。すなわち

        my @nutch_command = ("$Config{nutch_binary}",
             "crawl", "$Config{nutch_seed_dir}",
             "-solr", "$Config{solr_url}",
             "-d", "$Config{nutch_crawl_dir}",
             "-threads", "1",
             "-depth", "1");

これにより、Nutchラッパースクリプトが混乱し、間違ったクラス名を使用したと思われます(とりわけ)。コマンド全体を1つの文字列として渡してシェルを解析させると、問題は(当然)消えます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top