comandi IPC :: Run3 da perl di sistema () o chiamando non sembrano passare variabile d'ambiente ($ ENV {} JAVA_HOME)
Domanda
mi è stato alle prese con il lancio di un processo Java da Perl. La radice del problema è che il processo java manca la variabile di ambiente JAVA_HOME
causando un ClassNotFoundException
.
Ho iniziato utilizzando IPC::Run3
a causa della sua relativamente elegante reindirizzamento STDIN / STDOUT.
Supponendo IPC::Run3
userebbe %ENV
, ho provato ad aggiungere $ENV{JAVA_HOME}
.
Quando ciò non ha funzionato Ho provato a fare system()
. Che non ha funzionato, così alla fine, ho preso a lavorare con system("JAVA_HOME=/path/to/java && /path/to/java_program");
Il mio programma di test è al di sotto. Naturalmente mi piacerebbe Decommentare il blocco corretto per testare l'invocazione appropriata.
#!/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");
Ecco l'output di eseguire il 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.
E l'uscita della chiamata primo sistema ():
-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.
Infine, il terzo sistema: quando si fa l'unico che ha lavorato - con la linea impostata variabile d'ambiente:
-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
Infine alla domanda: Oltre ad avere per impostare l'ambiente in linea con la chiamata di sistema (), qual è il modo appropriato per passare un ambiente var ad un IPC :: Run3 oppure a) chiamata (sistema?
(Nota: l'uscita del% ENV viene troncato a solo linee rilevanti ... linee come PATH, SHELL, _, ecc non pertinente alla questione omesso)
Nel caso in cui sia rilevante:
-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
Soluzione
La radice del problema è che il processo java manca la variabile di ambiente JAVA_HOME causando un ClassNotFoundException.
REVISIONE
Questa non è la radice del problema. In realtà, Java stesso non richiede JAVA_HOME da impostare.
La causa immediata del problema è una delle seguenti:
-
Il wrapper non è l'impostazione della classpath in modo corretto per l'applicazione che si sta tentando di eseguire.
-
Il wrapper utilizzando il nome della classe sbagliata. Il nome della classe "nutch" è insolito e sospettoso -. Non c'è nessun nome di pacchetto
E 'probabile che la causa vera radice è che si sta assemblando la lista degli argomenti in modo non corretto. Ognuno di questi argomenti con uno spazio al loro interno in realtà dovrebbe essere due argomenti; cioè.
my @nutch_command = ("$Config{nutch_binary}",
"crawl", "$Config{nutch_seed_dir}",
"-solr", "$Config{solr_url}",
"-d", "$Config{nutch_crawl_dir}",
"-threads", "1",
"-depth", "1");
ho il sospetto che questo ha confuso lo script wrapper nutch, e ha causato in modo da utilizzare il nome di classe sbagliata (tra le altre cose). Quando si passa l'intero comando come una stringa e lasciare che il guscio di analizzarlo, il problema (naturalmente) va via.