Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added possibility to overwrite DefaultPluginManager (to create f.i. a JarPluginManager) #66

Closed
wants to merge 1 commit into from

Conversation

tuxedo0801
Copy link

To create an "JarPluginManager" that uses JARs (f.i. created with Maven Assembly "jar-with-dependencies") instead of ZIP, I needed to add two get-methods to DefaultPluginManager.

And while adding those two get-methods, I also updated javadoc to keep maven javadoc generation happy.

Here is my JarPluginManager implementation incl. demo program:

https://gist.github.com/tuxedo0801/0bc4ad265131b2d46643

Instead of the long configuration part in plugin's pom,xml + assembly xml, you now only need this in the pom (just an example):

....
    <properties>
    <!-- PF4J Plugin Settings -->
        <plugin.id>knx-logic-plugin</plugin.id>
        <plugin.class>de.root1.kad.logicplugin.LogicPlugin</plugin.class>
        <plugin.version>1.0.0</plugin.version>
        <plugin.provider>AC</plugin.provider>
        <plugin.dependencies></plugin.dependencies>    
    </properties>
....
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.5.4</version>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Plugin-Id>${plugin.id}</Plugin-Id>
                            <Plugin-Class>${plugin.class}</Plugin-Class>
                            <Plugin-Version>${plugin.version}</Plugin-Version>
                            <Plugin-Provider>${plugin.provider}</Plugin-Provider>
                            <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
                        </manifestEntries>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <!-- extend phase package to assembly the archives -->
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>               
        </plugins>
    </build>
....

That creates an JAR archive with "-jar-with-dependencies.jar" suffix/extension which includes all classes from dependencies.

One could also think of skipping the plugin-extraction-process and just pass the JAR to the classloader. But for improved startup-speed on small systems (Raspberry Pi f.i.) it could be a good idea to extract the JAR.

* added possibility to overwrite DefaultPluginManager (to create f.i. a JarPluginManager)
* Returns the PluginClasspath used by this plugin manager
* @return the classpath used by this manager
*/
protected PluginClasspath getPluginClasspath() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that we need this method. From your gist code I see that you use this method in

protected PluginDescriptorFinder createPluginDescriptorFinder() {
    if (RuntimeMode.DEVELOPMENT.equals(getRuntimeMode())) {
        return new PropertiesPluginDescriptorFinder();
    }

    return new DefaultPluginDescriptorFinder(getPluginClasspath());
}

but your code is exactly the same with the default implementation:

protected PluginDescriptorFinder createPluginDescriptorFinder() {
    if (RuntimeMode.DEVELOPMENT.equals(getRuntimeMode())) {
        return new PropertiesPluginDescriptorFinder();
    }

    return new DefaultPluginDescriptorFinder(pluginClasspath);
}

@decebals
Copy link
Member

decebals commented Sep 8, 2015

Other comments for your gist.

JarPluginClasspath implementation is to verbose. A short version could be:

public class JarPluginClasspath extends PluginClasspath {

    public JarPluginClasspath() {
        super();
    }

    protected void addResources() {
        classesDirectories.add(".");
    }

}

@decebals
Copy link
Member

decebals commented Sep 8, 2015

To be honest I don't see the value for a big jar plugin (jar with dependencies) versus a zip plugin (with the default layout: classes and lib) but this is other story.

@tuxedo0801
Copy link
Author

You're absolutely right. It's enough if pluginsDirectory is protected. That would be sufficient for overwriting the DefaultPluginManager.

The method "getPluginClasspath()" is also not required. It's a try&error-relict while trying to hack the JarPluginManager. Sorry for the confusion.

I updated the gist sample files + added a partial pom.xml for a plugin.

To be honest I don't see the value for a big jar plugin (jar with dependencies) versus a zip plugin (with the default layout: classes and lib) but this is other story.

The advantage is:

  • No additional assembly.xml per plugin, less xml in pom.xml
  • One can depend in parent/distribution maven project on the plugin artifact like this:
        <dependency>
            <groupId>de.root1.kad</groupId>
            <artifactId>kad-logic-plugin</artifactId>
            <version>1.0.0-SNAPSHOT</version>;.cdelmpru
            <classifier>jar-with-dependencies</classifier>
        </dependency>

which enables you to use the plugin, f.i. in another assembly (which packages the main application plus required packages into a distribution zip) like this:

assembly.xml

.....
        <dependencySet>
            <includes>
                <include>de.root1.kad:kad-logic-plugin::jar-with-dependencies</include>
            </includes>
            <outputDirectory>plugins</outputDirectory>
            <useProjectAttachments>true</useProjectAttachments>
        </dependencySet>
.....

With that, I'm now in the position of specifiying the version of my main-application plus the factory-default-plugins with its version in the pom of the "distribution" project and bundle all the stuff together to big distribution zip.

Maybe there are other ways of handling .zip artifacts of projects and bundle them together with maven assembly plugin. But that's the default way the maven documentation describes.

Beside that: The ZIP files worked well. I don't see the requirement of having the JarPluginManager in PF4J project. But there should be the option to overwrite the DefaultPluginManager to create a custom manager.

@decebals
Copy link
Member

decebals commented Sep 8, 2015

Probably the best option is to extend DefaultPluginManager (are a lot of stuff that can be configured via createXYZ factory methods. To implement a PluginManger from zero I think that it's a hard work.

@decebals
Copy link
Member

decebals commented Sep 8, 2015

If you need more help please tell me. Don't forget to close this PR if everything is OK.

@tuxedo0801
Copy link
Author

Probably the best option is to extend DefaultPluginManager (are a lot of stuff that can be configured via createXYZ factory methods.)

That was also my feeling. Maybe it's also a good idea to set a few other fields to "protected" instead of private? Otherwise overwriting other createXYZ methods could result in the same issue...

For me and my "special case" it's okay now. Thanks for changing the code.

@tuxedo0801 tuxedo0801 closed this Sep 8, 2015
@decebals
Copy link
Member

decebals commented Sep 8, 2015

That was also my feeling. Maybe it's also a good idea to set a few other fields to "protected" instead of private? Otherwise overwriting other createXYZ methods could result in the same issue...

Sure, I will do this step by step (on request).

@tuxedo0801
Copy link
Author

I'm working on an JarPluginManager which does not need to extract the jar archive. Will see if this works and what else needs to be changed in visibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants