खोज…


टिप्पणियों

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

URLClassLoader का उपयोग करना

जावा एप्लिकेशन के लिए प्लगइन सिस्टम को लागू करने के कई तरीके हैं। URLClassLoader का उपयोग करना सबसे सरल है। निम्नलिखित उदाहरण में JavaFX कोड का एक बिट शामिल होगा।

मान लीजिए हमारे पास एक मुख्य एप्लिकेशन का एक मॉड्यूल है। यह मॉड्यूल 'प्लगइन्स' फ़ोल्डर से जार के रूप में प्लगइन्स लोड करने वाला है। प्रारंभिक कोड:

package main;

public class MainApplication extends Application
{
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        File pluginDirectory=new File("plugins"); //arbitrary directory
        if(!pluginDirectory.exists())pluginDirectory.mkdir();
        VBox loadedPlugins=new VBox(6); //a container to show the visual info later
        Rectangle2D screenbounds=Screen.getPrimary().getVisualBounds();
        Scene scene=new Scene(loadedPlugins,screenbounds.getWidth()/2,screenbounds.getHeight()/2);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    public static void main(String[] a)
    {
            launch(a);
    }
}

फिर, हम एक इंटरफ़ेस बनाते हैं जो एक प्लगइन का प्रतिनिधित्व करेगा।

package main;

public interface Plugin
{
    default void initialize()
    {
        System.out.println("Initialized "+this.getClass().getName());
    }
    default String name(){return getClass().getSimpleName();}
}

हम उन कक्षाओं को लोड करना चाहते हैं जो इस इंटरफ़ेस को लागू करते हैं, इसलिए पहले हमें उन फ़ाइलों को फ़िल्टर करने की आवश्यकता है जिनके पास '.jar' एक्सटेंशन है।

File[] files=pluginDirectory.listFiles((dir, name) -> name.endsWith(".jar"));

यदि कोई फ़ाइल है, तो हमें URL और श्रेणी नामों का संग्रह बनाने की आवश्यकता है:

    if(files!=null && files.length>0)
    {
        ArrayList<String> classes=new ArrayList<>();
        ArrayList<URL> urls=new ArrayList<>(files.length);
        for(File file:files)
        {
            JarFile jar=new JarFile(file);
            jar.stream().forEach(jarEntry -> {
                if(jarEntry.getName().endsWith(".class"))
                {
                    classes.add(jarEntry.getName());
                }
            });
            URL url=file.toURI().toURL();
            urls.add(url);
        }
        
    }

चलिए एक स्थाई हैशसेट को मेनप्लीकेशन में जोड़ते हैं जो लोड किए गए प्लगइन्स को रखेगा :

static HashSet<Plugin> plugins=new HashSet<>();

इसके बाद, हम एक URLClassLoader को इंस्टेंट करते हैं , और क्लास के नामों पर पुनरावृति करते हैं, उन क्लासेस को त्वरित करते हैं जो प्लगइन इंटरफेस को लागू करते हैं:

URLClassLoader urlClassLoader=new URLClassLoader(urls.toArray(new URL[urls.size()]));
classes.forEach(className->{
    try
    {
        Class cls=urlClassLoader.loadClass(className.replaceAll("/",".").replace(".class","")); //transforming to binary name
        Class[] interfaces=cls.getInterfaces();
        for(Class intface:interfaces)
        {
            if(intface.equals(Plugin.class)) //checking presence of Plugin interface
            {
                Plugin plugin=(Plugin) cls.newInstance(); //instantiating the Plugin
                plugins.add(plugin);
                break;
            }
        }
    }
    catch (Exception e){e.printStackTrace();}
});

फिर, हम प्लगइन के तरीकों को कॉल कर सकते हैं, उदाहरण के लिए, उन्हें आरंभ करने के लिए:

if(!plugins.isEmpty())loadedPlugins.getChildren().add(new Label("Loaded plugins:"));
    plugins.forEach(plugin -> {
        plugin.initialize();
        loadedPlugins.getChildren().add(new Label(plugin.name()));
});

MainApplication का अंतिम कोड:

package main;
public class MainApplication extends Application
{
    static HashSet<Plugin> plugins=new HashSet<>();
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        File pluginDirectory=new File("plugins");
        if(!pluginDirectory.exists())pluginDirectory.mkdir();
        File[] files=pluginDirectory.listFiles((dir, name) -> name.endsWith(".jar"));
        VBox loadedPlugins=new VBox(6);
        loadedPlugins.setAlignment(Pos.CENTER);
        if(files!=null && files.length>0)
        {
            ArrayList<String> classes=new ArrayList<>();
            ArrayList<URL> urls=new ArrayList<>(files.length);
            for(File file:files)
            {
                JarFile jar=new JarFile(file);
                jar.stream().forEach(jarEntry -> {
                    if(jarEntry.getName().endsWith(".class"))
                    {
                        classes.add(jarEntry.getName());
                    }
                });
                URL url=file.toURI().toURL();
                urls.add(url);
            }
            URLClassLoader urlClassLoader=new URLClassLoader(urls.toArray(new URL[urls.size()]));
            classes.forEach(className->{
                try
                {
                    Class cls=urlClassLoader.loadClass(className.replaceAll("/",".").replace(".class",""));
                    Class[] interfaces=cls.getInterfaces();
                    for(Class intface:interfaces)
                    {
                        if(intface.equals(Plugin.class))
                        {
                            Plugin plugin=(Plugin) cls.newInstance();
                            plugins.add(plugin);
                            break;
                        }
                    }
                }
                catch (Exception e){e.printStackTrace();}
            });
            if(!plugins.isEmpty())loadedPlugins.getChildren().add(new Label("Loaded plugins:"));
            plugins.forEach(plugin -> {
                plugin.initialize();
                loadedPlugins.getChildren().add(new Label(plugin.name()));
            });
        }
        Rectangle2D screenbounds=Screen.getPrimary().getVisualBounds();
        Scene scene=new Scene(loadedPlugins,screenbounds.getWidth()/2,screenbounds.getHeight()/2);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    public static void main(String[] a)
    {
            launch(a);
    }
}

चलो दो प्लगइन्स बनाते हैं। जाहिर है, प्लगइन का स्रोत एक अलग मॉड्यूल में होना चाहिए।

package plugins;

import main.Plugin;

public class FirstPlugin implements Plugin
{
    //this plugin has default behaviour
}

दूसरा प्लगइन:

package plugins;

import main.Plugin;

public class AnotherPlugin implements Plugin
{
    @Override
    public void initialize() //overrided to show user's home directory
    {
        System.out.println("User home directory: "+System.getProperty("user.home"));
    }
}

इन प्लगइन्स को मानक जार में पैक किया जाना है - यह प्रक्रिया आपके आईडीई या अन्य उपकरणों पर निर्भर करती है।

जब जार को सीधे 'प्लगइन्स' में डाल दिया जाएगा, तो MainApplication उनका पता लगाएगा और उपयुक्त कक्षाओं को तुरंत शुरू करेगा।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow