我一直在利用Perl啓動Java進程中掙扎。該問題的根源在於,java程序缺少JAVA_HOME
環境變量引起ClassNotFoundException
。
我開始用IPC::Run3
,因爲它的標準輸入/輸出的相對優雅的重定向。
假設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");
這裏的運行RUN3的輸出:
-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.
最後,第三個系統call--唯一一個工作 - 與環境變量設置在線:
-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
最後一個問題:除了有設置在線環境與系統()調用,什麼對環境無功傳遞給IPC :: RUN3或系統的正確方法()調用?
(注:%ENV的輸出被截斷,只相關的行......行像PATH,SHELL,_等不相關的省略問題)
在情況下,它是相關的:
-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
只需設置%ENV即可。你得到什麼:'perl -e'die if $ ENV {FOO_BAR}; $ ENV {FOO_BAR} =「/usr/lib/jvm/java-1.6.0」;系統(q {echo - $ FOO_BAR - });''。 (「this is perl,v5.8.9 built for i686-linux-thread-multi」。將安裝5.8.8) – ikegami 2012-02-16 22:11:51
順便說一句,'system(「JAVA_HOME =/path/to/java &&/path/to/java_program 「);'可以簡化爲'system(」JAVA_HOME =/path/to/java/path/to/java_program「);' – ikegami 2012-02-16 22:22:14
我的簡化版本也適用於爲i686-linux-thread-multi構建的v5.8.8。 – ikegami 2012-02-16 22:33:50