Java 클래스 경로 내의 디렉토리에있는 모든 jar 포함
클래스 경로의 디렉토리 내에 모든 jar 파일을 포함하는 방법이 있습니까?
나는 노력 java -classpath lib/*.jar:. my.package.Program
하고 있으며 확실히 그 항아리에있는 클래스 파일을 찾을 수 없습니다. 각 jar 파일을 클래스 경로에 별도로 추가해야합니까?
Java 6 이상을 사용하는 경우 classpath 옵션은 와일드 카드를 지원합니다. 다음 사항에 유의하십시오.
- 곧은 따옴표 사용 (
"
) - 사용
*
하지 않고*.jar
윈도우
java -cp "Test.jar;lib/*" my.package.MainClass
유닉스
java -cp "Test.jar:lib/*" my.package.MainClass
이는 윈도우와 유사하지만 사용하는 :
대신 ;
. 와일드 카드를 사용할 수없는 경우 bash
다음 구문을 허용합니다 (여기서는 lib
모든 Java 아카이브 파일이 포함 된 디렉토리).
java -cp $(echo lib/*.jar | tr ' ' ':')
(클래스 경로를 사용하는 것은 -jar
옵션 과 호환되지 않습니다 . 참조 : 명령 프롬프트에서 여러 클래스 경로 라이브러리가있는 jar 파일 실행 )
와일드 카드 이해
로부터 클래스 경로 문서 :
클래스 경로 항목은 기본 이름 와일드 카드 문자를 포함 할 수 있습니다.
*
이는 디렉토리에있는 모든 파일의 목록을.jar
또는 확장자로 지정하는 것과 동일한 것으로 간주됩니다.JAR
. 예를 들어, 클래스 경로 항목foo/*
은 foo라는 디렉토리에있는 모든 JAR 파일을 지정합니다. 단순히로 구성된 클래스 경로 항목*
은 현재 디렉토리의 모든 jar 파일 목록 으로 확장됩니다.포함 된 클래스 경로 항목은
*
클래스 파일과 일치하지 않습니다. 단일 디렉토리 foo에서 클래스와 JAR 파일을 모두 일치 시키려면foo;foo/*
또는을 사용하십시오foo/*;foo
. 선택한 순서에 따라의 클래스와 리소스foo
가의 JAR 파일보다 먼저로드 되는지foo
또는 그 반대의 경우 로드 되는지 결정 됩니다.하위 디렉터리는 재귀 적으로 검색되지 않습니다. 예를 들어,
foo/*
단지에서 JAR 파일을 찾습니다foo
,하지에foo/bar
,foo/baz
등디렉토리의 JAR 파일이 확장 된 클래스 경로에 열거되는 순서는 지정되지 않았으며 플랫폼마다 다를 수 있으며 동일한 시스템에서 순간적으로도 다를 수 있습니다. 잘 구성된 응용 프로그램은 특정 순서에 의존해서는 안됩니다. 특정 순서가 필요한 경우 JAR 파일을 클래스 경로에 명시 적으로 열거 할 수 있습니다.
와일드 카드 확장은 클래스 로딩 프로세스 자체에서 늦지 않고 프로그램의 기본 메서드를 호출하기 전에 일찍 수행됩니다. 와일드 카드를 포함하는 입력 클래스 경로의 각 요소는 명명 된 디렉토리에서 JAR 파일을 열거하여 생성 된 요소의 시퀀스 (비어있을 수 있음)로 대체됩니다. 디렉토리가 예를 들어,
foo
포함a.jar
,b.jar
및c.jar
다음 클래스 패스foo/*
로 확장foo/a.jar;foo/b.jar;foo/c.jar
, 그 캐릭터 라인은 시스템 프로퍼티의 값이 될 것이다java.class.path
.
CLASSPATH
환경 변수에서 어떤 다르게 취급하지 않는-classpath
(또는-cp
) 명령 줄 옵션을 선택합니다. 즉, 이러한 모든 경우에 와일드 카드가 적용됩니다. 그러나 클래스 경로 와일드 카드는Class-Path jar-manifest
헤더 에 적용되지 않습니다 .
참고 : Java 8의 알려진 버그로 인해 Windows 예제는 뒤에 별표가있는 항목 앞에 백 슬래시를 사용해야합니다. https://bugs.openjdk.java.net/browse/JDK-8131329
창에서 작동합니다.
java -cp "Test.jar;lib/*" my.package.MainClass
그리고 이것은 작동하지 않습니다.
java -cp "Test.jar;lib/*.jar" my.package.MainClass
* .jar에주의하십시오. 따라서 * 와일드 카드는 단독으로 사용해야합니다 .
Linux에서는 다음이 작동합니다.
java -cp "Test.jar:lib/*" my.package.MainClass
구분 기호는 세미콜론 대신 콜론입니다.
다른 필수 jar와 함께 클래스 경로를 지정하는 매니페스트 ( ) 파일 이 포함 된 기본 jar 파일 myapp.jar
을 배포하여이 문제를 해결 한 다음 함께 배포합니다. 이 경우 코드를 실행할 때만 선언 하면됩니다.Manifest.mf
java -jar myapp.jar
따라서 메인 jar
을 일부 디렉토리에 배포 한 다음 종속 jar를 그 lib
아래 의 폴더에 넣으면 매니페스트는 다음과 같습니다.
Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar
주의 : 이것은 플랫폼에 독립적입니다. 동일한 jar를 사용하여 UNIX 서버 또는 Windows PC에서 실행할 수 있습니다.
"lib"디렉토리에 모든 jar가있는 java-sun 1.6.0_24를 사용하는 Ubuntu 10.04의 내 솔루션 :
java -cp. : lib / * my.main.Class
이것이 실패하면 다음 명령이 작동합니다 (lib 디렉토리의 모든 * .jars를 classpath 매개 변수로 출력).
java -cp $ (for i in lib / *. jar; do echo -n $ i :; done). my.main.Class
나를 위해 이것은 Windows에서 작동합니다.
java -cp "/lib/*;" sample
Linux의 경우
java -cp "/lib/*:" sample
내가 사용하고 자바 (6)
짧은 답변: java -classpath lib/*:. my.package.Program
오라클은 클래스 경로에 와일드 카드를 사용하여 문서를 제공 여기에 자바 6 과 여기에 자바 7에 대한 제목 섹션에서 이해 클래스 경로 와일드 카드를 . (이 글을 쓰는 동안 두 페이지에 동일한 정보가 포함되어 있습니다.) 다음은 주요 내용 요약입니다.
일반적으로 지정된 디렉토리에 모든 JAR을 포함하려면 와일드 카드
*
( 아님*.jar
)를 사용할 수 있습니다 .와일드 카드는 클래스 파일이 아닌 JAR에만 일치합니다. 디렉토리의 모든 클래스를 가져 오려면 디렉토리 이름에서 클래스 경로 항목을 끝내십시오.
위의 두 옵션을 결합하여 디렉토리의 모든 JAR 및 클래스 파일을 포함 할 수 있으며 일반적인 클래스 경로 우선 순위 규칙이 적용됩니다. 예
-cp /classes;/jars/*
와일드 카드는 하위 디렉토리에서 JAR을 검색 하지 않습니다 .
위의 글 머리 기호는
CLASSPATH
시스템 속성이나-cp
또는-classpath
명령 줄 플래그 를 사용하는 경우 참 입니다. 그러나Class-Path
JAR 매니페스트 헤더 를 사용하는 경우 (ant 빌드 파일에서 수행 할 수있는 것처럼) 와일드 카드가 적용 되지 않습니다 .
예, 내 첫 번째 링크는 최고 점수 답변 (추월 할 희망이 없음)에 제공된 것과 동일하지만 그 답변은 링크를 넘어서는 많은 설명을 제공하지 않습니다. 요즘 Stack Overflow에서는 이런 종류의 동작이 권장되지 않기 때문에 확장 할 것이라고 생각했습니다.
Windows :
java -cp file.jar;dir/* my.app.ClassName
Linux :
java -cp file.jar:dir/* my.app.ClassName
Remind:
- Windows path separator is ;
- Linux path separator is :
- In Windows if cp argument does not contains white space, the "quotes" is optional
You can try java -Djava.ext.dirs=jarDirectory
http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html
Directory for external jars when running java
Correct:
java -classpath "lib/*:." my.package.Program
Incorrect:
java -classpath "lib/a*.jar:." my.package.Program
java -classpath "lib/a*:." my.package.Program
java -classpath "lib/*.jar:." my.package.Program
java -classpath lib/*:. my.package.Program
If you really need to specify all the .jar files dynamically you could use shell scripts, or Apache Ant. There's a commons project called Commons Launcher which basically lets you specify your startup script as an ant build file (if you see what I mean).
Then, you can specify something like:
<path id="base.class.path">
<pathelement path="${resources.dir}"/>
<fileset dir="${extensions.dir}" includes="*.jar" />
<fileset dir="${lib.dir}" includes="*.jar"/>
</path>
In your launch build file, which will launch your application with the correct classpath.
If you are using Java 6, then you can use wildcards in the classpath.
Now it is possible to use wildcards in classpath definition:
javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java -d build/classes
Please note that wildcard expansion is broken for Java 7 on Windows.
Check out this StackOverflow issue for more information.
The workaround is to put a semicolon right after the wildcard. java -cp "somewhere/*;"
To whom it may concern,
I found this strange behaviour on Windows under an MSYS/MinGW shell.
Works:
$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java
Doesn't work:
$ javac -cp 'c:\Programs\COMSOL44\plugins\*' Reclaim.java
javac: invalid flag: c:\Programs\COMSOL44\plugins\com.comsol.aco_1.0.0.jar
Usage: javac <options> <source files>
use -help for a list of possible options
I am quite sure that the wildcard is not expanded by the shell, because e.g.
$ echo './*'
./*
(Tried it with another program too, rather than the built-in echo
, with the same result.)
I believe that it's javac
which is trying to expand it, and it behaves differently whether there is a semicolon in the argument or not. First, it may be trying to expand all arguments that look like paths. And only then it would parse them, with -cp
taking only the following token. (Note that com.comsol.aco_1.0.0.jar
is the second JAR in that directory.) That's all a guess.
This is
$ javac -version
javac 1.7.0
All the above solutions work great if you develop and run the Java application outside any IDE like Eclipse or Netbeans.
If you are on Windows 7 and used Eclipse IDE for Development in Java, you might run into issues if using Command Prompt to run the class files built inside Eclipse.
E.g. Your source code in Eclipse is having the following package hierarchy: edu.sjsu.myapp.Main.java
You have json.jar as an external dependency for the Main.java
When you try running Main.java from within Eclipse, it will run without any issues.
But when you try running this using Command Prompt after compiling Main.java in Eclipse, it will shoot some weird errors saying "ClassNotDef Error blah blah".
I assume you are in the working directory of your source code !!
Use the following syntax to run it from command prompt:
-
javac -cp ".;json.jar" Main.java
-
java -cp ".;json.jar" edu.sjsu.myapp.Main
[Don't miss the . above]
This is because you have placed the Main.java inside the package edu.sjsu.myapp and java.exe will look for the exact pattern.
Hope it helps !!
For windows quotes are required and ; should be used as separator. e.g.:
java -cp "target\\*;target\\dependency\\*" my.package.Main
Short Form: If your main is within a jar, you'll probably need an additional '-jar pathTo/yourJar/YourJarsName.jar ' explicitly declared to get it working (even though 'YourJarsName.jar' was on the classpath) (or, expressed to answer the original question that was asked 5 years ago: you don't need to redeclare each jar explicitly, but does seem, even with java6 you need to redeclare your own jar ...)
Long Form: (I've made this explicit to the point that I hope even interlopers to java can make use of this)
Like many here I'm using eclipse to export jars: (File->Export-->'Runnable JAR File'). There are three options on 'Library handling' eclipse (Juno) offers:
opt1: "Extract required libraries into generated JAR"
opt2: "Package required libraries into generated JAR"
opt3: "Copy required libraries into a sub-folder next to the generated JAR"
Typically I'd use opt2 (and opt1 was definitely breaking), however native code in one of the jars I'm using I discovered breaks with the handy "jarinjar" trick that eclipse leverages when you choose that option. Even after realizing I needed opt3, and then finding this StackOverflow entry, it still took me some time to figure it out how to launch my main outside of eclipse, so here's what worked for me, as it's useful for others...
If you named your jar: "fooBarTheJarFile.jar" and all is set to export to the dir: "/theFully/qualifiedPath/toYourChosenDir".
(meaning the 'Export destination' field will read: '/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar' )
After you hit finish, you'll find eclipse then puts all the libraries into a folder named 'fooBarTheJarFile_lib' within that export directory, giving you something like:
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar01.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar02.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar03.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar04.jar
You can then launch from anywhere on your system with:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(For Java Newbies: 'package.path_to.the_class_with.your_main' is the declared package-path that you'll find at the top of the 'TheClassWithYourMain.java' file that contains the 'main(String[] args){...}' that you wish to run from outside java)
The pitfall to notice: is that having 'fooBarTheJarFile.jar' within the list of jars on your declared classpath is not enough. You need to explicitly declare '-jar', and redeclare the location of that jar.
e.g. this breaks:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain
restated with relative paths:
cd /theFully/qualifiedPath/toYourChosenDir/;
BREAKS: java -cp "fooBarTheJarFile_lib/*" package.path_to.the_class_with.your_main.TheClassWithYourMain
BREAKS: java -cp ".;fooBarTheJarFile_lib/*" package.path_to.the_class_with.your_main.TheClassWithYourMain
BREAKS: java -cp ".;fooBarTheJarFile_lib/*" -jar package.path_to.the_class_with.your_main.TheClassWithYourMain
WORKS: java -cp ".;fooBarTheJarFile_lib/*" -jar fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(using java version "1.6.0_27"; via OpenJDK 64-Bit Server VM on ubuntu 12.04)
The only way I know how is to do it individually, for example:
setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.
Hope that helps!
class from wepapp:
> mvn clean install
> java -cp "webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/tool-jar-1.17.0-SNAPSHOT.jar;webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/*" com.xx.xx.util.EncryptorUtils param1 param2
Not a direct solution to being able to set /* to -cp but I hope you could use the following script to ease the situation a bit for dynamic class-paths and lib directories.
libDir2Scan4jars="../test";cp=""; for j in `ls ${libDir2Scan4jars}/*.jar`; do if [ "$j" != "" ]; then cp=$cp:$j; fi; done; echo $cp| cut -c2-${#cp} > .tmpCP.tmp; export tmpCLASSPATH=`cat .tmpCP.tmp`; if [ "$tmpCLASSPATH" != "" ]; then echo .; echo "classpath set, you can now use ~> java -cp \$tmpCLASSPATH"; echo .; else echo .; echo "Error please check libDir2Scan4jars path"; echo .; fi;
Scripted for Linux, could have a similar one for windows too. If proper directory is provided as input to the "libDir2Scan4jars"; the script will scan all the jars and create a classpath string and export it to a env variable "tmpCLASSPATH".
You need to add them all separately. Alternatively, if you really need to just specify a directory, you can unjar everything into one dir and add that to your classpath. I don't recommend this approach however as you risk bizarre problems in classpath versioning and unmanagability.
Think of a jar file as the root of a directory structure. Yes, you need to add them all separately.
Set the classpath in a way suitable multiple jars and current directory's class files.
CLASSPATH=${ORACLE_HOME}/jdbc/lib/ojdbc6.jar:${ORACLE_HOME}/jdbc/lib/ojdbc14.jar:${ORACLE_HOME}/jdbc/lib/nls_charset12.jar;
CLASSPATH=$CLASSPATH:/export/home/gs806e/tops/jconn2.jar:.;
export CLASSPATH
I have multiple jars in a folder. The below command worked for me in JDK1.8
to include all jars present in the folder. Please note that to include in quotes if you have a space in the classpath
Windows
Compiling: javac -classpath "C:\My Jars\sdk\lib\*" c:\programs\MyProgram.java
Running: java -classpath "C:\My Jars\sdk\lib\*;c:\programs" MyProgram
Linux
Compiling: javac -classpath "/home/guestuser/My Jars/sdk/lib/*" MyProgram.java
Running: java -classpath "/home/guestuser/My Jars/sdk/lib/*:/home/guestuser/programs" MyProgram
I am trying to run Java file either as jar or as classes in Ubuntu. I failed in both options. The following exception is its output.
Download link: https://upload.cat/f694139f88c663b1
java org.statmetrics.Statmetric
or
java -cp /home/elias/statmetrics/statmetrics.jar:. org.statmetrics.Statmetrics
or
java -classpath "/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/*" -jar /home/elias/statmeics/statmetrics.jar org.statmetrics.Statmetrics
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/adapters/XmlAdapter
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at org.statmetrics.c.a(Unknown Source)
at org.statmetrics.dw.a(Unknown Source)
at org.statmetrics.dx.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.adapters.XmlAdapter
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 12 more
I found the answer:
My stupidity.
First step: You must set the corresponding Java: I had Java 11 but I set as Java lib path the 8th version! - You can do set the Java version from here:
sudo update-alternatives --config java
2nd step: Then run the following command, by changing path and file names to your corresponding path and files:
java -classpath "/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/*" -jar /home/elias/statmetrics/statmetrics.jar org.statmetrics.Statmetrics
It was run succesfully!
'programing tip' 카테고리의 다른 글
'ArrayList 변환 (0) | 2020.09.28 |
---|---|
grep을 사용하여 Linux에서 파일 이름 만 표시하려면 어떻게해야합니까? (0) | 2020.09.28 |
동시성과 병렬성의 차이점은 무엇입니까? (0) | 2020.09.28 |
인라인 CSS에서 a : hover를 작성하는 방법은 무엇입니까? (0) | 2020.09.28 |
왼쪽에 0이있는 정수를 어떻게 채울 수 있습니까? (0) | 2020.09.28 |