একটি জার ফাইলের মধ্যে ক্লাসগুলির নাম কীভাবে পাবেন?


112

আমার একটি জেআর ফাইল রয়েছে এবং আমার এই জেআর ফাইলের ভিতরে থাকা সমস্ত শ্রেণীর নাম নেওয়া দরকার। আমি এটা কিভাবে করবো?

আমি এটি গুগল করেছিলাম এবং জারফিল বা জাভা সম্পর্কে কিছু দেখেছি ClassLoaderতবে কীভাবে করব তা আমার কোনও ধারণা নেই।


আপনি কি কিছু আইডিই ব্যবহার করছেন? আপনি যদি এটি ব্যবহার করেন তবে এটি স্বয়ংক্রিয়ভাবে প্রদর্শিত হবে।
জোয় রোহান

আমি Eclipse ব্যবহার করছি, তবে কোড সহ আমার এটি করা দরকার।
স্টিকসু

@ লুইগিমেডোজা - সম্ভাব্য নকলটির উদাহরণ সহ ডকুমেন্টেশনের সংস্থান রয়েছে। এই শ্রেণীর নামগুলির মধ্যে একটির জন্য অনুসন্ধান + উদাহরণস্বরূপ বেশ কয়েকটি দরকারী ফলাফল পাওয়া যাবে।
আইয়িয়াস

@ আলিয়াস সম্ভাব্য সদৃশটি কীভাবে একটি জার থেকে কোনও ফাইল সন্ধান এবং পাবেন তা জানায়, যখন প্রশ্নটি একটি জারের ভিতরে শ্রেণীর নামগুলি পাওয়া (সম্ভবত এটির অভ্যন্তরে সমস্ত প্যাকেজের ক্লাস) থাকে। এরিককাজুর উত্তরের লিঙ্কটি ব্যবহার করে একটি সম্ভাব্য সমাধান JarInputStreamএবং JarEntryক্লাসগুলি যা আমি আপনার উল্লেখ করা লিঙ্কের কোনও উত্তরে খুঁজে পাচ্ছি না তাতে নির্দেশ করে।
লুইগি মেন্দোজা

উত্তর:


68

দুর্ভাগ্যক্রমে, জাভা "নেটিভ" জেআরইতে ক্লাস তালিকা করার কোনও সহজ উপায় সরবরাহ করে না। এটি আপনাকে বেশ কয়েকটি বিকল্পের সাথে ছেড়ে দেয়: (ক) প্রদত্ত যে কোনও জেআর ফাইলের জন্য, আপনি সেই জেআর ফাইলের ভিতরে থাকা তালিকাগুলি তালিকাভুক্ত করতে পারেন, ফাইলগুলি সন্ধান করতে পারেন .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হ'ল এটি খুঁজে পাওয়া ক্লাসগুলি লোড করে না, আপনি যখন প্রচুর ক্লাসের জন্য স্ক্যান করছেন তখন তা গুরুত্বপূর্ণ important

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

ভাবনা

আমি ব্যক্তিগতভাবে প্রতিচ্ছবি গ্রন্থাগারটি ব্যবহার করি নি , তবে এটি ভাল পছন্দ হয়েছে বলে মনে হচ্ছে। কোনও জেআর ফাইল দ্বারা সরবরাহিত প্যাকেজে সমস্ত ক্লাস লোড করার জন্য এই দুর্দান্ত উপায়ে ওয়েবসাইটটিতে কয়েকটি দুর্দান্ত উদাহরণ সরবরাহ করা হয়েছে, এটি আপনার অ্যাপ্লিকেশনের জন্যও কার্যকর হতে পারে।

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

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

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

এক্সিকিউটেবল জার থেকে চালানো হলে রিফ্লেকশনগুলি কাজ করে না।
লুক 13

এক্সিকিউটেবল জারগুলি থেকে কার্যকর একটি বসন্ত সমাধান: stackoverflow.com/a/21430849/4265610
লুক 14

1
শুধু ব্যবহার। জার টিভিএফ জারফিল.জার। কেন আপনি এই সব জন্য করছেন।
ফিলিপ রেগো

184

আপনি জাভা jarসরঞ্জাম ব্যবহার করতে পারেন । একটি টেক্সট ফাইলে জারের ফাইলের বিষয়বস্তু তালিকাভুক্ত করুন এবং আপনি জারের সমস্ত ক্লাস দেখতে পাবেন।

jar tvf jarfile.jar

সংরক্ষণাগারের জন্য বিষয়বস্তুগুলির তালিকাভুক্ত করুন

-v স্ট্যান্ডার্ড আউটপুটে ভার্বোজ আউটপুট উত্পন্ন করে

-ফ সংরক্ষণাগার ফাইলের নাম নির্দিষ্ট করুন


1
ধন্যবাদ। এটি ওপির "সবেমাত্র একটি শ্রেণি তালিকা পান" অংশটির উত্তর দেয় যা জিজ্ঞাসা করা হয়নি।
অক্টোপাসগ্র্যাববাস

9
আপনি unzip -l jarfile.jarএকটি চিমটি ব্যবহার করতে পারেন । একটি JAR ফাইল হ'ল একটি জিপ ফাইল যা ম্যানিফেস্টের সাথে থাকে!

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এসএস দেখতে ফলাফলের উপরে কেবল গ্রেপ করুন

$ 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>

এটি আপনাকে প্রাথমিক শ্রেণি হিসাবে পাস করার জন্য উপলব্ধ ক্লাসগুলির একটি তালিকা দেবে give অবশ্যই, কোনও প্রধান ফাইল নেই এমনটি ব্যবহার করার চেষ্টা করা কিছু করবে না, তবে আপনি দেখতে পাচ্ছেন যা javaঅভ্যন্তরের ক্লাসগুলি .jarবলা হয় তা কী মনে করে ।



5

আপনি চেষ্টা করতে পারেন:

jar tvf jarfile.jar 

এটি কেবল তখনই সহায়ক হবে যদি আপনার জার কার্যকর হয় (যেমন ম্যানিফেস্টে আপনি কিছু শ্রেণিকে প্রধান শ্রেণি হিসাবে সংজ্ঞায়িত করেছেন


আপনার উত্তরের একটি উদাহরণ জারে কিছু নির্দিষ্ট উদাহরণ যুক্ত করুন।
জুন

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 তালিকা সংরক্ষণাগার ফাইল (সংক্ষিপ্ত ফর্ম্যাট)। নির্দিষ্ট ফাইলগুলির নাম, সংকোচিত ফাইল আকার এবং পরিবর্তনের তারিখ এবং সময় প্রিন্ট করা হয়। যদি আনজিপ ওএস 2_ইএএস সংজ্ঞায়িত করে সংকলিত হয়, -l বিকল্পটি সঞ্চিত ওএস / 2 বর্ধিত বৈশিষ্ট্য (EAs) এবং ওএস / 2 অ্যাক্সেস নিয়ন্ত্রণ তালিকা (এসিএল) এর আকারগুলির জন্য কলামগুলিও তালিকাভুক্ত করে। এছাড়াও, জিপফাইলে মন্তব্য এবং পৃথক ফাইল মন্তব্য (যদি থাকে) প্রদর্শিত হয়। যদি কোনও ফাইল কোনও একক ক্ষেত্রে ফাইল সিস্টেম থেকে সংরক্ষণাগারভুক্ত হয় (উদাহরণস্বরূপ, পুরানো এমএস-ডস এফএটি ফাইল সিস্টেম) এবং -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

সমাধানের বিবরণ : একটি নমুনা জাভা প্রকল্প তৈরি করে প্রকল্প তৈরির পথে সমস্ত জার যুক্ত করে Eclipse IDE ব্যবহার করা যেতে পারে

নীচে পদক্ষেপ :

  1. একটি নমুনা Eclipse Java প্রকল্প তৈরি করুন।

  2. আপনার বিল্ড পাথে থাকা সমস্ত জার

  3. CTRL + SHIFT + T এবং সম্পূর্ণ শ্রেণীর নাম টাইপ করুন।

  4. ফলাফলটি উইন্ডোতে সমস্ত শ্রেণীর জারগুলির সাথে প্রদর্শিত হবে। সংযুক্ত ছবি দেখুন। এখানে চিত্র বর্ণনা লিখুন


0

উইন্ডোজ সেন্টিমিডি: যদি একই ডিরেক্টরিতে সমস্ত তে জার থাকে এবং নীচের কমান্ডটি কার্যকর করে তবে এটি কাজ করবে

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.