--- /dev/null
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.pf4j</groupId>
+ <artifactId>pf4j-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>pf4j-quickstart</artifactId>
+ <packaging>maven-archetype</packaging>
+ <name>Quickstart Archetype</name>
+
+ <build>
+ <!-- http://stackoverflow.com/questions/7223031/how-to-embed-archetype-project-version-in-maven-archetype -->
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>archetype-resources/**/pom.xml</include>
+ </includes>
+ </resource>
+
+ <resource>
+ <filtering>false</filtering>
+ <directory>src/main/resources</directory>
+ <excludes>
+ <exclude>archetype-resources/**/pom.xml</exclude>
+ </excludes>
+ </resource>
+ </resources>
+
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.archetype</groupId>
+ <artifactId>archetype-packaging</artifactId>
+ <version>2.3</version>
+ </extension>
+ </extensions>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-archetype-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+
+ <!-- http://stackoverflow.com/questions/7223031/how-to-embed-archetype-project-version-in-maven-archetype -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.5</version>
+ <configuration>
+ <delimiters>
+ <delimiter>{{*}}</delimiter>
+ </delimiters>
+ <useDefaultDelimiters>false</useDefaultDelimiters>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<archetype-descriptor name="quickstart">
+
+ <fileSets>
+ <fileSet encoding="UTF-8">
+ <directory></directory>
+ <includes>
+ <include>run.sh</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+
+ <modules>
+ <module id="${rootArtifactId}-app" dir="app" name="${rootArtifactId}-app">
+ <fileSets>
+ <fileSet filtered="true" packaged="true" encoding="UTF-8">
+ <directory>src/main/java</directory>
+ <includes>
+ <include>**/*.java</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*.properties</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/assembly</directory>
+ <includes>
+ <include>**/*.xml</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+ </module>
+
+ <module id="${rootArtifactId}-plugins" dir="plugins" name="${rootArtifactId}-plugins">
+ <fileSets>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory></directory>
+ <includes>
+ <include>enabled.txt</include>
+ <include>disabled.txt</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+
+ <modules>
+ <module id="hello-plugin" dir="hello" name="hello-plugin">
+ <fileSets>
+ <fileSet filtered="true" packaged="true" encoding="UTF-8">
+ <directory>src/main/java</directory>
+ <includes>
+ <include>**/*.java</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory></directory>
+ <includes>
+ <include>plugin.properties</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+ </module>
+
+ <module id="welcome-plugin" dir="welcome" name="welcome-plugin">
+ <fileSets>
+ <fileSet filtered="true" packaged="true" encoding="UTF-8">
+ <directory>src/main/java</directory>
+ <includes>
+ <include>**/*.java</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory></directory>
+ <includes>
+ <include>plugin.properties</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+ </module>
+ </modules>
+ </module>
+ </modules>
+
+</archetype-descriptor>
--- /dev/null
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>${groupId}</groupId>
+ <artifactId>${rootArtifactId}</artifactId>
+ <version>${version}</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>${artifactId}</artifactId>
+ <version>${version}</version>
+ <packaging>jar</packaging>
+ <name>App</name>
+
+ <properties>
+ <main.class>${package}.Boot</main.class>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/assembly.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attached</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <classpathPrefix>lib/</classpathPrefix>
+ <mainClass>${main.class}</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.pf4j</groupId>
+ <artifactId>pf4j</artifactId>
+ <version>${pf4j.version}</version>
+ </dependency>
+
+ <!-- Logs -->
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.16</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+<assembly>
+ <id>app</id>
+ <formats>
+ <format>dir</format>
+ <format>zip</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <dependencySets>
+ <dependencySet>
+ <useProjectArtifact>false</useProjectArtifact>
+ <outputDirectory>lib</outputDirectory>
+ <includes>
+ <include>*:jar:*</include>
+ </includes>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <directory>${project.build.directory}</directory>
+ <outputDirectory></outputDirectory>
+ <includes>
+ <include>*.jar</include>
+ </includes>
+ <excludes>
+ <exclude>*-javadoc.jar</exclude>
+ <exclude>*-sources.jar</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+</assembly>
--- /dev/null
+package ${package};
+
+import org.apache.commons.lang.StringUtils;
+import org.pf4j.DefaultPluginManager;
+import org.pf4j.ExtensionFinder;
+import org.pf4j.PluginManager;
+import org.pf4j.PluginWrapper;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A boot class that start the application.
+ */
+public class Boot {
+
+ public static void main(String[] args) {
+ // create the plugin manager
+ PluginManager pluginManager = new DefaultPluginManager();
+
+ // load the plugins
+ pluginManager.loadPlugins();
+
+ // enable a disabled plugin
+// pluginManager.enablePlugin("welcome-plugin");
+
+ // start (active/resolved) the plugins
+ pluginManager.startPlugins();
+
+ // retrieves the extensions for Greeting extension point
+ List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
+ System.out.println(String.format("Found %d extensions for extension point '%s'", greetings.size(), Greeting.class.getName()));
+ for (Greeting greeting : greetings) {
+ System.out.println(">>> " + greeting.getGreeting());
+ }
+
+ // print extensions from classpath (non plugin)
+ System.out.println("Extensions added by classpath:");
+ Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null);
+ for (String extension : extensionClassNames) {
+ System.out.println(" " + extension);
+ }
+
+ System.out.println("Extension classes by classpath:");
+ List<Class<? extends Greeting>> greetingsClasses = pluginManager.getExtensionClasses(Greeting.class);
+ for (Class<? extends Greeting> greeting : greetingsClasses) {
+ System.out.println(" Class: " + greeting.getCanonicalName());
+ }
+
+ // print extensions ids for each started plugin
+ List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins();
+ for (PluginWrapper plugin : startedPlugins) {
+ String pluginId = plugin.getDescriptor().getPluginId();
+ System.out.println(String.format("Extensions added by plugin '%s':", pluginId));
+ extensionClassNames = pluginManager.getExtensionClassNames(pluginId);
+ for (String extension : extensionClassNames) {
+ System.out.println(" " + extension);
+ }
+ }
+
+ // print extensions instances for Greeting extension point for each started plugin
+ for (PluginWrapper plugin : startedPlugins) {
+ String pluginId = plugin.getDescriptor().getPluginId();
+ System.out.println(String.format("Extensions instances added by plugin '%s' for extension point '%s':", pluginId, Greeting.class.getName()));
+ List<Greeting> extensions = pluginManager.getExtensions(Greeting.class, pluginId);
+ for (Object extension : extensions) {
+ System.out.println(" " + extension);
+ }
+ }
+
+ // print extensions instances from classpath (non plugin)
+ System.out.println("Extensions instances added by classpath:");
+ List extensions = pluginManager.getExtensions((String) null);
+ for (Object extension : extensions) {
+ System.out.println(" " + extension);
+ }
+
+ // print extensions instances for each started plugin
+ for (PluginWrapper plugin : startedPlugins) {
+ String pluginId = plugin.getDescriptor().getPluginId();
+ System.out.println(String.format("Extensions instances added by plugin '%s':", pluginId));
+ extensions = pluginManager.getExtensions(pluginId);
+ for (Object extension : extensions) {
+ System.out.println(" " + extension);
+ }
+ }
+
+ // stop the plugins
+ pluginManager.stopPlugins();
+ /*
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+
+ @Override
+ public void run() {
+ pluginManager.stopPlugins();
+ }
+
+ });
+ */
+ }
+
+}
--- /dev/null
+package ${package};
+
+import org.pf4j.ExtensionPoint;
+
+public interface Greeting extends ExtensionPoint {
+
+ String getGreeting();
+
+}
--- /dev/null
+package ${package};
+
+import org.pf4j.Extension;
+
+@Extension
+public class WhazzupGreeting implements Greeting {
+
+ @Override
+ public String getGreeting() {
+ return "Whazzup";
+ }
+
+}
--- /dev/null
+log4j.rootLogger=DEBUG, Console
+
+#
+# PF4J log
+#
+log4j.logger.org.pf4j=DEBUG, Console
+# !!! Put the bellow classes on level TRACE when you are in trouble
+log4j.logger.org.pf4j.PluginClassLoader=DEBUG, Console
+log4j.logger.org.pf4j.AbstractExtensionFinder=DEBUG, Console
+log4j.additivity.org.pf4j=false
+log4j.additivity.org.pf4j.PluginClassLoader=false
+log4j.additivity.org.pf4j.AbstractExtensionFinder=false
+
+#
+# Appenders
+#
+log4j.appender.Console=org.apache.log4j.ConsoleAppender
+log4j.appender.Console.layout=org.apache.log4j.PatternLayout
+#log4j.appender.Console.layout.conversionPattern=%-5p - %-32.32c{1} - %m\n
+log4j.appender.Console.layout.ConversionPattern=%d %p %c - %m%n
--- /dev/null
+########################################
+# - load all plugins except these
+# - add one plugin id on each line
+# - put this file in plugins folder
+########################################
+#welcome-plugin
--- /dev/null
+########################################
+# - load only these plugins
+# - add one plugin id on each line
+# - put this file in plugins folder
+########################################
+#welcome-plugin
--- /dev/null
+plugin.id=hello-plugin
+plugin.class=${package}.hello.HelloPlugin
+plugin.version=${version}
+plugin.provider=
+plugin.dependencies=
--- /dev/null
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>${groupId}</groupId>
+ <artifactId>${rootArtifactId}-plugins</artifactId>
+ <version>${version}</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>hello-plugin</artifactId>
+ <version>${version}</version>
+ <packaging>jar</packaging>
+ <name>Hello Plugin</name>
+
+ <properties>
+ <plugin.id>hello-plugin</plugin.id>
+ <plugin.class>${package}.hello.HelloPlugin</plugin.class>
+ <plugin.version>${version}</plugin.version>
+ <plugin.provider/>
+ <plugin.dependencies/>
+ </properties>
+
+</project>
--- /dev/null
+package ${package}.hello;
+
+import org.pf4j.Extension;
+import org.pf4j.Plugin;
+import org.pf4j.PluginWrapper;
+import ${package}.Greeting;
+
+/**
+ * A very simple plugin.
+ */
+public class HelloPlugin extends Plugin {
+
+ public HelloPlugin(PluginWrapper wrapper) {
+ super(wrapper);
+ }
+
+ @Override
+ public void start() {
+ System.out.println("HelloPlugin.start()");
+ }
+
+ @Override
+ public void stop() {
+ System.out.println("HelloPlugin.stop()");
+ }
+
+ @Extension(ordinal=1)
+ public static class HelloGreeting implements Greeting {
+
+ @Override
+ public String getGreeting() {
+ return "Hello";
+ }
+
+ }
+
+}
--- /dev/null
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>${groupId}</groupId>
+ <artifactId>${rootArtifactId}</artifactId>
+ <version>${version}</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>${artifactId}</artifactId>
+ <version>${version}</version>
+ <packaging>pom</packaging>
+ <name>Plugins Parent</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+
+ <!-- Override below properties in each plugin's pom.xml -->
+ <plugin.id></plugin.id>
+ <plugin.class></plugin.class>
+ <plugin.version></plugin.version>
+ <plugin.provider></plugin.provider>
+ <plugin.dependencies></plugin.dependencies>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>3.1.0</version>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <finalName>${project.artifactId}-${project.version}-all</finalName>
+ <appendAssemblyId>false</appendAssemblyId>
+ <attach>false</attach>
+ <archive>
+ <manifest>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ </manifest>
+ <manifestEntries>
+ <Plugin-Id>${plugin.id}</Plugin-Id>
+ <Plugin-Version>${plugin.version}</Plugin-Version>
+ <Plugin-Provider>${plugin.provider}</Plugin-Provider>
+ <Plugin-Class>${plugin.class}</Plugin-Class>
+ <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.pf4j</groupId>
+ <artifactId>pf4j</artifactId>
+ <version>${pf4j.version}</version>
+ <!-- !!! VERY IMPORTANT -->
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${groupId}</groupId>
+ <artifactId>${rootArtifactId}-app</artifactId>
+ <version>${version}</version>
+ <!-- !!! VERY IMPORTANT -->
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+plugin.id=welcome-plugin
+plugin.class=${package}.welcome.WelcomePlugin
+plugin.version=${version}
+plugin.provider=
+plugin.dependencies=
--- /dev/null
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>${groupId}</groupId>
+ <artifactId>${rootArtifactId}-plugins</artifactId>
+ <version>${version}</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>welcome-plugin</artifactId>
+ <version>${version}</version>
+ <packaging>jar</packaging>
+ <name>Welcom Plugin</name>
+
+ <properties>
+ <plugin.id>welcome-plugin</plugin.id>
+ <plugin.class>${package}.welcome.WelcomePlugin</plugin.class>
+ <plugin.version>${version}</plugin.version>
+ <plugin.provider/>
+ <plugin.dependencies/>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+package ${package}.welcome;
+
+import org.apache.commons.lang.StringUtils;
+
+import org.pf4j.PluginWrapper;
+import org.pf4j.RuntimeMode;
+import org.pf4j.Extension;
+import org.pf4j.Plugin;
+import ${package}.Greeting;
+
+public class WelcomePlugin extends Plugin {
+
+ public WelcomePlugin(PluginWrapper wrapper) {
+ super(wrapper);
+ }
+
+ @Override
+ public void start() {
+ System.out.println("WelcomePlugin.start()");
+ // for testing the development mode
+ if (RuntimeMode.DEVELOPMENT.equals(wrapper.getRuntimeMode())) {
+ System.out.println(StringUtils.upperCase("WelcomePlugin"));
+ }
+ }
+
+ @Override
+ public void stop() {
+ System.out.println("WelcomePlugin.stop()");
+ }
+
+ @Extension
+ public static class WelcomeGreeting implements Greeting {
+
+ @Override
+ public String getGreeting() {
+ return "Welcome";
+ }
+
+ }
+
+}
--- /dev/null
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>${groupId}</groupId>
+ <artifactId>${artifactId}</artifactId>
+ <version>${version}</version>
+ <packaging>pom</packaging>
+ <name>PF4J Quickstart</name>
+
+ <repositories>
+ <repository>
+ <id>sonatype-nexus-snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.release>8</maven.compiler.release>
+
+ <pf4j.version>{{project.version}}</pf4j.version>
+ <slf4j.version>1.7.7</slf4j.version>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>false</filtering>
+ <directory>src/main/java</directory>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+
+</project>
--- /dev/null
+#!/bin/sh
+
+# create artifacts using Maven
+mvn clean package -DskipTests
+
+# create "dist" directory
+rm -fr dist
+mkdir -p dist/plugins
+
+# copy plugins to "dist" directory
+cp plugins/*/target/*-all.jar dist/plugins/
+cp plugins/enabled.txt dist/plugins/
+cp plugins/disabled.txt dist/plugins/
+
+cd dist
+
+# unzip app to "dist" directory
+jar xf ../app/target/*.zip
+
+# run app
+java -jar *.jar
+
+cd -
<modules>
<module>pf4j</module>
<module>demo</module>
+ <module>maven-archetypes/quickstart</module>
</modules>
<profiles>