जार फ़ाइल के अंदर कक्षाओं के नाम कैसे प्राप्त करें?


112

मेरे पास एक JAR फ़ाइल है और मुझे इस JAR फ़ाइल के अंदर सभी वर्गों का नाम प्राप्त करने की आवश्यकता है। मैं उसे कैसे कर सकता हूँ?

मैंने इसे googled और JarFile या Java के बारे में कुछ देखा, ClassLoaderलेकिन मुझे नहीं पता कि इसे कैसे करना है।


क्या आप कुछ आईडीई का उपयोग कर रहे हैं? क्योंकि यदि आप एक का उपयोग कर रहे हैं तो यह ऑटो प्रदर्शित होगा।
जॉय रोहन

मैं ग्रहण का उपयोग कर रहा हूं, लेकिन मुझे कोड के साथ ऐसा करने की आवश्यकता है।
sticksu

@LuiggiMendoza - संभावित डुप्लिकेट में उदाहरणों के साथ-साथ प्रलेखन के लिए संसाधन भी हैं। उन वर्ग नामों में से एक के लिए खोज + उदाहरण कई उपयोगी परिणाम प्राप्त करेंगे।
ऐय्यास

@ एलियास संभव डुप्लिकेट बताता है कि जार से फ़ाइल कैसे ढूंढें और प्राप्त करें, जबकि सवाल एक जार के अंदर वर्ग नाम (संभवतः इसके अंदर सभी पैकेजों में कक्षाएं) प्राप्त करने के बारे में है। ErikKaju के उत्तर का लिंक एक संभावित समाधान का उपयोग करके इंगित करता है JarInputStreamऔर JarEntryकक्षाएं जिन्हें मैं आपके संदर्भित लिंक के किसी भी उत्तर में नहीं पा सकता हूं।
लुइगी मेंडोज़ा

जवाबों:


68

दुर्भाग्य से, जावा "देशी" JRE में कक्षाएं सूचीबद्ध करने का एक आसान तरीका प्रदान नहीं करता है। यह आपको कुछ विकल्पों के साथ छोड़ देता है: (ए) किसी भी दिए गए JAR फ़ाइल के लिए, आप उस JAR फ़ाइल के अंदर की प्रविष्टियों को सूचीबद्ध कर सकते हैं, .classफ़ाइलों को ढूँढ सकते हैं, और फिर निर्धारित कर सकते हैं कि कौन-सी जावा क्लास प्रत्येक .classफ़ाइल का प्रतिनिधित्व करती है; या (बी) आप एक पुस्तकालय का उपयोग कर सकते हैं जो आपके लिए ऐसा करता है।

विकल्प (ए): मैन्युअल रूप से जार फ़ाइलों को स्कैन करना

इस विकल्प में, हम classNamesएक जार फ़ाइल के अंदर निहित सभी जावा वर्गों की सूची से भरेंगे /path/to/jar/file.jar

List<String> classNames = new ArrayList<String>();
ZipInputStream zip = new ZipInputStream(new FileInputStream("/path/to/jar/file.jar"));
for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
    if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
        // This ZipEntry represents a class. Now, what class does it represent?
        String className = entry.getName().replace('/', '.'); // including ".class"
        classNames.add(className.substring(0, className.length() - ".class".length()));
    }
}

विकल्प (बी): विशेष प्रतिबिंब पुस्तकालयों का उपयोग करना

अमरूद

अमरूदClassPath कम से कम 14.0 से पड़ा है , जिसे मैंने इस्तेमाल किया है और पसंद किया है। इसके बारे ClassPathमें एक अच्छी बात यह है कि यह उन कक्षाओं को लोड नहीं करता है जो इसे पाता है, जो तब महत्वपूर्ण होता है जब आप बड़ी संख्या में कक्षाओं के लिए स्कैन कर रहे होते हैं।

ClassPath cp=ClassPath.from(Thread.currentThread().getContextClassLoader());
for(ClassPath.ClassInfo info : cp.getTopLevelClassesRecurusive("my.package.name")) {
    // Do stuff with classes here...
}

कुछ विचार

मैंने व्यक्तिगत रूप से रिफ्लेक्शंस लाइब्रेरी का उपयोग नहीं किया है , लेकिन यह अच्छी तरह से पसंद किया गया है। वेबसाइट पर कुछ बेहतरीन उदाहरण दिए गए हैं जैसे कि किसी भी JAR फ़ाइल द्वारा दिए गए पैकेज में सभी कक्षाओं को लोड करने का यह त्वरित तरीका , जो आपके आवेदन के लिए भी उपयोगी हो सकता है।

Reflections reflections = new Reflections("my.project.prefix");

Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);

Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);

यदि एक निष्पादन योग्य जार से चलाया जाता है, तो प्रतिबिंब कार्य नहीं करता है।
ल्यूक

निष्पादन योग्य जार से काम करने वाला स्प्रिंग समाधान: stackoverflow.com/a/21430849/4265610
ल्यूक

1
महज प्रयोग करें। जार टीवीफ jarfile.jar। आप यह सब क्यों कर रहे हैं
फिलिप रीगो

184

आप जावा jarटूल का उपयोग कर सकते हैं । जार फ़ाइल की सामग्री को txt फ़ाइल में सूचीबद्ध करें और आप जार में सभी वर्गों को देख सकते हैं।

jar tvf jarfile.jar

संग्रह के लिए सामग्री की सूची सूची

-V मानक आउटपुट पर वर्बोज़ आउटपुट उत्पन्न करते हैं

-f संग्रह फ़ाइल नाम निर्दिष्ट करें


1
धन्यवाद। यह "बस एक वर्ग सूची प्राप्त" ओपी का हिस्सा है जो नहीं पूछा गया था का जवाब देता है।
ऑक्टोपसग्राबस 17

9
आप unzip -l jarfile.jarचुटकी में भी इस्तेमाल कर सकते हैं । एक JAR फाइल एक प्रकट के साथ एक ज़िप फ़ाइल है!
sigpwned

3
मुद्दा यह है कि वह संभवतः रनटाइम के दौरान एक जार के अंदर वर्ग फ़ाइलों को प्राप्त करना चाहता था, एक क्लास लोडर उदाहरण दिया जाता है (यह देखने की संभावना है कि उस विशिष्ट जार के अंदर कौन सी कक्षाएं भरी हुई हैं)।
रिचर्ड ड्यूयर

19

हो सकता है कि आप jarटर्मिनल में कक्षाओं की सूची प्राप्त करने के लिए कमांड देख रहे हों ,

$ jar tf ~/.m2/repository/org/apache/spark/spark-assembly/1.2.0-SNAPSHOT/spark-assembly-1.2.0-SNAPSHOT-hadoop1.0.4.jar 
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/spark/
org/apache/spark/unused/
org/apache/spark/unused/UnusedStubClass.class
META-INF/maven/
META-INF/maven/org.spark-project.spark/
META-INF/maven/org.spark-project.spark/unused/
META-INF/maven/org.spark-project.spark/unused/pom.xml
META-INF/maven/org.spark-project.spark/unused/pom.properties
META-INF/NOTICE

कहाँ पे,

-t  list table of contents for archive
-f  specify archive file name

या, केवल परिणाम देखने के लिए .classकेवल ऊपर grep

$ jar tf ~/.m2/repository/org/apache/spark/spark-assembly/1.2.0-SNAPSHOT/spark-assembly-1.2.0-SNAPSHOT-hadoop1.0.4.jar | grep .class
org/apache/spark/unused/UnusedStubClass.class

classतों की संख्या देखने के लिए ,

jar tvf launcher/target/usergrid-launcher-1.0-SNAPSHOT.jar | grep .class | wc -l
61079

2
यह वही था जो मुझे चाहिए था, भले ही प्रश्न मालिक को कोड-आधारित समाधान की आवश्यकता हो। धन्यवाद!
प्रोवेंसमैक

10

यह एक हैक है जिसका मैं उपयोग कर रहा हूं:

आप javaइस तरह से स्वत: पूर्ण का उपयोग कर सकते हैं :

java -cp path_to.jar <Tab>

यह आपको शुरुआती कक्षा के रूप में उत्तीर्ण करने के लिए उपलब्ध कक्षाओं की एक सूची देगा। बेशक, एक का उपयोग करने की कोशिश करना जिसमें कोई मुख्य फ़ाइल नहीं है, कुछ भी नहीं करेगा, लेकिन आप देख सकते हैं कि javaअंदर के वर्ग क्या .jarकहते हैं।



5

तुम कोशिश कर सकते हो:

jar tvf jarfile.jar 

यह तभी मददगार होगा जब आपका जार निष्पादन योग्य हो अर्थात प्रकट रूप में आपने कुछ वर्ग को मुख्य वर्ग के रूप में परिभाषित किया हो


अपने उत्तर में एक उदाहरण जार पर कुछ विशिष्ट उदाहरण जोड़ें।
Juru

4

नीचे कमांड एक जार फ़ाइल की सामग्री को सूचीबद्ध करेगी ।

आज्ञा: - unzip -l jarfilename.jar

नमूना ओ / पी: -

Archive: hello-world.jar Length Date Time Name --------- ---------- ----- ---- 43161 10-18-2017 15:44 hello-world/com/ami/so/search/So.class 20531 10-18-2017 15:44 hello-world/com/ami/so/util/SoUtil.class --------- ------- 63692 2 files

के मैनुअल के अनुसार unzip

-l सूची संग्रह फ़ाइलें (लघु प्रारूप)। निर्दिष्ट फ़ाइलों के लिए योग के साथ-साथ निर्दिष्ट फ़ाइलों के नाम, असम्पीडित फ़ाइल आकार और संशोधन तिथियां और समय मुद्रित होते हैं। यदि UnZip को OS2_EAS परिभाषित के साथ संकलित किया गया था, -l विकल्प संग्रहीत ओएस / 2 विस्तारित विशेषताओं (ईएएस) और ओएस / 2 एक्सेस कंट्रोल सूचियों (एसीएल) के आकारों के लिए कॉलम भी सूचीबद्ध करता है। इसके अलावा, zipfile टिप्पणी और व्यक्तिगत फ़ाइल टिप्पणियां (यदि कोई हो) प्रदर्शित की जाती हैं। यदि किसी फ़ाइल को एकल-केस फ़ाइल सिस्टम से संग्रहीत किया गया था (उदाहरण के लिए, पुराने MS-DOS FAT फ़ाइल सिस्टम) और -L विकल्प दिया गया था, तो फ़ाइल नाम को लोअरकेस में बदल दिया जाता है और एक कैरेट (^) के साथ उपसर्ग किया जाता है।


जबकि इस कोड स्निपेट का स्वागत है, और कुछ मदद प्रदान कर सकता है, यह हो जाएगा काफी सुधार हुआ है, तो यह उसका स्पष्टीकरण शामिल की कैसे और क्यों इस को हल करती है समस्या। याद रखें कि आप भविष्य में पाठकों के लिए सवाल का जवाब दे रहे हैं, न कि केवल उस व्यक्ति से जो अब पूछ रहा है! कृपया स्पष्टीकरण जोड़ने के लिए अपना उत्तर संपादित करें, और इस बात का संकेत दें कि क्या सीमाएँ और मान्यताएँ लागू होती हैं।
टोबी स्पाईट

2

आप यह कोशिश कर सकते हैं:

unzip -v /your/jar.jar

यह तभी मददगार होगा जब आपका जार निष्पादन योग्य हो अर्थात प्रकट रूप में आपने कुछ वर्ग को मुख्य वर्ग के रूप में परिभाषित किया हो


1

इस बैश स्क्रिप्ट का उपयोग करें:

#!/bin/bash

for VARIABLE in *.jar
do
   jar -tf $VARIABLE |grep "\.class"|awk -v arch=$VARIABLE '{print arch ":" $4}'|sed 's/\//./g'|sed 's/\.\.//g'|sed 's/\.class//g'
done

यह फॉर्म में आपकी निर्देशिका में जार के अंदर की कक्षाओं को सूचीबद्ध करेगा:

file1.jar:fullyqualifiedclassName
file1.jar:fullyqualifiedclassName
file1.jar:fullyqualifiedclassName
file1.jar:fullyqualifiedclassName
file2.jar:fullyqualifiedclassName
file2.jar:fullyqualifiedclassName
file2.jar:fullyqualifiedclassName

नमूना उत्पादन:

commons-io.jar:org.apache.commons.io.ByteOrderMark
commons-io.jar:org.apache.commons.io.Charsets
commons-io.jar:org.apache.commons.io.comparator.AbstractFileComparator
commons-io.jar:org.apache.commons.io.comparator.CompositeFileComparator
commons-io.jar:org.apache.commons.io.comparator.DefaultFileComparator
commons-io.jar:org.apache.commons.io.comparator.DirectoryFileComparator
commons-io.jar:org.apache.commons.io.comparator.ExtensionFileComparator
commons-io.jar:org.apache.commons.io.comparator.LastModifiedFileComparator

खिड़कियों में आप पॉवरशेल का उपयोग कर सकते हैं:

Get-ChildItem -File -Filter *.jar |
ForEach-Object{
    $filename = $_.Name
    Write-Host $filename
    $classes = jar -tf $_.Name |Select-String -Pattern '.class' -CaseSensitive -SimpleMatch
    ForEach($line in $classes) {
       write-host $filename":"(($line -replace "\.class", "") -replace "/", ".")
    }
}

0

समाधान का विवरण : नमूना आईडीई परियोजना के लिए ग्रहण आईडीई का उपयोग किया जा सकता है और प्रोजेक्ट बिल्ड पथ में सभी जार जोड़ सकते हैं

नीचे STEPS :

  1. एक नमूना बनाएँ जावा परियोजना।

  2. इसके निर्माण पथ में सभी जार आपके पास हैं

  3. CTRL + SHIFT + T और पूर्ण श्रेणी नाम टाइप करें।

  4. परिणाम उस वर्ग वाले सभी जार के साथ खिड़की में प्रदर्शित किए जाएंगे। संलग्न चित्र देखें। यहां छवि विवरण दर्ज करें


0

windows cmd: यह काम करेगा यदि आपके पास एक ही डायरेक्टरी में सभी te jars हैं और नीचे दिए गए कमांड को निष्पादित करें

for /r %i in (*) do ( jar tvf %i | find /I "search_string")

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.