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

plugin manifest issues #70

Closed
tuxedo0801 opened this issue Sep 17, 2015 · 2 comments · Fixed by #72
Closed

plugin manifest issues #70

tuxedo0801 opened this issue Sep 17, 2015 · 2 comments · Fixed by #72

Comments

@tuxedo0801
Copy link

As explained in another issue/post, I create my plugins not as ZIP but as a single jar containing all dependencies.

For that I use the following build-plugin with maven:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.5.5</version>

                <executions>
                    <execution>
                        <id>make-plugin-assembly</id>
                        <!-- extend phase package to assembly the archives -->
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <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>
                            <finalName>${project.build.finalName}.plugin</finalName>
                            <appendAssemblyId>false</appendAssemblyId>
                        </configuration>
                    </execution>
                </executions>
            </plugin>   

Works quite well. Now I wanted to have the plugin-properties not in pom.xml

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>

        <plugin.id>de.root1.kad-logicplugin</plugin.id>
        <plugin.class>de.root1.kad.logicplugin.LogicPlugin</plugin.class>
        <plugin.version>1.0.0</plugin.version>
        <plugin.provider>Alexander Christian</plugin.provider>
        <plugin.dependencies></plugin.dependencies>        
    </properties>

but in an external plugin.properties file (makes life easier when using development-runtimemode). To not need to define plugin-properties twice (pom + properties), I used the following maven-build-plugin to read it from properties-file and use it in pom:

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>properties-maven-plugin</artifactId>
                <version>1.0-alpha-2</version>
                <executions>
                    <execution>
                        <id>read-plugin-properties</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>read-project-properties</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <files>
                        <file>${basedir}/plugin.properties</file>
                    </files>
                </configuration>
            </plugin>

Works in principle, but creates an name-conflict... It tooks me 2hrs to find the root-cause:

The pom variable ${plugin.id} is not only used by pf4j/it's plugin-configuration, but also by the maven assembly plugin... BUT: This only get's visible when reading the properties from properties-file. As long as you define the properties directly in pom.xml, ${plugin.id} will have the value we defined by outselves, don't matter where in the pom-file you use it.
If the property is read from propert-file (not direclty defined in pom), ${plugin.id} will contain the plugin-id of the build-plugin you're currenty configuring. In this case, it is "org.apache.maven.plugins:maven-assembly-plugin:2.5.5".

And it's getting further:

With ${plugin.class} you get an exception when running maven build:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.5.5:single (make-plugin-assembly) on project logicplugin: A type incompatibility occured while executing org.apache.maven.plugins:maven-assembly-plugin:2.5.5:single: java.lang.Class cannot be cast to java.lang.String

So ${plugin.class} at this point is not containing the plugin-class-string, but the plugin class object...

Maybe this is a kind of special case, as most users will not do that "advanced stuff" that I do.
But I recommend anyway to not use conflicting names.
Maybe prefix all the plugin-property-names with "pf4j." ....

I tried to overcome this issue with having my own manifestPluginDescriptorFinder... But again, some "private" tags prevent me from doing this... :-(

The ManifestPluginDescriptorFinder itself can be overwritten, but it depends on the Plugindescriptor, which has the "setXYZ()" methods package-private :-(

I would overcome also this by overwriting it and having a large constructor instead of using all the package-private setter... But this would be more a hack than "good code".

So, finally, two things should change:

  1. prefix the plugin-properties with "pf4j."
  2. enable the user to have an own prefix by overwriting *PluginDescriptorFinder (which is in principle already possible) and enable access to PluginDescriptor to set (somehow) the required values (so that overwriting *PlugindescriptorFinder makes sense.

br,
Alex

@tuxedo0801
Copy link
Author

Could be a bigger change for pf4j ...

So in the meantime I worked around it by implementing PluginDescriptorFinder and overwriting PluginDescriptor.

The custom PluginDescriptorFinder reads my prefixed manifest entries/properties and uses a custom PluginDescriptor which ignores all the setters and use the constructor for setting the values instead.

It's far away from beautiful, but works.

@decebals
Copy link
Member

We can add a new method in each class.
In PropertiesPluginDescriptorFinder a new method getPropertyNameFor(field) and in ManifestPluginDescriptorFinder a new method getAttributeNameFor(field), where field is a constant (ID, DESCRIPTION, CLASS, ...). I don't know yet if it's a good idea but it's an idea 😄

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 a pull request may close this issue.

2 participants