programing tip

Java 클래스 경로 내의 디렉토리에있는 모든 jar 포함

itbloger 2020. 9. 28. 08:24
반응형

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.jarc.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.mfjava -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-PathJAR 매니페스트 헤더 를 사용하는 경우 (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

Ref: http://www.rekk.de/bloggy/2008/add-all-jars-in-a-directory-to-classpath-with-java-se-6-using-wildcards/


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:

  1. javac -cp ".;json.jar" Main.java

  2. 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!

참고URL : https://stackoverflow.com/questions/219585/including-all-the-jars-in-a-directory-within-the-java-classpath

반응형