web-dev-qa-db-fra.com

Problèmes avec Java JDBC (MySQL) pour linux - Le travail Crontab provoque l'échec de la connexion dans le programme Java, mais lorsqu'il est exécuté manuellement, c'est bien

Donc, comme l'indique le titre, j'ai eu un problème avec Crontab et mon programme Java se connectant à une base de données MySQL distante.

Le programme lui-même est assez simple: il se connecte à la base de données, saisit deux tables (utilisateurs et mots de passe), puis l'affecte à une variable temporaire et envoie la sortie de la variable à un script Shell qui crée un nouvel utilisateur avec le répertoire personnel et un mot de passe .

Le programme lui-même fonctionne lorsqu'il est exécuté manuellement, mais lorsque j'essaie d'exécuter le programme via Crontab, il ne parvient pas à se connecter à la base de données. Maintenant, j'ai essayé une variété de choses différentes pour que cela fonctionne, comme assigner la crontab à différentes heures de la journée (nous avons aussi d'autres programmes accédant à la base de données, donc je lui ai assigné une heure où les autres ne l'ont pas fait), mais cela n'a pas fonctionné et m'a juste posé le même problème. J'ai essayé d'exécuter le programme Java directement à partir de crontab, via un script attribué à crontab et via un script qui active le script précédent ... et chaque méthode échoue. (Les scripts s'exécutent, mais à nouveau - aucune connexion DB n'est établie).

J'arrache mes cheveux à ce stade en essayant de comprendre cela ... Cela fonctionne lorsque je l'exécute manuellement, mais échoue lorsque crontab essaie de l'exécuter ... (WTF?)

En outre, Crontab semble fonctionner correctement car il exécute tous les éléments de la liste, mais lorsqu'il arrive à mon programme Java, la connexion n'est jamais établie pour une raison quelconque ...

Donc, si quelqu'un a une idée de ce qui peut se passer ici, j'apprécierais grandement la contribution.


De plus, si quelqu'un peut me dire comment imprimer la sortie d'erreur de la connexion SQL via Java, cela peut m'aider/nous aider à diagnostiquer le problème ...

Merci encore!


Information additionnelle:

Running Ubuntu 4.4.3
Latest version of linux JDK from apt-get
Latest version of linux Java MySQL integration from apt-get
I do *NOT* have MySQL installed locally! everything is remote.

Ligne Crontab utilisée pour exécuter Java program:

  30 14 *  *  * Java -cp $CLASSPATH:/home/user/Java myprogram > /home/user/Java/user_logfile.txt

Classpath:

/usr/share/Java/mysql-connector-Java-5.1.10.jar

Informations mises à jour:

En utilisant les conseils de Jukka sur le printStackTrace, j'ai recherché sur google une méthode pour envoyer le stacktrace à la fonction System.out.println afin que crontab puisse me donner plus précisément un résumé du journal de ce qui se passait. J'ai réussi à trouver:

catch(Exception e)
{
ByteArrayOutputStream file = new ByteArrayOutputStream();
PrintStream stream = new PrintStream(file);
e.printStackTrace(stream);
System.out.println("The result is :"+file.toString().trim());
}

ce qui m'a aidé à trouver ceci:

Error:
Java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
        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)
        at Java.lang.Class.forName0(Native Method)
        at Java.lang.Class.forName(Class.Java:186)
        at prog_users.main(prog_users.Java:24)

Donc, l'erreur principale est que le chemin de classe pour crontab ne peut pas trouver le pilote jdbc!

Maintenant ... comment puis-je changer le CLASSPATH pour un processus qui n'a pas de répertoire personnel ou .rcbash ...?

1
Jason

Solution:

L'allusion de Jukka à propos du StackTrace m'a informé de la solution, donc une bonne majorité du mérite lui revient de m'aider à trouver la solution.


Donc, fondamentalement, je travaillais sur ce problème avec un état d'esprit Windows. J'ai pensé que depuis que j'ai défini le CLASSPATH dans Root (à partir duquel crontab s'exécutait), que le CLASSPATH serait défini. Cependant, pour Linux, ce n'est pas le cas - crontab doit avoir l'ensemble CLASSPATH.

ce qui m'a amené à:

Dans le programme Java, j'ai remplacé le

}catch(Exception e){
    e.printStackTrace();
}

avec

}catch(Exception e){
    ByteArrayOutputStream file = new ByteArrayOutputStream();
    PrintStream stream = new PrintStream(file);
    e.printStackTrace(stream);
    System.out.println("The result is :"+file.toString().trim());
}

afin que mon fichier journal affiche réellement la sortie d'erreur dans le fichier journal lorsqu'il est exécuté à partir de crontab.


Alors, passons à la solution:

Créez un script dans /home/user/Java appelé script1

script1:

#!/bin/bash
export CLASSPATH=/usr/share/Java/mysql-connector-Java-5.1.10.jar
Java -cp $CLASSPATH:/home/user/Java myprogram > /home/user/Java/user_logfile.txt

Puis utilisé Sudo chmod 0755 /home/user/Java/script1 pour le rendre exécutable.

- - - - -

Remplacez ensuite la ligne crontab:

  30 14 *  *  * Java -cp $CLASSPATH:/home/user/Java myprogram > /home/user/Java/user_logfile.txt

avec:

  30 14 *  *  * /home/user/Java/script1
0
Jason

Cron vous enverra par courrier la sortie de toutes les tâches qu'il exécute, alors assurez-vous qu'en cas d'échec, votre programme génère suffisamment d'informations pour que vous puissiez diagnostiquer le problème.

Lorsque votre programme Java échoue, imprimez au moins la trace de la pile d'exceptions dans le flux d'erreur standard et quittez avec un code de sortie non nul:

try {
    // your code here
    // ...
} catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
}

Vérifiez également que la distribution de votre courrier est correctement configurée afin de recevoir les courriers que cron vous envoie.

1
Jukka Matilainen