我创建了一个包含我所有编译内容的jar文件。此外,我的ant build脚本将所需的libs复制到子文件夹“libs”中。结构如下所示:
MyProgram.jar
libs/
所以当我现在尝试运行我的程序时,我收到以下错误:
java -cp ".:/home/user/java/MyProgram/jar/libs" -jar MyProgram.jar
java.lang.ClassNotFoundException: org.postgresql.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 database.PostgresQL.getConnection(PostgresQL.java:38)
at recommender.dao.Creative2IdxDAO.createCreatives2Idx(Creative2IdxDAO.java:19)
at main.Main.calculateCorrelationMatrix(Main.java:51)
at main.Main.main(Main.java:28)
java.lang.NullPointerException
at recommender.dao.Creative2IdxDAO.createCreatives2Idx(Creative2IdxDAO.java:25)
at main.Main.calculateCorrelationMatrix(Main.java:51)
at main.Main.main(Main.java:28)
为什么会发生这种情况?
这有点棘手。下面的脚本试图从jar的清单中获取类路径,然后允许添加额外的类路径条目。我有混合的结果,但还是想分享脚本,这样它就可以在这里完全发挥作用。
剧本有两个名字
通过将两个文件硬链接在一起
ln calljar showmanifest
使用呼叫 -h,您可以看到用法。
#!/bin/bash
#set -x
# show the manifest of a jar file
# 2012-07-18
# author WF
#
# show usage
#
usage() {
echo "usage: showmanifest (jarfile | directory jarfile) " 1>&2
echo "usage: calljar directory jarfile classpath pattern arguments" 1>&2
echo " -h|--help " 1>&2
echo " show this help and exit" 1>&2
echo " -m|--mainclass javaclass" 1>&2
echo " mainclass to use (otherwise manifest is inspected)" 1>&2
exit 1
}
#
# show the manifest of the given jar file
#
show() {
dir="$1"
jar="$2"
fulljar=`find "$dir" -name "$jar"`
cd /tmp
mkdir show$$
cd show$$
jar xvf $fulljar META-INF/MANIFEST.MF
cat META-INF/MANIFEST.MF
cd /tmp
rm -rf show$$
}
#
# show the classpath of the manifest
#
calljar() {
dir="$1"
jar="$2"
classpath="$3"
pattern="$4"
arguments="$5"
cmd=`show "$dir" "$jar" | awk -v extracp="$classpath" -v dir="$dir" -v pattern="$pattern" -v jar="$jar" -v mainclass="$mainclass" -v args="$arguments" '
/Main-Class: / { if (mainclass=="") mainclass=$2 }
/^Class-Path:/ {
incp=1;
cp=$0;
gsub("Class-Path: ","",cp)
next
}
/^ .*$/ && incp {
line=substr($0,2)
# remove carriage return (if any)
cp=cp line
}
END {
# we do not like carriage returns
gsub("\\r","",cp)
gsub("\\r","",mainclass)
# we do not like blanks ...
gsub(" ","",cp)
gsub(pattern,":"dir"/"pattern,cp)
print "java -cp " extracp cp ":"dir"/"jar " " mainclass " " args
}
'`
#echo $cmd
$cmd
}
# echo $# arguments found: $*
# parse command line options
while true; do
# echo "option $1"
case "$1" in
# options without arguments
-h|--help) usage;;
# for options with required arguments, an additional shift is required
-m|--mainclass) mainclass=$2; shift;;
(--) shift; break;;
(-*) echo "$0: error - unrecognized option $1" 1>&2; usage;;
(*) dir=$1;shift;break;;
esac
shift
done
#echo "argcount=$#"
case $# in
0) dir=`dirname "$dir"`
jar=`basename "$dir"`
show "$dir" "$jar";;
1) jar="$1"
show "$dir" "$jar";;
2) usage;;
3) usage;;
*) jar="$1"; shift;
classpath="$1"; shift;
pattern="$1"; shift;
arguments="$@";
#echo "mainclass=${mainclass}"
#echo "classpath=${classpath}"
#echo calljar "${dir}" "${jar}" "${classpath}" "$pattern" "$arguments"
calljar "$dir" "$jar" "$classpath" "$pattern" "$arguments"
;;
esac
当使用-jar
选项时,将忽略-cp
选项。设置类路径的唯一方法是使用jar中的清单文件。
使用 -cp
选项,将 jar 文件添加到该选项,然后显式调用主类会更容易。
此外,假设< code >/home/user/Java/my program/jar/libs 文件夹包含jar文件(而不是类文件),这将不起作用。您不能指定jar文件的文件夹,但是必须在类路径中单独指定每个jar文件(如果有大量jar,那么编写一个简单的shell脚本来完成这项工作是值得的)。
如果使用-jar
或-cp
,则不能将两者结合起来。如果您想在类路径上放置额外的JAR,那么您应该将它们放在主JAR的清单中,然后使用java-JAR
,或者将完整的类路径(包括主JAR及其依赖项)放在-cp
中,并在命令行上显式地命名主类
java -cp 'MyProgram.jar:libs/*' main.Main
(我使用的是dir/*
语法,它告诉java
命令将所有.jar
文件从特定目录添加到类路径中。请注意,*
必须受到保护,以防止 shell 扩展,这就是我使用单引号的原因。
您提到您正在使用ant,因此对于另一种清单方法,您可以使用Ant的< code >
<manifestclasspath property="myprogram.manifest.classpath" jarfile="MyProgram.jar">
<classpath>
<fileset dir="libs" includes="*.jar" />
</classpath>
</manifestclasspath>
<jar destfile="MyProgram.jar" basedir="classes">
<manifest>
<attribute name="Main-Class" value="main.Main" />
<attribute name="Class-Path" value="${myprogram.manifest.classpath}" />
</manifest>
</jar>
有了这个,java -jar MyProgram.jar
将正常工作,并且还将包括类路径上的所有库
JAR文件。
我创建了一个jar文件,其中包含所有编译的内容。此外,我的ant构建脚本将所需的库复制到子文件夹“libs”中。结构如下所示: 为什么会出现这种情况?
我目前正在尝试使用Apache POI从java中读写excel (xlsx而不是xls)。问题是我不仅需要poi-oo XML jar,还需要依赖关系。我如何创建一个类路径来将所有这些链接在一起? 我目前使用的包括: < li>poi-ooxml-3.10 < li>poi-ooxml-schemas-3.10 < li>dom4j- 1.6.1 < li>xmlbeans-2.3.0 < li
问题内容: 我运行以下命令: MyException在dependency.jar中。我也尝试用-classpath替换-cp。我做错了什么? 问题答案: 如果使用,则将忽略这些选项。如果在类路径上需要额外的jar文件,则应在清单中指定以下内容: (然后,您可以使用来运行程序。)
问题内容: 我创建了一个包含所有已编译内容的jar文件。另外,我的ant构建脚本将所需的库复制到子文件夹“ libs”中。结构如下: 因此,当我现在尝试运行程序时,出现以下错误: 为什么会这样? 问题答案: 你可以使用两种 或者 ,你不能将二者结合起来。如果要将其他JAR放在类路径中,则应将它们放在主JAR的清单中,然后使用,或者将完整的类路径(包括主JAR及其依赖项)放入其中,并在命令行上显式命
问题内容: 您好,我有3个Java文件 我设法使用生成了A和B的.class文件 但是当我对c.java执行相同操作时,出现错误错误:找不到符号b和c 关于如何解决此问题的任何建议? 所有的Java文件都在同一个文件夹中 问题答案: 尝试编译class时,必须具有类并且在类路径中。这使编译器可以验证它们是否存在,找出它们具有哪些方法等。 对包名称和类路径非常敏感。最简单的方法是像这样同时编译这三个
我正在使用maven构建工具。我的意图是将单独的绝对文件夹[例如:C:\test1.jar,C:\test2.jar]中可用的jar文件添加到类路径中。 我可以看到JAR被添加到war中可用的Manifest.mf文件的类路径中,但当war部署时,它由于“java.lang.ClassNotFoundException”[与test1.jar或test2.jar相关]而失败。 这是否意味着在man