Système d'appel () ou IPC :: commandes run3 de Perl ne semblent pas passer la variable d'environnement ($ ENV {JAVA_HOME})

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

  •  26-10-2019
  •  | 
  •  

Question

J'ai été aux prises avec le lancement d'un processus de Java à partir perl. La racine du problème est que le processus java manque la variable d'environnement JAVA_HOME provoquant une ClassNotFoundException.

J'ai commencé en utilisant IPC::Run3 en raison de sa réorientation relativement élégante de STDIN / STDOUT.

En supposant IPC::Run3 utiliserait %ENV, j'ai essayé d'ajouter $ENV{JAVA_HOME}.

Quand cela n'a pas essayé de le faire, je system(). Cela n'a pas fonctionné, donc finalement, je l'ai eu au travail en utilisant system("JAVA_HOME=/path/to/java && /path/to/java_program");

Mon programme de test est ci-dessous. Naturellement je décommenter le bloc approprié pour tester l'invocation appropriée.

#!/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");

Voici la sortie de l'exécution du 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.

Et la sortie du premier système () appel:

    -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.

Enfin, le troisième système call-- le seul qui a travaillé - avec l'ensemble variable d'environnement en ligne:

    -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

Enfin à la question: En plus d'avoir à mettre l'environnement en ligne avec le système () appel, quelle est la bonne façon de passer un environnement var à un IPC :: run3 ou un système () appel?

(Note: sortie% ENV est tronquée à entrées correspondant ... des lignes comme PATH, SHELL, _, etc. pas pertinents à la question omise)

Dans le cas où il est pertinent:

-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
Était-ce utile?

La solution

La racine du problème est que le processus java manque la variable d'environnement JAVA_HOME provoquant une ClassNotFoundException.

RÉVISÉ

Ce n'est pas la racine du problème. En fait, Java lui-même ne nécessite pas JAVA_HOME être ensemble.

La cause immédiate du problème est l'un des éléments suivants:

  • L'enveloppe ne fixe pas de classpath correctement pour l'application que vous essayez d'exécuter.

  • L'emballage en utilisant le mauvais nom de la classe. Le nom de la classe "nutch" est inhabituel et suspect -. Il n'y a pas de nom de package

Il semble probable que la cause réelle est que vous assemblez la liste des arguments de manière incorrecte. Chacun de ces arguments avec un espace intérieur d'eux devrait vraiment être deux arguments; i.e..

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

Je soupçonne que cela a confondu le script wrapper nutch, et a causé d'utiliser la mauvaise classname (entre autres). Lorsque vous passez la commande entière comme une chaîne et laissez la coquille Parse, le problème (naturellement) disparaît.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top