স্প্রিং অ্যাপ্লিকেশন কনটেক্সট - রিসোর্স লিক: 'প্রসঙ্গ' কখনই বন্ধ হয় না


94

একটি বসন্ত এমভিসি অ্যাপ্লিকেশনটিতে, আমি নিম্নলিখিত পদ্ধতির সাহায্যে পরিষেবা ক্লাসগুলির মধ্যে একটিতে একটি ভেরিয়েবল শুরু করি:

ApplicationContext context = 
         new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);

ইউজারলিবারি একটি তৃতীয় পক্ষের ইউটিলিটি যা আমি আমার অ্যাপ্লিকেশনটিতে ব্যবহার করছি। উপরের কোডটি 'প্রসঙ্গ' ভেরিয়েবলের জন্য একটি সতর্কতা তৈরি করে। সতর্কতা নীচে দেখানো হয়েছে:

Resource leak: 'context' is never closed

আমি সতর্কতা বুঝতে পারি না। অ্যাপ্লিকেশনটি একটি স্প্রিং এমভিসি অ্যাপ্লিকেশন হিসাবে, অ্যাপ্লিকেশনটি চলমান থাকাকালীন আমি পরিষেবাটি উল্লেখ করার সাথে সাথে আমি প্রসঙ্গটি বন্ধ করতে / ধ্বংস করতে পারি না। সতর্কবাণীটি আমাকে কী বলার চেষ্টা করছে?


4
আমি কৌতূহল করছি কেন আপনি স্প্রিং এমভিসি দ্বারা বুটস্ট্র্যাপ করা অ্যাপ্লিকেশন প্রসঙ্গের মধ্যে শিম তৈরির বিপরীতে অন্য অ্যাপ্লিকেশন প্রসঙ্গ তৈরি করছেন
কেভিন বোয়ারক্সক্স

আমাকে একটি নতুন ধারক কেন তৈরি করতে হয়েছে তার ব্যাখ্যার জন্য এই থ্রেড স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / 14184177/… দেখুন ।
জিগি

কখন এই প্রবণতাটি প্রদর্শিত হবে: আপনি প্রসঙ্গ তৈরি করার সময়?
রাল্ফ

আমি এটি কেবলমাত্র Eclipse এ দেখলাম (হলুদ বর্ণিত)। আমি যখন অ্যাপ্লিকেশনটি চালাব তখন আমি কেবল লগগুলি পরীক্ষা করেছিলাম কিন্তু আমি সতর্কতাটি দেখতে পাচ্ছি না।
জিগি

উত্তর:


92

যেহেতু অ্যাপ্লিকেশন প্রসঙ্গটি হ'ল ResourceLoader(অর্থাত্ I / O ক্রিয়াকলাপ) এটি এমন সংস্থান খায় যা কোনও পর্যায়ে মুক্ত হতে হবে। এটি AbstractApplicationContextপ্রয়োগ করে একটি এক্সটেনশন Closable। সুতরাং, এটি একটি close()পদ্ধতি পেয়েছে এবং একটি সংস্থান-রিসোর্স বিবৃতিতে ব্যবহার করা যেতে পারে ।

try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/userLibrary.xml")) {
  service = context.getBean(UserLibrary.class);
}

আপনার আসলে এই প্রসঙ্গটি তৈরি করা দরকার কিনা তা অন্যরকম প্রশ্ন (আপনি এর সাথে যুক্ত), আমি এ বিষয়ে মন্তব্য করব না।

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


আমি মনে করি সমস্যার উত্সটি আসলে এটিই যে আমি একটি ভিন্ন প্রসঙ্গ তৈরি করেছি। সতর্কতা সমাধানের চেষ্টা করার চেয়ে অতিরিক্ত প্রসঙ্গটি সরিয়ে ফেলা সম্ভবত একটি ভাল বিকল্প। ধন্যবাদ
জিগি

25
নোটের উপযুক্ত: যদিও বেস ApplicationContextইন্টারফেসটি পদ্ধতিটি সরবরাহ করে না close(), ConfigurableApplicationContext(যা ClassPathXmlApplicationContextপ্রয়োগ করে) এটি করে এবং Closeableবুট পর্যন্ত প্রসারিত করে, তাই আপনি জাভা try চেষ্টা করে-রিসোর্স দৃষ্টান্ত ব্যবহার করতে পারেন ig
kbolino

@ কেবোলিনো রিসোর্স-এ-রিসোর্স বিবৃতিটি নিশ্চিত করে যে বিবৃতিটির শেষে প্রতিটি সংস্থান বন্ধ রয়েছে।
ruruskyi

4
: @kbolino আরও দেখুন stackoverflow.com/questions/14423980/...
Raedwald

4
এখানে +1 কেবোলিনোর মন্তব্য, কারণ আমি আমার পরিবর্তনশীল হিসাবে ঘোষনা করছিলাম ApplicationContextএবং যখন আমার কাছে কোনও ঘনিষ্ঠ পদ্ধতি উপলব্ধ ছিল না তখন কেন সতর্কতা পাচ্ছিলাম তা নিয়ে আমার মাথা
আছড়ে পড়ছিল

40

close()ApplicationContextইন্টারফেসে সংজ্ঞায়িত করা হয় না ।

সতর্কতা থেকে নিরাপদে মুক্তি পাওয়ার একমাত্র উপায় নিম্নলিখিতটি is

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...);
try {
    [...]
} finally {
    ctx.close();
}

বা, জাভা 7 এ

try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...)) {
    [...]
}

মূল পার্থক্যটি হ'ল যেহেতু আপনি প্রসঙ্গটি স্পষ্টভাবে ইনস্ট্যান্ট করেন (অর্থাত্ ব্যবহার করে new) আপনি যে ক্লাসটি ইনস্ট্যান্ট করছেন তা জানেন, তাই আপনি সেই অনুযায়ী আপনার পরিবর্তনশীলকে সংজ্ঞায়িত করতে পারেন।

আপনি যদি অ্যাপকন্টেক্সট ইনস্ট্যান্ট না করছিলেন (অর্থাত্ বসন্তের সরবরাহকৃত একটি ব্যবহার করে) তবে আপনি এটি বন্ধ করতে পারবেন না।


6
বারবার ভুল চেষ্টা ... অবশেষে অন্যকে শেখানো হয় ... ট্রাই new ClassPathXmlApplicationContext(...);-ব্লকের বাইরে হওয়া আবশ্যক। তাহলে নাল চেকের দরকার নেই। যদি কনস্ট্রাক্টর একটি ব্যতিক্রম ছুড়ে ফেলে তবে ctxনাল হয় এবং finallyব্লকটি ডাকা হয় না (কারণ ব্যতিক্রমটি চেষ্টা-ব্লকের বাইরে ফেলে দেওয়া হয়েছিল)। যদি কনস্ট্রাক্টর কোনও ব্যতিক্রম না ছুঁড়ে দেয় তবে tryব্লকটি প্রবেশ করানো হয় এবং ctxশূন্য হতে পারে না, সুতরাং নাল-চেক করার প্রয়োজন নেই।
কায়াহর

এই উত্তরটি খারাপ, আপনার চেষ্টা অবশেষে অবরুদ্ধ করার সাথে একটি আসল সমস্যা আছে। সবেমাত্র পরীক্ষিত কিন্তু কিছুতেই কাজ করছে না।
HDJEMAI


6

অ্যাপ্লিকেশন প্রসঙ্গে যেমন ক্লাসপ্যাথএক্সএমএল অ্যাপ্লিকেশনকন্টেক্সটসের একটি উদাহরণ রয়েছে এবং এটিতে একটি ঘনিষ্ঠ () পদ্ধতি রয়েছে। আমি কেবল অ্যাপকন্টেক্সট অবজেক্টটি কাস্ট করব এবং নীচের মতো বন্ধ () পদ্ধতিটি প্রার্থনা করব।

ApplicationContext appContext = new ClassPathXmlApplicationContext("spring.xml");
//do some logic
((ClassPathXmlApplicationContext) appContext).close();

এটি রিসোর্স ফাঁসের সতর্কতা ঠিক করবে।


4

এটা চেষ্টা কর. অ্যাপ্লিকেশন পাঠ্য বন্ধ করতে আপনাকে কাস্ট প্রয়োগ করতে হবে।

   ClassPathXmlApplicationContext ctx = null;
      try {
         ctx = new ClassPathXmlApplicationContext(...);
            [...]
             } finally {
              if (ctx != null)
                  ((AbstractApplicationContext) ctx).close();       
      }

3

এমনকি আমার ঠিক একই সতর্কতা ছিল, আমি যা করেছি তা হ'ল ApplicationContextমূল ফাংশনের বাইরে private staticএবং টা-দা হিসাবে সমস্যাটি স্থির ছিল।

public class MainApp {
    private static ApplicationContext context;

    public static void main(String[] args) {
        context = new ClassPathXmlApplicationContext("Beans.xml");

        HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

        objA.setMessage("I'm object A");
        objA.getMessage();

        HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
        objB.getMessage();
    }
}

9
এটি সতর্কবার্তা সমস্যাটি সমাধান করে তবে আসল সমস্যাটি নয় যা প্রসঙ্গটি উন্মুক্ত রেখে একটি ফাঁস হওয়ার কারণ হয়ে দাঁড়িয়েছে। আপনি একটি @SupressWarningsটীকা দিয়ে একই কাজ করতে পারেন , তবে মূল সমস্যার সমাধান করা আরও ভাল, আপনি কি ভাবেন না?
এক্সট্রিম বাইকার

হ্যাঁ আপনি ঠিক বলেছেন .. এই মুহুর্তে এটি আমার পক্ষে একমাত্র কাজ ছিল।
ইলিজিয়াম

এটি একটি ভাল উত্তর নয়। যেহেতু আসল ইস্যুটি একই থাকে, অর্থাত্ রিসোর্স লিক হয়, প্রসঙ্গ কখনও বন্ধ হয় না।
HDJEMAI

2

Ingালাই এই সমস্যাটির সঠিক সমাধান resolution আমি নীচের লাইনটি ব্যবহার করে একই সমস্যার মুখোমুখি হয়েছি। ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

সতর্কবার্তাটি সমাধান করার জন্য ঠিক ctxনীচের মতো অবজেক্টটি ডাউনকাস্ট করুন এবং তারপরে এটি বন্ধ করুন। ((AnnotationConfigApplicationContext) ctx).close();


1

কনফিগারযোগ্য অ্যাপ্লিকেশন কনটেক্সটে প্রসঙ্গটি ডাউনকাস্ট করুন।

((ConfigurableApplicationContext)context).close();

((ConfigurableApplicationContext)(context)).close();এটিই সঠিক উত্তর হতে পারে
ভার্গব মোদী

অ্যামিট 28 এর উত্তরটি সঠিক। উত্তরটি কেন কার্যকর নয়?
রুডি দর্শকদের

1
Object obj = context.getBean("bean");
if(bean instanceof Bean) {
    Bean bean = (Bean) obj;
}

আমার ক্ষেত্রে ফুটো অদৃশ্য হয়ে যায়


1

এটি আমার পক্ষে সবচেয়ে ভাল কাজ করেছে।

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class Test {

     private static ApplicationContext con;

     public static void main(String[] args) {

         con = new ClassPathXmlApplicationContext("config.xml");

         Employee ob = (Employee) con.getBean("obj");
         System.out.println("Emp Id " + ob.getEmpno());
         System.out.println("Emp name " + ob.getEmpname());
    }
}

0

আপনি যদি ক্লাসপ্যাথএক্সএমএল অ্যাপ্লিকেশন কনটেক্সট ব্যবহার করছেন তবে আপনি ব্যবহার করতে পারেন

((ClassPathXmlApplicationContext) context).close();

রিসোর্স লিক সমস্যা বন্ধ করতে।

আপনি যদি অ্যাবস্ট্রাক্ট অ্যাপ্লিকেশন কনটেক্সট ব্যবহার করছেন তবে আপনি এটি নিকট পদ্ধতিতে কাস্ট করতে পারেন।

((AbstractApplicationContext) context).close();

এটি অ্যাপ্লিকেশনটিতে প্রসঙ্গের ধরণের উপর নির্ভর করে।


0
import org.springframework.context.ConfigurableApplicationContext;

((ConfigurableApplicationContext)ctx).close();

4
আপনি কেন এই প্রশ্নের উত্তরটি ভাবেন তা বিশদ দিয়ে বলতে পারেন?
জিন ব্রুকস্ট্র্রা

ClassPathXMLApplicationContext সুপার ক্লাস কনফিগারযোগ্য অ্যাপ্লিকেশন কনটেক্সট প্রয়োগ করে যার মধ্যে ক্লোজ () পদ্ধতি রয়েছে। বন্ধ () পদ্ধতিটি কল করতে আমরা কনফিগারযোগ্য অ্যাপ্লিকেশন কনটেক্সটে প্রসঙ্গটি টাইপকাস্ট করতে পারি, এটি সংস্থানগুলি মুক্ত করে। কেবলমাত্র আমরা ((ClassPathXML অ্যাপ্লিকেশন কনটেক্সট) ctx)। ক্লোজ ();
সুসেন্দ্রন পি

0

আপনি প্রসঙ্গটি একটি স্থিতিশীল পরিবর্তনশীল বানান, যার অর্থ এই যে প্রসঙ্গটি ক্লাসের সমস্ত স্থিতিশীল পদ্ধতির জন্য উপলভ্য এবং মূল পদ্ধতির ক্ষেত্রের মধ্যে সীমাবদ্ধ নয়। সুতরাং সরঞ্জামটি ধরেই নিতে পারে না যে এটি আর পদ্ধতির শেষে বন্ধ করা উচিত, সুতরাং এটি আর সতর্কতা জারি করে না।

public class MainApp {
    private static ApplicationContext context;
    public static void main(String[] args) {
          context = 
                 new ClassPathXmlApplicationContext("Beans.xml");

          HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

          obj.getMessage();

       }
}

0

হ্যাঁ, ইন্টারফেসের ApplicationContextকোনও close()পদ্ধতি নেই, সুতরাং আমি AbstractApplicationContextসেই closeপদ্ধতিটি স্পষ্টভাবে ব্যবহার করতে ক্লাস ব্যবহার করতে চাই এবং এখানেও আপনি XMLটাইপের পরিবর্তে টীকাটি ব্যবহার করে আপনার স্প্রিং অ্যাপ্লিকেশন কনফিগারেশন ক্লাস ব্যবহার করতে পারেন ।

AbstractApplicationContext context = new AnnotationConfigApplicationContext(SpringAppConfig.class);
Foo foo = context.getBean(Foo.class);

//do some work with foo

context.close();

তোমার Resource leak: 'context' is never closedসতর্কতা এখন শেষ


0

এটির একটি সহজ সমাধান রয়েছে কেবল এই লিংকে প্রদত্ত কোর জারের পাঠাগারগুলিতে ইনপুট করুন [বসন্তের জন্য মূল জার ফাইলগুলি ডাউনলোড করুন] [1] [1]: https://static.javatPoint.com/src/sp/spcorejars। জিপ


4
দয়া করে মার্কডাউন ডক্স পরীক্ষা করুন এবং প্রাকদর্শনটি ব্যবহার করুন, আপনার URL টি কেটে ফেলা হয়েছে বলে মনে হচ্ছে।
লিও

-1

পদ্ধতির কাছাকাছিটি কনফিগারযোগ্য অ্যাপ্লিকেশন কনটেক্সট ইন্টারফেসে যুক্ত করা হয়েছে, সুতরাং এতে অ্যাক্সেস পাওয়ার জন্য আপনি সবচেয়ে ভাল যা করতে পারেন তা হ'ল:

ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
                "/app-context.xml");

// Use the context...

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