如何在Ubuntu上使用Apache Commons Java库?

4

我是一名Java初学者,正在努力弄清如何使用Apache Commons库。

这里有一个源文件Randstr.java

import org.apache.commons.lang3.RandomStringUtils;

class Randstr {
    public static void main(String[] args) {
        String s = RandomStringUtils.random(12);
        System.out.println(s);
    }
}

我在 /usr/share/java/ 目录下有 commons-lang3-3.1.jar 文件,并已在当前目录中创建了符号链接。然后我像这样编译它:javac -cp commons-lang3-3.1.jar Randstr.java,编译通过了,但当我执行 java Randstr 时,出现了以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/RandomStringUtils
        at Randstr.main(Randstr.java:5)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.RandomStringUtils
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more

如果我在类路径中没有指定jar文件,甚至无法编译:

javac -cp . Randstr.java

# Randstr.java:1: error: package org.apache.commons.lang3 does not exist
# import org.apache.commons.lang3.RandomStringUtils;
#                                ^
# Randstr.java:5: error: cannot find symbol
#         String s = RandomStringUtils.random(12);
#                    ^
#   symbol:   variable RandomStringUtils
#   location: class Randstr
# 2 errors

javac -cp /usr/share/java/  Randstr.java

# Randstr.java:1: error: package org.apache.commons.lang3 does not exist
# import org.apache.commons.lang3.RandomStringUtils;
#                                ^
# Randstr.java:5: error: cannot find symbol
#         String s = RandomStringUtils.random(12);
#                    ^
#   symbol:   variable RandomStringUtils
#   location: class Randstr
# 2 errors

从阅读stackoverflow上的其他问题,我发现这可以通过使用IDE来解决,但目前我更喜欢一个简单的编辑器。


这看起来是一个好问题。原帖作者做错了什么? - Cole Tobin
@Cole"Cole9"Johnson 全局安装 Java 库对于初学者来说可能并不是最好的选择(当然,这并不完全正确)。在学习 Maven 之前拒绝使用能够协助管理库的 IDE 应该会更加重要。 - millimoose
1
@Cole"Cole9"Johnson,我刚意识到你在询问我没有投票的关闭投票。我认为询问关闭或者踩票的意义不大——那个人不想就此展开对话,很可能已经投了票并离开了。如果他们真的有话要说,早就会写评论了。 - millimoose
3个回答

3

如果您可以使用编译器进行编译

javac -cp commons-lang3-3.1.jar Randstr.java

那么您可以使用以下方式运行它:
java -cp commons-lang3-3.1.jar:. Randstr

JAR文件必须在类路径中。

仍然没有运气,java -cp commons-lang3-3.1.jar Randstr 错误:找不到或加载主类Randstr - qed
将当前目录添加到类路径中。 - Plínio Pantaleão
@PlínioPantaleão 当前工作目录始终在类路径上。 - millimoose
1
@millimoose - 默认情况下,工作目录在类路径上,一旦你开始操作类路径,就应该将其包含进去。 - Chase
@CravingSpirit 尽管在实践中,你最终会使用高级的处理方式,因此从另一个角度来看,你正在避免学习它们。无论哪种方式,我的答案都链接到有关此概念文档的更多背景信息。 - millimoose
显示剩余2条评论

1

编辑你的个人配置文件。vim ~/.bashrc

在你的个人配置文件中添加以下行:

export CLASSPATH=/usr/share/java/commons-lang3-3.1.jar:.

退出并重新登录。或在您打开的窗口中源代码文件。您始终可以将类路径添加到每个Java和javac命令中,但这会变得痛苦。使用CLASSPATH环境变量,您无需再在命令行上添加它了。请注意,如果您正在使用NetBeans或Eclipse等IDE,则仍然可能需要将库添加到项目的IDE库中。


设置CLASSPATH不是推荐的做法。 - millimoose
我不建议更改系统级别的类路径,而是用户特定的路径?对于像commons这样的库和想要手动构建的开发人员来说,这是推荐此做法的少数几个时候之一。 - Chase
它并不是积极的坏事,但它只是一个权宜之计。我的意思是,迟早你会不得不学习如何制作独立的项目,所以我建议你最好现在就开始学习。 (见鬼,整个编程语言社区花了数年才意识到他们必须支持这一点。) - millimoose

0

显然,/usr/share/java/ 的内容不会自动添加到类路径中 - 这只是APT软件包放置Java库的常见位置。开发人员需要正确引用它们。

Java安装的ext/子目录中的JAR文件会自动添加到类路径中。但是,请不要将自己的JAR文件放在那里。这是一种可怕的做法,因为它与Java应用程序在“现实世界”中的部署方式不匹配。

正确的方法是在编译和运行应用程序时明确使用-cp参数。Java不会将库代码编译到您的.class文件中,.class文件仅引用其他类的名称,这些类在应用程序运行时从类路径中按需加载。 -cp参数仅接受.jar文件或其中包含.class文件的目录。您还可以在该参数的值中使用通配符。有关管理类路径的更多信息,请查看设置类路径的工具文档

你可以使用自动设置构建工具,例如IDE或Maven或其他带有依赖管理的构建系统(GradleAnt+Ivy)。如果你正在编写使用第三方库的Java应用程序,我强烈建议你学习并使用其中之一。(此外,大多数IDE都可以使用Maven的配置文件,让你在与使用混合或没有IDE的人一起工作时使用相同的构建设置。)通常,如果你直接调用编译器,那么你就不是在正确地做事。


但他创建了一个符号链接,将jar文件放在与源代码相同的文件夹中。 - jsedano
@anakata 那又怎样?如果你在类路径上没有指定它,那么JAR在哪里都无所谓。我编辑了我的答案以强调现在运行应用程序时需要这样做。 - millimoose
但他正在做这件事,不是吗?javac -cp commons-lang3-3.1.jar Randstr.java - jsedano
@anakata 在编译时,“编译通过”表示编译成功。但是,如果在命令行中运行java Randstr时没有必要的-cp,则应用程序将崩溃。 - millimoose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接