![Linux 版 Java 的 JDBC(MySQL)问题 - Crontab 作业导致 Java 程序连接失败,但手动运行时则没问题](https://linux22.com/image/1092849/Linux%20%E7%89%88%20Java%20%E7%9A%84%20JDBC%EF%BC%88MySQL%EF%BC%89%E9%97%AE%E9%A2%98%20-%20Crontab%20%E4%BD%9C%E4%B8%9A%E5%AF%BC%E8%87%B4%20Java%20%E7%A8%8B%E5%BA%8F%E8%BF%9E%E6%8E%A5%E5%A4%B1%E8%B4%A5%EF%BC%8C%E4%BD%86%E6%89%8B%E5%8A%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E5%88%99%E6%B2%A1%E9%97%AE%E9%A2%98.png)
正如标题所述,我在使用 Crontab 和 Java 程序连接远程 MySQL 数据库时遇到了问题。
该程序本身非常简单:它连接到数据库,获取两个表(用户和密码),然后将其分配给一个临时变量并将变量输出推送到创建具有主目录和密码的新用户的 shell 脚本。
程序本身在手动运行时可以运行,但是当我尝试通过 Crontab 运行程序时,它无法连接到数据库。现在,我尝试了各种不同的方法来使其工作,例如将 crontab 分配给一天中的不同时间(我们还有其他程序访问数据库,因此我为它分配了一个其他程序没有的时间),但这些方法不起作用,只是给我带来了同样的问题。我尝试过直接从 crontab 运行 Java 程序,通过分配给 crontab 的脚本,以及通过激活前一个脚本的脚本……但每种方法都失败了。(脚本运行,但同样 - 没有建立数据库连接)。
我现在正绞尽脑汁试图弄清楚这一点...当我手动运行它时它可以工作,但是当 crontab 尝试运行它时却失败了......(WTF?)
此外,Crontab 似乎运行良好,因为它执行了列表中的所有项目,但是当它到达我的 Java 程序时,由于某种原因从未建立连接......
因此,如果有人知道这里可能发生的事情,我将非常感激您的意见。
此外,如果有人能告诉我如何通过 Java 打印 SQL 连接的错误输出,它可能会帮助我/我们诊断问题......
再次感谢!
附加信息:
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.
用于执行 java 程序的 Crontab 行:
30 14 * * * java -cp $CLASSPATH:/home/user/java myprogram > /home/user/java/user_logfile.txt
类路径:
/usr/share/java/mysql-connector-java-5.1.10.jar
更新信息:
根据 Jukka 关于 printStackTrace 的建议,我在 Google 上查找了一种方法,将堆栈跟踪发送到 System.out.println 函数,以便 crontab 可以更准确地为我提供正在发生的事情的日志摘要。我设法找到了:
catch(Exception e)
{
ByteArrayOutputStream file = new ByteArrayOutputStream();
PrintStream stream = new PrintStream(file);
e.printStackTrace(stream);
System.out.println("The result is :"+file.toString().trim());
}
这帮助我找到了这个:
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)
因此主要错误是 crontab 的类路径找不到 jdbc 驱动程序!
现在...我该如何更改没有主目录或 .rcbash 的进程的 CLASSPATH……?
答案1
Cron 会将其运行的所有作业的输出通过电子邮件发送给您,因此请确保在失败时程序输出足够的信息,以便您诊断问题。
当您的 Java 程序失败时,至少将异常堆栈跟踪打印到标准错误流并以非零退出代码退出:
try {
// your code here
// ...
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
另外,请检查您的邮件传递是否设置正确,以便您能收到 cron 发送的邮件。
答案2
解决方案:
Jukka 关于 StackTrace 的提示让我找到了解决方案,因此大部分功劳都归功于他帮助我找到了解决方案。
所以基本上,我是在 Windows 的框架下处理这个问题的。我认为,由于我CLASSPATH
在 Root 中设置了 (crontab 从中运行),所以CLASSPATH
应该被定义。但是,对于 Linux 来说情况并非如此 - crontab 需要设置CLASSPATH
。
这让我想到:
在 Java 程序中,我替换了
}catch(Exception e){
e.printStackTrace();
}
和
}catch(Exception e){
ByteArrayOutputStream file = new ByteArrayOutputStream();
PrintStream stream = new PrintStream(file);
e.printStackTrace(stream);
System.out.println("The result is :"+file.toString().trim());
}
这样,当从 crontab 运行时,我的日志文件实际上会在日志文件中显示错误输出。
那么,继续解决方案吧:
/home/user/java
创建一个名为的脚本script1
脚本1:
#!/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
然后用来sudo chmod 0755 /home/user/java/script1
使其可执行。
-- -- -- -- --
然后替换 crontab 行:
30 14 * * * java -cp $CLASSPATH:/home/user/java myprogram > /home/user/java/user_logfile.txt
和:
30 14 * * * /home/user/java/script1