জাভা ক্লাসটি কোথা থেকে লোড করা হয়েছে তা সন্ধান করুন


184

জাভা ক্লাসলোডার কোথা থেকে ক্লাসটি লোড করে কোথা থেকে প্রোগ্রামিমেটিকভাবে এটি সন্ধান করতে হয় তা কি কেউ জানেন?

আমি প্রায়শই বড় প্রকল্পগুলিতে কাজ করি যেখানে ক্লাসপথটি খুব দীর্ঘ হয় এবং ম্যানুয়াল অনুসন্ধানগুলি আসলে কোনও বিকল্প নয়। আমার সম্প্রতি একটি সমস্যা হয়েছিল যেখানে ক্লাসলোডার একটি শ্রেণীর একটি ভুল সংস্করণ লোড করছিল কারণ এটি দুটি পৃথক স্থানে ক্লাসপাথে ছিল।

তাহলে আমি ক্লাস লোডারকে কীভাবে বলতে পারি যে ডিস্কে আসল ক্লাস ফাইলটি কোথা থেকে আসছে?

সম্পাদনা: ক্লাসলোডার যদি কোনও ভার্সন মিলের (বা অন্য কিছু) কারণে ক্লাস লোড করতে ব্যর্থ হয় তবে কী হবে, যাইহোক আমরা কী ফাইলটি পড়ার আগে এটি পড়ার চেষ্টা করে তা জানতে পারি?


4
@JarrodRoberson আমি মনে করি না এই সদৃশ বিবেচনা করা উচিত stackoverflow.com/questions/11747833/... যেহেতু এই প্রশ্নের 2008 সালে জিজ্ঞাসা করা হল এবং 2012 সালে যে প্রশ্ন জিজ্ঞাসা করা হল
লুক

উত্তর:


188

এখানে একটি উদাহরণ:

package foo;

public class Test
{
    public static void main(String[] args)
    {
        ClassLoader loader = Test.class.getClassLoader();
        System.out.println(loader.getResource("foo/Test.class"));
    }
}

এটি মুদ্রিত:

file:/C:/Users/Jon/Test/foo/Test.class

32
অপ্রয়োজনীয় টাইপিং কাটাতে, একটি স্বল্প সংস্করণও ব্যবহার করতে পারে: Test.class.getResource("Test.class")যা প্যাকেজের নামটির পুনরাবৃত্তি করে না।
মেরিটন

1
ক্লাসটি যদি সংকলিত হয়, উদাহরণস্বরূপ একটি .groovy ফাইল থেকে?
ওন্দ্রা Žižka

35
@ মেরিটন: বা, রিফ্যাক্টরিঞ্জস টিকে থাকতে:Test.class.getResource(Test.class.getSimpleName() + ".class")
21:13

1
জন্য BouncyCastleProviderপূর্ণ প্যাকেজের নাম অবশ্য প্রয়োজন।
পাভেল ভ্লাসভ

3
getClassLoader()ফিরে আসা সম্ভব null। এটি পরিচালনা করতে এই পদ্ধতিতে এক্সটেনশনের জন্য এখানে দেখুন ।
ওল্ড কারুকমডজিওন

100

কোনও শ্রেণি কোথা থেকে লোড করা হয়েছে তা খুঁজে বের করার আরেকটি উপায় (উত্সটি হস্তান্তর না করে) জাভা ভিএম বিকল্পটি দিয়ে শুরু করা: -verbose:class


6
এটি খুব ভালভাবে কাজ করেছে, এবং নাল ClassLoader
লেজিকস্কোপ

2
@ সিরিজগুলি যদি এই প্রোগ্রামটিমেটিকভাবে করার দরকার না হয় তবে এটি অবশ্যই যাওয়ার উপায় এবং এটি আমার সমস্যার সমাধান করে। তবে ওপি বিশেষভাবে জিজ্ঞাসা করেছিল যে কীভাবে এই প্রোগ্রামটিমেটিকভাবে করা যায়।
সান্টিবাইলার্স

79
getClass().getProtectionDomain().getCodeSource().getLocation();

4
হ্যাঁ, এটি কোনও সুরক্ষা পরিচালক ইনস্টল করা এবং প্রয়োজনীয় অনুমতি ব্যতীত কাজ করে না।
টম হাটিন -

1
এফওয়াইআই, এনপিই = নাল পয়েন্টার ব্যতিক্রম। আছে HTH!
এভেজেনি সার্জিভ

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

1
জাভা 9+ মডিউল থেকে কল করার পরেও কাজ করে না (অবশ্যই আপনি 2008 সালে জানতেন না)।
জেফ জি

28

এটি আমরা ব্যবহার করি:

public static String getClassResource(Class<?> klass) {
  return klass.getClassLoader().getResource(
     klass.getName().replace('.', '/') + ".class").toString();
}

এটি ClassLoader প্রয়োগের উপর নির্ভর করে কাজ করবে: getClass().getProtectionDomain().getCodeSource().getLocation()


17

জনের সংস্করণ ব্যর্থ হয় যখন অবজেক্টটি ClassLoaderনিবন্ধিত হয় nullযা মনে হয় যে এটি বুট দ্বারা লোড হয়েছিল ClassLoader

এই পদ্ধতিটি এই সমস্যাটির সাথে সম্পর্কিত:

public static String whereFrom(Object o) {
  if ( o == null ) {
    return null;
  }
  Class<?> c = o.getClass();
  ClassLoader loader = c.getClassLoader();
  if ( loader == null ) {
    // Try the bootstrap classloader - obtained from the ultimate parent of the System Class Loader.
    loader = ClassLoader.getSystemClassLoader();
    while ( loader != null && loader.getParent() != null ) {
      loader = loader.getParent();
    }
  }
  if (loader != null) {
    String name = c.getCanonicalName();
    URL resource = loader.getResource(name.replace(".", "/") + ".class");
    if ( resource != null ) {
      return resource.toString();
    }
  }
  return "Unknown";
}

5

মাত্র 1 ম লাইন সম্পাদনা করুন: Main.ক্লাস

Class<?> c = Main.class;
String path = c.getResource(c.getSimpleName() + ".class").getPath().replace(c.getSimpleName() + ".class", "");

System.out.println(path);

আউটপুট:

/C:/Users/Test/bin/

খারাপ স্টাইল হতে পারে তবে কাজ করে!


3

সাধারণত, আমরা হার্ডকোডিং কী ব্যবহার করব তা বলি না। আমরা প্রথমে ক্লাসনেম পেতে পারি এবং তারপরে ক্লাসের ইউআরএল পেতে ক্লাসলুডার ব্যবহার করতে পারি।

        String className = MyClass.class.getName().replace(".", "/")+".class";
        URL classUrl  = MyClass.class.getClassLoader().getResource(className);
        String fullPath = classUrl==null ? null : classUrl.getPath();

হওয়া দরকার: ইউআরএল শ্রেণিআউআরএল = মাইক্লাস.ক্লাস.সেটক্লাসলোডার ()। GetResource ("/" + শ্রেণীর নাম);
অ্যান্ড্রু কোটস

মাইক্লাস.ক্লাস গুরুত্বপূর্ণ অংশ - getClass () প্রক্সি ফিরিয়ে দিতে পারে! তারপরে আপনি মাইক্লাস $$ EnhancerBySpringCGLIB $$ a98db882.class, এবং নাল URL এর মতো নাম পেতে পারেন।
জলমসি


1

সহজ উপায়:

System.out.println (java.lang.String.class.getResource (String.class.getSimpleName () + + "শ্রেণী।"));

আউট উদাহরণ:

বয়াম: ফাইল: / ডি: /Java/jdk1.8/jre/lib/rt.jar /java/lang/String.class

অথবা

স্ট্রিংজেজ = "সরল পরীক্ষা"; System.out.println (obj.getClass () getResource (obj.getClass () getSimpleName () + +)।। "বর্গ।");

আউট উদাহরণ:

বয়াম: ফাইল: / ডি: /Java/jdk1.8/jre/lib/rt.jar /java/lang/String.class


0

এই পদ্ধতির ফাইল এবং জার উভয়ের জন্য কাজ করে:

Class clazz = Class.forName(nameOfClassYouWant);

URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class");
InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish

-1

ধরে নেওয়া যে আপনি নামের একটি শ্রেণীর সাথে কাজ করছেন MyClass, নিম্নলিখিতগুলির কাজ করা উচিত:

MyClass.class.getClassLoader();

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


এটি ক্লাস লোড করার জন্য ব্যবহৃত ClassLoader প্রদান করে, তাই না? .Class ফাইলটি কোথায় পাওয়া যায় না?
Koray Tugay

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