+++ /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.demo</groupId>
- <artifactId>pf4j-demo-parent</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>pf4j-demo-api</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>Demo Api</name>
-
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-deploy-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.pf4j</groupId>
- <artifactId>pf4j</artifactId>
- <version>${project.version}</version>
- <!-- !!! VERY IMPORTANT -->
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
-</project>
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.api;
-
-import org.pf4j.Plugin;
-
-/**
- * Base {@link Plugin} for all demo plugins.
- *
- * @author Decebal Suiu
- */
-public abstract class DemoPlugin extends Plugin {
-
- protected final PluginContext context;
-
- protected DemoPlugin(PluginContext context) {
- super();
-
- this.context = context;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.api;
-
-import org.pf4j.ExtensionPoint;
-
-/**
- * @author Decebal Suiu
- */
-public interface Greeting extends ExtensionPoint {
-
- String getGreeting();
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.api;
-
-import org.pf4j.RuntimeMode;
-
-/**
- * An instance of this class is provided to plugins in their constructor.
- * It's safe for plugins to keep a reference to the instance for later use.
- * This class facilitates communication with application and plugin manager.
- *
- * @author Decebal Suiu
- */
-public class PluginContext {
-
- private final RuntimeMode runtimeMode;
-
- public PluginContext(RuntimeMode runtimeMode) {
- this.runtimeMode = runtimeMode;
- }
-
- public RuntimeMode getRuntimeMode() {
- return runtimeMode;
- }
-
-}
+++ /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.demo</groupId>
- <artifactId>pf4j-demo-parent</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>pf4j-demo-app</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>Demo App</name>
-
- <properties>
- <main.class>org.pf4j.demo.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>
- <configuration>
- <archive>
- <manifest>
- <addClasspath>true</addClasspath>
- <classpathPrefix>lib/</classpathPrefix>
- <mainClass>${main.class}</mainClass>
- </manifest>
- </archive>
- </configuration>
- </plugin>
-
- <plugin>
- <artifactId>maven-deploy-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.pf4j</groupId>
- <artifactId>pf4j</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.pf4j.demo</groupId>
- <artifactId>pf4j-demo-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <!-- Logging -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>${slf4j.version}</version>
- </dependency>
-
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.4</version>
- </dependency>
- </dependencies>
-
-</project>
+++ /dev/null
-<!--
- Describes the dist
-
- @author Decebal Suiu
- @version 1.0
--->
-<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
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo;
-
-import org.apache.commons.lang.StringUtils;
-import org.pf4j.PluginManager;
-import org.pf4j.PluginWrapper;
-import org.pf4j.demo.api.Greeting;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * A boot class that start the demo.
- *
- * @author Decebal Suiu
- */
-public class Boot {
-
- private static final Logger log = LoggerFactory.getLogger(Boot.class);
-
- public static void main(String[] args) {
- // print logo
- printLogo();
-
- // create the plugin manager
- PluginManager pluginManager = new DemoPluginManager();
-
- // 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);
- log.info("Found {} extensions for extension point '{}'", greetings.size(), Greeting.class.getName());
- for (Greeting greeting : greetings) {
- log.info(">>> {}", greeting.getGreeting());
- }
-
- // print extensions from classpath (non plugin)
- log.info("Extensions added by classpath:");
- Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null);
- for (String extension : extensionClassNames) {
- log.info(" {}", extension);
- }
-
- log.info("Extension classes by classpath:");
- List<Class<? extends Greeting>> greetingsClasses = pluginManager.getExtensionClasses(Greeting.class);
- for (Class<? extends Greeting> greeting : greetingsClasses) {
- log.info(" Class: {}", greeting.getCanonicalName());
- }
-
- // print extensions ids for each started plugin
- List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins();
- for (PluginWrapper plugin : startedPlugins) {
- String pluginId = plugin.getDescriptor().getPluginId();
- log.info("Extensions added by plugin '{}}':", pluginId);
- extensionClassNames = pluginManager.getExtensionClassNames(pluginId);
- for (String extension : extensionClassNames) {
- log.info(" {}", extension);
- }
- }
-
- // print the extensions instances for Greeting extension point for each started plugin
- for (PluginWrapper plugin : startedPlugins) {
- String pluginId = plugin.getDescriptor().getPluginId();
- log.info("Extensions instances added by plugin '{}' for extension point '{}':", pluginId, Greeting.class.getName());
- List<Greeting> extensions = pluginManager.getExtensions(Greeting.class, pluginId);
- for (Object extension : extensions) {
- log.info(" {}", extension);
- }
- }
-
- // print extensions instances from classpath (non plugin)
- log.info("Extensions instances added by classpath:");
- List<?> extensions = pluginManager.getExtensions((String) null);
- for (Object extension : extensions) {
- log.info(" {}", extension);
- }
-
- // print extensions instances for each started plugin
- for (PluginWrapper plugin : startedPlugins) {
- String pluginId = plugin.getDescriptor().getPluginId();
- log.info("Extensions instances added by plugin '{}':", pluginId);
- extensions = pluginManager.getExtensions(pluginId);
- for (Object extension : extensions) {
- log.info(" {}", extension);
- }
- }
-
- // stop the plugins
- pluginManager.stopPlugins();
- /*
- Runtime.getRuntime().addShutdownHook(new Thread() {
-
- @Override
- public void run() {
- pluginManager.stopPlugins();
- }
-
- });
- */
- }
-
- private static void printLogo() {
- log.info(StringUtils.repeat("#", 40));
- log.info(StringUtils.center("PF4J-DEMO", 40));
- log.info(StringUtils.repeat("#", 40));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo;
-
-import java.lang.reflect.Constructor;
-import org.pf4j.DefaultPluginFactory;
-import org.pf4j.Plugin;
-import org.pf4j.PluginWrapper;
-import org.pf4j.demo.api.PluginContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class DemoPluginFactory extends DefaultPluginFactory {
-
- private static final Logger log = LoggerFactory.getLogger(DemoPluginFactory.class);
-
- @Override
- protected Plugin createInstance(Class<?> pluginClass, PluginWrapper pluginWrapper) {
- PluginContext context = new PluginContext(pluginWrapper.getRuntimeMode());
- try {
- Constructor<?> constructor = pluginClass.getConstructor(PluginContext.class);
- return (Plugin) constructor.newInstance(context);
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- }
-
- return null;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo;
-
-import org.pf4j.DefaultExtensionFinder;
-import org.pf4j.DefaultPluginFactory;
-import org.pf4j.DefaultPluginManager;
-import org.pf4j.ExtensionFinder;
-import org.pf4j.PluginFactory;
-
-class DemoPluginManager extends DefaultPluginManager {
-
- // Use below code if you want to enable ServiceProviderExtensionFinder
- /*
- @Override
- protected ExtensionFinder createExtensionFinder() {
- DefaultExtensionFinder extensionFinder = (DefaultExtensionFinder) super.createExtensionFinder();
- extensionFinder.addServiceProviderExtensionFinder(); // to activate "HowdyGreeting" extension
-
- return extensionFinder;
- }
- */
-
- @Override
- protected PluginFactory createPluginFactory() {
- return new DemoPluginFactory();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo;
-
-import org.pf4j.demo.api.Greeting;
-
-/**
- * A Service Implementation (no @Extension) declared via Java Service Provider mechanism (using META-INF/services).
- *
- * @author Decebal Suiu
- */
-public class HowdyGreeting implements Greeting {
-
- @Override
- public String getGreeting() {
- return "Howdy";
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo;
-
-import org.pf4j.Extension;
-import org.pf4j.demo.api.Greeting;
-
-/**
- * @author Decebal Suiu
- */
-@Extension
-public class WhazzupGreeting implements Greeting {
-
- @Override
- public String getGreeting() {
- return "Whazzup";
- }
-
-}
+++ /dev/null
-org.pf4j.demo.HowdyGreeting
+++ /dev/null
-# SLF4J's SimpleLogger configuration file
-# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
-
-# Default logging detail level for all instances of SimpleLogger.
-# Must be one of ("trace", "debug", "info", "warn", or "error").
-# If not specified, defaults to "info".
-org.slf4j.simpleLogger.defaultLogLevel=debug
-
-# Logging detail level for a SimpleLogger instance named "xxxxx".
-# Must be one of ("trace", "debug", "info", "warn", or "error").
-# If not specified, the default logging detail level is used.
-#org.slf4j.simpleLogger.log.xxxxx=
-# !!! Uncomment below loggers when you are in trouble
-#org.slf4j.simpleLogger.log.org.pf4j.PluginClassLoader=trace
-#org.slf4j.simpleLogger.log.org.pf4j.AbstractExtensionFinder=trace
-
-# Set to true if you want the current date and time to be included in output messages.
-# Default is false, and will output the number of milliseconds elapsed since startup.
-#org.slf4j.simpleLogger.showDateTime=false
-org.slf4j.simpleLogger.showDateTime=true
-
-# The date and time format to be used in the output messages.
-# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
-# If the format is not specified or is invalid, the default format is used.
-# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
-#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
-org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss
-
-# Set to true if you want to output the current thread name.
-# Defaults to true.
-#org.slf4j.simpleLogger.showThreadName=true
-
-# Set to true if you want the Logger instance name to be included in output messages.
-# Defaults to true.
-#org.slf4j.simpleLogger.showLogName=true
-
-# Set to true if you want the last component of the name to be included in output messages.
-# Defaults to false.
-#org.slf4j.simpleLogger.showShortLogName=false
--- /dev/null
+build
+.gradle
+.idea
--- /dev/null
+# PF4J Gradle Demo
+
+This demo assumes that you know the basics of Gradle (Please look at [gradle](https://gradle.org/) for more info)
+
+### Setup/Build
+
+1. Clone the repo
+2. Go to demo_gradle `cd demo_gradle`
+3. run `./gradlew build`
+
+* This will produce one jar, named app-plugin-demo-uberjar.jar, located in the `app/build/libs/` directory and three plugins zips located in `build/plugins` directory.
+* The plugins are `plugin-hello-plugin-0.0.1.zip`, `plugin-KotlinPlugin-1.0.0.zip` and `plugin-welcome-plugin-0.0.1.zip`
+
+### Run the demo
+
+1. Run
+
+```
+ ./gradlew app:run
+```
+
+2. The demo's output should look similar to: (Please see `Boot#main()` for more details)
+```
+[main] INFO org.pf4j.demo.Boot - ########################################
+[main] INFO org.pf4j.demo.Boot - PF4J-DEMO
+[main] INFO org.pf4j.demo.Boot - ########################################
+[main] INFO org.pf4j.DefaultPluginStatusProvider - Enabled plugins: []
+[main] INFO org.pf4j.DefaultPluginStatusProvider - Disabled plugins: []
+[main] INFO org.pf4j.DefaultPluginManager - PF4J version 3.1.0 in 'deployment' mode
+[main] INFO org.pf4j.util.FileUtils - Expanded plugin zip 'plugin-hello-plugin-0.0.1.zip' in 'plugin-hello-plugin-0.0.1'
+[main] INFO org.pf4j.util.FileUtils - Expanded plugin zip 'plugin-KotlinPlugin-1.0.0.zip' in 'plugin-KotlinPlugin-1.0.0'
+[main] INFO org.pf4j.util.FileUtils - Expanded plugin zip 'plugin-welcome-plugin-0.0.1.zip' in 'plugin-welcome-plugin-0.0.1'
+[main] INFO org.pf4j.AbstractPluginManager - Plugin 'welcome-plugin@0.0.1' resolved
+[main] INFO org.pf4j.AbstractPluginManager - Plugin 'KotlinPlugin@1.0.0' resolved
+[main] INFO org.pf4j.AbstractPluginManager - Plugin 'hello-plugin@0.0.1' resolved
+[main] INFO org.pf4j.AbstractPluginManager - Start plugin 'welcome-plugin@0.0.1'
+[main] INFO org.pf4j.demo.welcome.WelcomePlugin - WelcomePlugin.start()
+[main] INFO org.pf4j.demo.welcome.WelcomePlugin - WELCOMEPLUGIN
+[main] INFO org.pf4j.AbstractPluginManager - Start plugin 'KotlinPlugin@1.0.0'
+[main] INFO org.pf4j.demo.kotlin.KotlinPlugin - KotlinPlugin.start()
+[main] INFO org.pf4j.demo.kotlin.KotlinPlugin - KOTLINPLUGIN
+[main] INFO org.pf4j.AbstractPluginManager - Start plugin 'hello-plugin@0.0.1'
+[main] INFO org.pf4j.demo.hello.HelloPlugin - HelloPlugin.start()
+[main] INFO org.pf4j.demo.Boot - Plugindirectory:
+[main] INFO org.pf4j.demo.Boot - ../build/plugins
+
+[main] INFO org.pf4j.demo.Boot - Found 4 extensions for extension point 'org.pf4j.demo.api.Greeting'
+[main] INFO org.pf4j.demo.Boot - >>> Whazzup
+[main] INFO org.pf4j.demo.Boot - >>> Welcome
+[main] INFO org.pf4j.demo.Boot - >>> KotlinGreetings
+[main] INFO org.pf4j.demo.Boot - >>> Hello
+[main] INFO org.pf4j.demo.Boot - Extensions added by plugin 'welcome-plugin':
+[main] INFO org.pf4j.demo.Boot - Extensions added by plugin 'KotlinPlugin':
+[main] INFO org.pf4j.demo.Boot - Extensions added by plugin 'hello-plugin':
+[main] INFO org.pf4j.AbstractPluginManager - Stop plugin 'hello-plugin@0.0.1'
+[main] INFO org.pf4j.demo.hello.HelloPlugin - HelloPlugin.stop()
+[main] INFO org.pf4j.AbstractPluginManager - Stop plugin 'KotlinPlugin@1.0.0'
+[main] INFO org.pf4j.demo.kotlin.KotlinPlugin - KotlinPlugin.stop()
+[main] INFO org.pf4j.AbstractPluginManager - Stop plugin 'welcome-plugin@0.0.1'
+[main] INFO org.pf4j.demo.welcome.WelcomePlugin - WelcomePlugin.stop()
+```
+
--- /dev/null
+dependencies {
+ implementation group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}"
+ implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
+
+ testImplementation group: 'junit', name: 'junit', version: '4.+'
+}
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.api;
+
+import org.pf4j.ExtensionPoint;
+
+/**
+ * @author Decebal Suiu
+ */
+public interface Greeting extends ExtensionPoint {
+
+ String getGreeting();
+
+}
--- /dev/null
+apply plugin: 'application'
+
+mainClassName = 'org.pf4j.demo.Boot'
+run {
+ systemProperty 'pf4j.pluginsDir', '../build/plugins'
+}
+
+dependencies {
+ implementation project(':api')
+ implementation group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}"
+ annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
+ implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
+ implementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'
+
+ testImplementation group: 'junit', name: 'junit', version: '4.+'
+}
+
+task uberjar(type: Jar, dependsOn: ['compileJava']) {
+ zip64 true
+ from configurations.runtimeClasspath.asFileTree.files.collect {
+ exclude "META-INF/*.SF"
+ exclude "META-INF/*.DSA"
+ exclude "META-INF/*.RSA"
+ zipTree(it)
+ }
+ from files(sourceSets.main.output.classesDirs)
+ from files(sourceSets.main.resources)
+ manifest {
+ attributes 'Main-Class': mainClassName
+ }
+
+ archiveBaseName = "${project.name}-plugin-demo"
+ archiveClassifier = "uberjar"
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo;
+
+import org.apache.commons.lang3.StringUtils;
+import org.pf4j.CompoundPluginDescriptorFinder;
+import org.pf4j.ManifestPluginDescriptorFinder;
+import org.pf4j.PropertiesPluginDescriptorFinder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.pf4j.DefaultPluginManager;
+import org.pf4j.PluginManager;
+import org.pf4j.PluginWrapper;
+import org.pf4j.demo.api.Greeting;
+
+import java.util.List;
+
+/**
+ * A boot class that start the demo.
+ *
+ * @author Decebal Suiu
+ */
+public class Boot {
+ private static final Logger logger = LoggerFactory.getLogger(Boot.class);
+
+ public static void main(String[] args) {
+ // print logo
+ printLogo();
+
+ // create the plugin manager
+ final PluginManager pluginManager = new DefaultPluginManager() {
+ @Override
+ protected CompoundPluginDescriptorFinder createPluginDescriptorFinder() {
+ return new CompoundPluginDescriptorFinder()
+ // Demo is using the Manifest file
+ // PropertiesPluginDescriptorFinder is commented out just to avoid error log
+ //.add(new PropertiesPluginDescriptorFinder())
+ .add(new ManifestPluginDescriptorFinder());
+ }
+ };
+
+ // load the plugins
+ pluginManager.loadPlugins();
+
+ // enable a disabled plugin
+// pluginManager.enablePlugin("welcome-plugin");
+
+ // start (active/resolved) the plugins
+ pluginManager.startPlugins();
+
+ logger.info("Plugindirectory: ");
+ logger.info("\t" + System.getProperty("pf4j.pluginsDir", "plugins") + "\n");
+
+ // retrieves the extensions for Greeting extension point
+ List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
+ logger.info(String.format("Found %d extensions for extension point '%s'", greetings.size(), Greeting.class.getName()));
+ for (Greeting greeting : greetings) {
+ logger.info(">>> " + greeting.getGreeting());
+ }
+
+ // // print extensions from classpath (non plugin)
+ // logger.info(String.format("Extensions added by classpath:"));
+ // Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null);
+ // for (String extension : extensionClassNames) {
+ // logger.info(" " + extension);
+ // }
+
+ // print extensions for each started plugin
+ List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins();
+ for (PluginWrapper plugin : startedPlugins) {
+ String pluginId = plugin.getDescriptor().getPluginId();
+ logger.info(String.format("Extensions added by plugin '%s':", pluginId));
+ // extensionClassNames = pluginManager.getExtensionClassNames(pluginId);
+ // for (String extension : extensionClassNames) {
+ // logger.info(" " + extension);
+ // }
+ }
+
+ // stop the plugins
+ pluginManager.stopPlugins();
+ /*
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+
+ @Override
+ public void run() {
+ pluginManager.stopPlugins();
+ }
+
+ });
+ */
+ }
+
+ private static void printLogo() {
+ logger.info(StringUtils.repeat("#", 40));
+ logger.info(StringUtils.center("PF4J-DEMO", 40));
+ logger.info(StringUtils.repeat("#", 40));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo;
+
+import org.pf4j.Extension;
+import org.pf4j.demo.api.Greeting;
+
+/**
+ * @author Decebal Suiu
+ */
+@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
+log4j.logger.org.pf4j.PluginClassLoader=WARN, Console
+log4j.additivity.org.pf4j=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
+subprojects {
+ apply plugin: 'java'
+
+ repositories {
+ mavenLocal()
+ mavenCentral()
+ }
+}
+// plugin location
+ext.pluginsDir = rootProject.buildDir.path + '/plugins'
+
+task build(dependsOn: [':app:uberjar'])
+
+
--- /dev/null
+# PF4J
+pf4jVersion=3.1.0
--- /dev/null
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
--- /dev/null
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
--- /dev/null
+@rem\r
+@rem Copyright 2015 the original author or authors.\r
+@rem\r
+@rem Licensed under the Apache License, Version 2.0 (the "License");\r
+@rem you may not use this file except in compliance with the License.\r
+@rem You may obtain a copy of the License at\r
+@rem\r
+@rem https://www.apache.org/licenses/LICENSE-2.0\r
+@rem\r
+@rem Unless required by applicable law or agreed to in writing, software\r
+@rem distributed under the License is distributed on an "AS IS" BASIS,\r
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+@rem See the License for the specific language governing permissions and\r
+@rem limitations under the License.\r
+@rem\r
+\r
+@if "%DEBUG%"=="" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%"=="" set DIRNAME=.\r
+@rem This is normally unused\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.\r
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if %ERRORLEVEL% equ 0 goto execute\r
+\r
+echo. 1>&2\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2\r
+echo. 1>&2\r
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2\r
+echo location of your Java installation. 1>&2\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto execute\r
+\r
+echo. 1>&2\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2\r
+echo. 1>&2\r
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2\r
+echo location of your Java installation. 1>&2\r
+\r
+goto fail\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if %ERRORLEVEL% equ 0 goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+set EXIT_CODE=%ERRORLEVEL%\r
+if %EXIT_CODE% equ 0 set EXIT_CODE=1\r
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%\r
+exit /b %EXIT_CODE%\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
--- /dev/null
+subprojects {
+ jar {
+ manifest {
+ attributes 'Plugin-Class': "${pluginClass}",
+ 'Plugin-Id': "${pluginId}",
+ 'Plugin-Version': "${archiveVersion}",
+ 'Plugin-Provider': "${pluginProvider}",
+ 'Plugin-Dependencies': "${pluginDependencies}"
+ }
+ }
+
+ task plugin(type: Jar) {
+ archiveBaseName = "plugin-${pluginId}"
+ into('classes') {
+ with jar
+ }
+ into('lib') {
+ from configurations.runtimeClasspath
+ }
+ archiveExtension ='zip'
+ }
+
+ task assemblePlugin(type: Copy) {
+ from plugin
+ into pluginsDir
+ }
+}
+
+task assemblePlugins(type: Copy) {
+ dependsOn subprojects.assemblePlugin
+}
+
+build.dependsOn project.tasks.assemblePlugins
--- /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
+dependencies {
+ // compileOnly important!!! We do not want to put the api into the zip file since the main program has it already!
+ compileOnly project(':api')
+ compileOnly(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
+ exclude group: "org.slf4j"
+ }
+ annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
+ implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
+ implementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'
+ testImplementation group: 'junit', name: 'junit', version: '4.+'
+}
--- /dev/null
+version=0.0.1
+
+pluginId=welcome-plugin
+pluginClass=org.pf4j.demo.welcome.WelcomePlugin
+pluginProvider=Decebal Suiu
+pluginDependencies=
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.welcome;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.pf4j.Extension;
+import org.pf4j.Plugin;
+import org.pf4j.PluginWrapper;
+import org.pf4j.demo.api.Greeting;
+
+/**
+ * @author Decebal Suiu
+ */
+public class WelcomePlugin extends Plugin {
+
+ private static final Logger logger = LoggerFactory.getLogger(WelcomePlugin.class);
+
+ public WelcomePlugin(PluginWrapper wrapper) {
+ super(wrapper);
+ }
+
+ @Override
+ public void start() {
+ logger.info("WelcomePlugin.start()");
+ logger.info(StringUtils.upperCase("WelcomePlugin"));
+ }
+
+ @Override
+ public void stop() {
+ logger.info("WelcomePlugin.stop()");
+ }
+
+ @Extension
+ public static class WelcomeGreeting implements Greeting {
+
+ @Override
+ public String getGreeting() {
+ return "Welcome";
+ }
+
+ }
+
+}
--- /dev/null
+dependencies {
+ // compileOnly important!!! We do not want to put the api into the zip file since the main program has it already!
+ compileOnly project(':api')
+ compileOnly(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
+ exclude group: "org.slf4j"
+ }
+ annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
+ implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
+ implementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'
+ testImplementation group: 'junit', name: 'junit', version: '4.+'
+}
--- /dev/null
+version=0.0.1
+
+pluginId=hello-plugin
+pluginClass=org.pf4j.demo.hello.HelloPlugin
+pluginProvider=Decebal Suiu
+pluginDependencies=
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.hello;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.pf4j.Extension;
+import org.pf4j.Plugin;
+import org.pf4j.PluginWrapper;
+import org.pf4j.demo.api.Greeting;
+
+/**
+ * A very simple plugin.
+ *
+ * @author Decebal Suiu
+ */
+public class HelloPlugin extends Plugin {
+ private static final Logger logger = LoggerFactory.getLogger(HelloPlugin.class);
+
+ public HelloPlugin(PluginWrapper wrapper) {
+ super(wrapper);
+ }
+
+ @Override
+ public void start() {
+ logger.info("HelloPlugin.start()");
+ }
+
+ @Override
+ public void stop() {
+ logger.info("HelloPlugin.stop()");
+ }
+
+ @Extension(ordinal=1)
+ public static class HelloGreeting implements Greeting {
+
+ @Override
+ public String getGreeting() {
+ return "Hello";
+ }
+
+ }
+
+}
--- /dev/null
+buildscript {
+ ext.kotlin_version = '1.9.24'
+
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+apply plugin: 'kotlin'
+apply plugin: 'kotlin-kapt'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compileOnly project(':api')
+ compileOnly(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
+ exclude group: "org.slf4j"
+ }
+ kapt(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
+ implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
+ implementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+
+ testImplementation group: 'junit', name: 'junit', version: '4.+'
+}
--- /dev/null
+version=1.0.0
+
+pluginId=KotlinPlugin
+pluginClass=org.pf4j.demo.kotlin.KotlinPlugin
+pluginProvider=Anindya Chatterjee
+pluginDependencies=
--- /dev/null
+/*
+ * Copyright (C) 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.kotlin
+
+import org.apache.commons.lang3.StringUtils
+import org.slf4j.LoggerFactory
+import org.pf4j.Extension
+import org.pf4j.Plugin
+import org.pf4j.PluginWrapper
+import org.pf4j.demo.api.Greeting
+
+/**
+ * A sample plugin written in Kotlin
+ *
+ * @author Anindya Chatterjee
+ */
+class KotlinPlugin(wrapper: PluginWrapper) : Plugin(wrapper) {
+ private val logger = LoggerFactory.getLogger(KotlinPlugin::class.java)
+
+ override fun start() {
+ logger.info("KotlinPlugin.start()")
+ logger.info(StringUtils.upperCase("KotlinPlugin"))
+ }
+
+ override fun stop() {
+ logger.info("KotlinPlugin.stop()")
+ }
+}
+
+@Extension
+class KotlinGreeting : Greeting {
+ override fun getGreeting(): String {
+ return "KotlinGreetings"
+ }
+}
--- /dev/null
+include 'api'
+include 'app'
+
+include 'plugins'
+
+include 'plugins:plugin1'
+include 'plugins:plugin2'
+include 'plugins:plugin3'
--- /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.demo</groupId>
+ <artifactId>pf4j-demo-parent</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>pf4j-demo-api</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Demo Api</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.pf4j</groupId>
+ <artifactId>pf4j</artifactId>
+ <version>${project.version}</version>
+ <!-- !!! VERY IMPORTANT -->
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.api;
+
+import org.pf4j.Plugin;
+
+/**
+ * Base {@link Plugin} for all demo plugins.
+ *
+ * @author Decebal Suiu
+ */
+public abstract class DemoPlugin extends Plugin {
+
+ protected final PluginContext context;
+
+ protected DemoPlugin(PluginContext context) {
+ super();
+
+ this.context = context;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.api;
+
+import org.pf4j.ExtensionPoint;
+
+/**
+ * @author Decebal Suiu
+ */
+public interface Greeting extends ExtensionPoint {
+
+ String getGreeting();
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.api;
+
+import org.pf4j.RuntimeMode;
+
+/**
+ * An instance of this class is provided to plugins in their constructor.
+ * It's safe for plugins to keep a reference to the instance for later use.
+ * This class facilitates communication with application and plugin manager.
+ *
+ * @author Decebal Suiu
+ */
+public class PluginContext {
+
+ private final RuntimeMode runtimeMode;
+
+ public PluginContext(RuntimeMode runtimeMode) {
+ this.runtimeMode = runtimeMode;
+ }
+
+ public RuntimeMode getRuntimeMode() {
+ return runtimeMode;
+ }
+
+}
--- /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.demo</groupId>
+ <artifactId>pf4j-demo-parent</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>pf4j-demo-app</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Demo App</name>
+
+ <properties>
+ <main.class>org.pf4j.demo.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>
+ <configuration>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <classpathPrefix>lib/</classpathPrefix>
+ <mainClass>${main.class}</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.pf4j</groupId>
+ <artifactId>pf4j</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- Logging -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+<!--
+ Describes the dist
+
+ @author Decebal Suiu
+ @version 1.0
+-->
+<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
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo;
+
+import org.apache.commons.lang.StringUtils;
+import org.pf4j.PluginManager;
+import org.pf4j.PluginWrapper;
+import org.pf4j.demo.api.Greeting;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A boot class that start the demo.
+ *
+ * @author Decebal Suiu
+ */
+public class Boot {
+
+ private static final Logger log = LoggerFactory.getLogger(Boot.class);
+
+ public static void main(String[] args) {
+ // print logo
+ printLogo();
+
+ // create the plugin manager
+ PluginManager pluginManager = new DemoPluginManager();
+
+ // 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);
+ log.info("Found {} extensions for extension point '{}'", greetings.size(), Greeting.class.getName());
+ for (Greeting greeting : greetings) {
+ log.info(">>> {}", greeting.getGreeting());
+ }
+
+ // print extensions from classpath (non plugin)
+ log.info("Extensions added by classpath:");
+ Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null);
+ for (String extension : extensionClassNames) {
+ log.info(" {}", extension);
+ }
+
+ log.info("Extension classes by classpath:");
+ List<Class<? extends Greeting>> greetingsClasses = pluginManager.getExtensionClasses(Greeting.class);
+ for (Class<? extends Greeting> greeting : greetingsClasses) {
+ log.info(" Class: {}", greeting.getCanonicalName());
+ }
+
+ // print extensions ids for each started plugin
+ List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins();
+ for (PluginWrapper plugin : startedPlugins) {
+ String pluginId = plugin.getDescriptor().getPluginId();
+ log.info("Extensions added by plugin '{}}':", pluginId);
+ extensionClassNames = pluginManager.getExtensionClassNames(pluginId);
+ for (String extension : extensionClassNames) {
+ log.info(" {}", extension);
+ }
+ }
+
+ // print the extensions instances for Greeting extension point for each started plugin
+ for (PluginWrapper plugin : startedPlugins) {
+ String pluginId = plugin.getDescriptor().getPluginId();
+ log.info("Extensions instances added by plugin '{}' for extension point '{}':", pluginId, Greeting.class.getName());
+ List<Greeting> extensions = pluginManager.getExtensions(Greeting.class, pluginId);
+ for (Object extension : extensions) {
+ log.info(" {}", extension);
+ }
+ }
+
+ // print extensions instances from classpath (non plugin)
+ log.info("Extensions instances added by classpath:");
+ List<?> extensions = pluginManager.getExtensions((String) null);
+ for (Object extension : extensions) {
+ log.info(" {}", extension);
+ }
+
+ // print extensions instances for each started plugin
+ for (PluginWrapper plugin : startedPlugins) {
+ String pluginId = plugin.getDescriptor().getPluginId();
+ log.info("Extensions instances added by plugin '{}':", pluginId);
+ extensions = pluginManager.getExtensions(pluginId);
+ for (Object extension : extensions) {
+ log.info(" {}", extension);
+ }
+ }
+
+ // stop the plugins
+ pluginManager.stopPlugins();
+ /*
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+
+ @Override
+ public void run() {
+ pluginManager.stopPlugins();
+ }
+
+ });
+ */
+ }
+
+ private static void printLogo() {
+ log.info(StringUtils.repeat("#", 40));
+ log.info(StringUtils.center("PF4J-DEMO", 40));
+ log.info(StringUtils.repeat("#", 40));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo;
+
+import java.lang.reflect.Constructor;
+import org.pf4j.DefaultPluginFactory;
+import org.pf4j.Plugin;
+import org.pf4j.PluginWrapper;
+import org.pf4j.demo.api.PluginContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class DemoPluginFactory extends DefaultPluginFactory {
+
+ private static final Logger log = LoggerFactory.getLogger(DemoPluginFactory.class);
+
+ @Override
+ protected Plugin createInstance(Class<?> pluginClass, PluginWrapper pluginWrapper) {
+ PluginContext context = new PluginContext(pluginWrapper.getRuntimeMode());
+ try {
+ Constructor<?> constructor = pluginClass.getConstructor(PluginContext.class);
+ return (Plugin) constructor.newInstance(context);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+
+ return null;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo;
+
+import org.pf4j.DefaultExtensionFinder;
+import org.pf4j.DefaultPluginFactory;
+import org.pf4j.DefaultPluginManager;
+import org.pf4j.ExtensionFinder;
+import org.pf4j.PluginFactory;
+
+class DemoPluginManager extends DefaultPluginManager {
+
+ // Use below code if you want to enable ServiceProviderExtensionFinder
+ /*
+ @Override
+ protected ExtensionFinder createExtensionFinder() {
+ DefaultExtensionFinder extensionFinder = (DefaultExtensionFinder) super.createExtensionFinder();
+ extensionFinder.addServiceProviderExtensionFinder(); // to activate "HowdyGreeting" extension
+
+ return extensionFinder;
+ }
+ */
+
+ @Override
+ protected PluginFactory createPluginFactory() {
+ return new DemoPluginFactory();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo;
+
+import org.pf4j.demo.api.Greeting;
+
+/**
+ * A Service Implementation (no @Extension) declared via Java Service Provider mechanism (using META-INF/services).
+ *
+ * @author Decebal Suiu
+ */
+public class HowdyGreeting implements Greeting {
+
+ @Override
+ public String getGreeting() {
+ return "Howdy";
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo;
+
+import org.pf4j.Extension;
+import org.pf4j.demo.api.Greeting;
+
+/**
+ * @author Decebal Suiu
+ */
+@Extension
+public class WhazzupGreeting implements Greeting {
+
+ @Override
+ public String getGreeting() {
+ return "Whazzup";
+ }
+
+}
--- /dev/null
+org.pf4j.demo.HowdyGreeting
--- /dev/null
+# SLF4J's SimpleLogger configuration file
+# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
+
+# Default logging detail level for all instances of SimpleLogger.
+# Must be one of ("trace", "debug", "info", "warn", or "error").
+# If not specified, defaults to "info".
+org.slf4j.simpleLogger.defaultLogLevel=debug
+
+# Logging detail level for a SimpleLogger instance named "xxxxx".
+# Must be one of ("trace", "debug", "info", "warn", or "error").
+# If not specified, the default logging detail level is used.
+#org.slf4j.simpleLogger.log.xxxxx=
+# !!! Uncomment below loggers when you are in trouble
+#org.slf4j.simpleLogger.log.org.pf4j.PluginClassLoader=trace
+#org.slf4j.simpleLogger.log.org.pf4j.AbstractExtensionFinder=trace
+
+# Set to true if you want the current date and time to be included in output messages.
+# Default is false, and will output the number of milliseconds elapsed since startup.
+#org.slf4j.simpleLogger.showDateTime=false
+org.slf4j.simpleLogger.showDateTime=true
+
+# The date and time format to be used in the output messages.
+# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
+# If the format is not specified or is invalid, the default format is used.
+# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
+#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
+org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss
+
+# Set to true if you want to output the current thread name.
+# Defaults to true.
+#org.slf4j.simpleLogger.showThreadName=true
+
+# Set to true if you want the Logger instance name to be included in output messages.
+# Defaults to true.
+#org.slf4j.simpleLogger.showLogName=true
+
+# Set to true if you want the last component of the name to be included in output messages.
+# Defaults to false.
+#org.slf4j.simpleLogger.showShortLogName=false
--- /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=welcome-plugin
+plugin.class=org.pf4j.demo.welcome.WelcomePlugin
+plugin.version=0.0.1
+plugin.provider=Decebal Suiu
+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>org.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-plugins</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>pf4j-demo-plugin1</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Demo Plugin #1</name>
+
+ <properties>
+ <plugin.id>welcome-plugin</plugin.id>
+ <plugin.class>org.pf4j.demo.welcome.WelcomePlugin</plugin.class>
+ <plugin.version>0.0.1</plugin.version>
+ <plugin.provider>Decebal Suiu</plugin.provider>
+ <plugin.dependencies />
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.welcome;
+
+import org.apache.commons.lang.StringUtils;
+import org.pf4j.Extension;
+import org.pf4j.RuntimeMode;
+import org.pf4j.demo.api.DemoPlugin;
+import org.pf4j.demo.api.Greeting;
+import org.pf4j.demo.api.PluginContext;
+
+/**
+ * @author Decebal Suiu
+ */
+public class WelcomePlugin extends DemoPlugin {
+
+ public WelcomePlugin(PluginContext context) {
+ super(context);
+ }
+
+ @Override
+ public void start() {
+ log.info("WelcomePlugin.start()");
+ // for testing the development mode
+ if (RuntimeMode.DEVELOPMENT.equals(context.getRuntimeMode())) {
+ log.info(StringUtils.upperCase("WelcomePlugin"));
+ }
+ }
+
+ @Override
+ public void stop() {
+ log.info("WelcomePlugin.stop()");
+ }
+
+ @Extension
+ public static class WelcomeGreeting implements Greeting {
+
+ @Override
+ public String getGreeting() {
+ return "Welcome";
+ }
+
+ }
+
+}
--- /dev/null
+plugin.id=hello-plugin
+plugin.class=org.pf4j.demo.hello.HelloPlugin
+plugin.version=0.0.1
+plugin.provider=Decebal Suiu
+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>org.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-plugins</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>pf4j-demo-plugin2</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Demo Plugin #2</name>
+
+ <properties>
+ <plugin.id>hello-plugin</plugin.id>
+ <plugin.class>org.pf4j.demo.hello.HelloPlugin</plugin.class>
+ <plugin.version>0.0.1</plugin.version>
+ <plugin.provider>Decebal Suiu</plugin.provider>
+ <plugin.dependencies />
+ </properties>
+
+</project>
--- /dev/null
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.demo.hello;
+
+import org.pf4j.Extension;
+import org.pf4j.demo.api.DemoPlugin;
+import org.pf4j.demo.api.Greeting;
+import org.pf4j.demo.api.PluginContext;
+
+/**
+ * A very simple plugin.
+ *
+ * @author Decebal Suiu
+ */
+public class HelloPlugin extends DemoPlugin {
+
+ public HelloPlugin(PluginContext context) {
+ super(context);
+ }
+
+ @Override
+ public void start() {
+ log.info("HelloPlugin.start()");
+ }
+
+ @Override
+ public void stop() {
+ log.info("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>org.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-parent</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>pf4j-demo-plugins</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Demo 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.class />
+ <plugin.version />
+ <plugin.provider />
+ <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>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ <version>2.8.2</version>
+ </plugin>
+ </plugins>
+ </build>
+
+ <modules>
+ <module>plugin1</module>
+ <module>plugin2</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.pf4j</groupId>
+ <artifactId>pf4j</artifactId>
+ <version>${project.version}</version>
+ <!-- !!! VERY IMPORTANT -->
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-api</artifactId>
+ <version>${project.version}</version>
+ <!-- !!! VERY IMPORTANT -->
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
--- /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.12.0-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-parent</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Demo Parent</name>
+
+ <properties>
+ <javadoc.disabled>true</javadoc.disabled>
+ <deploy.disabled>true</deploy.disabled>
+ <source.disabled>true</source.disabled>
+ </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>
+
+ <modules>
+ <module>app</module>
+ <module>api</module>
+ <module>plugins</module>
+ </modules>
+
+</project>
+++ /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=welcome-plugin
-plugin.class=org.pf4j.demo.welcome.WelcomePlugin
-plugin.version=0.0.1
-plugin.provider=Decebal Suiu
-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>org.pf4j.demo</groupId>
- <artifactId>pf4j-demo-plugins</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>pf4j-demo-plugin1</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>Demo Plugin #1</name>
-
- <properties>
- <plugin.id>welcome-plugin</plugin.id>
- <plugin.class>org.pf4j.demo.welcome.WelcomePlugin</plugin.class>
- <plugin.version>0.0.1</plugin.version>
- <plugin.provider>Decebal Suiu</plugin.provider>
- <plugin.dependencies />
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.6</version>
- </dependency>
- </dependencies>
-
-</project>
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.welcome;
-
-import org.apache.commons.lang.StringUtils;
-import org.pf4j.Extension;
-import org.pf4j.RuntimeMode;
-import org.pf4j.demo.api.DemoPlugin;
-import org.pf4j.demo.api.Greeting;
-import org.pf4j.demo.api.PluginContext;
-
-/**
- * @author Decebal Suiu
- */
-public class WelcomePlugin extends DemoPlugin {
-
- public WelcomePlugin(PluginContext context) {
- super(context);
- }
-
- @Override
- public void start() {
- log.info("WelcomePlugin.start()");
- // for testing the development mode
- if (RuntimeMode.DEVELOPMENT.equals(context.getRuntimeMode())) {
- log.info(StringUtils.upperCase("WelcomePlugin"));
- }
- }
-
- @Override
- public void stop() {
- log.info("WelcomePlugin.stop()");
- }
-
- @Extension
- public static class WelcomeGreeting implements Greeting {
-
- @Override
- public String getGreeting() {
- return "Welcome";
- }
-
- }
-
-}
+++ /dev/null
-plugin.id=hello-plugin
-plugin.class=org.pf4j.demo.hello.HelloPlugin
-plugin.version=0.0.1
-plugin.provider=Decebal Suiu
-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>org.pf4j.demo</groupId>
- <artifactId>pf4j-demo-plugins</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>pf4j-demo-plugin2</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>Demo Plugin #2</name>
-
- <properties>
- <plugin.id>hello-plugin</plugin.id>
- <plugin.class>org.pf4j.demo.hello.HelloPlugin</plugin.class>
- <plugin.version>0.0.1</plugin.version>
- <plugin.provider>Decebal Suiu</plugin.provider>
- <plugin.dependencies />
- </properties>
-
-</project>
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.hello;
-
-import org.pf4j.Extension;
-import org.pf4j.demo.api.DemoPlugin;
-import org.pf4j.demo.api.Greeting;
-import org.pf4j.demo.api.PluginContext;
-
-/**
- * A very simple plugin.
- *
- * @author Decebal Suiu
- */
-public class HelloPlugin extends DemoPlugin {
-
- public HelloPlugin(PluginContext context) {
- super(context);
- }
-
- @Override
- public void start() {
- log.info("HelloPlugin.start()");
- }
-
- @Override
- public void stop() {
- log.info("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>org.pf4j.demo</groupId>
- <artifactId>pf4j-demo-parent</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>pf4j-demo-plugins</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>Demo 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.class />
- <plugin.version />
- <plugin.provider />
- <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>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-deploy-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- <version>2.8.2</version>
- </plugin>
- </plugins>
- </build>
-
- <modules>
- <module>plugin1</module>
- <module>plugin2</module>
- </modules>
-
- <dependencies>
- <dependency>
- <groupId>org.pf4j</groupId>
- <artifactId>pf4j</artifactId>
- <version>${project.version}</version>
- <!-- !!! VERY IMPORTANT -->
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.pf4j.demo</groupId>
- <artifactId>pf4j-demo-api</artifactId>
- <version>${project.version}</version>
- <!-- !!! VERY IMPORTANT -->
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
-</project>
+++ /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.12.0-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.pf4j.demo</groupId>
- <artifactId>pf4j-demo-parent</artifactId>
- <version>3.12.0-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>Demo Parent</name>
-
- <properties>
- <javadoc.disabled>true</javadoc.disabled>
- <deploy.disabled>true</deploy.disabled>
- <source.disabled>true</source.disabled>
- </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>
-
- <modules>
- <module>app</module>
- <module>api</module>
- <module>plugins</module>
- </modules>
-
-</project>
+++ /dev/null
-build
-.gradle
-.idea
+++ /dev/null
-# PF4J Gradle Demo
-
-This demo assumes that you know the basics of Gradle (Please look at [gradle](https://gradle.org/) for more info)
-
-### Setup/Build
-
-1. Clone the repo
-2. Go to demo_gradle `cd demo_gradle`
-3. run `./gradlew build`
-
-* This will produce one jar, named app-plugin-demo-uberjar.jar, located in the `app/build/libs/` directory and three plugins zips located in `build/plugins` directory.
-* The plugins are `plugin-hello-plugin-0.0.1.zip`, `plugin-KotlinPlugin-1.0.0.zip` and `plugin-welcome-plugin-0.0.1.zip`
-
-### Run the demo
-
-1. Run
-
-```
- ./gradlew app:run
-```
-
-2. The demo's output should look similar to: (Please see `Boot#main()` for more details)
-```
-[main] INFO org.pf4j.demo.Boot - ########################################
-[main] INFO org.pf4j.demo.Boot - PF4J-DEMO
-[main] INFO org.pf4j.demo.Boot - ########################################
-[main] INFO org.pf4j.DefaultPluginStatusProvider - Enabled plugins: []
-[main] INFO org.pf4j.DefaultPluginStatusProvider - Disabled plugins: []
-[main] INFO org.pf4j.DefaultPluginManager - PF4J version 3.1.0 in 'deployment' mode
-[main] INFO org.pf4j.util.FileUtils - Expanded plugin zip 'plugin-hello-plugin-0.0.1.zip' in 'plugin-hello-plugin-0.0.1'
-[main] INFO org.pf4j.util.FileUtils - Expanded plugin zip 'plugin-KotlinPlugin-1.0.0.zip' in 'plugin-KotlinPlugin-1.0.0'
-[main] INFO org.pf4j.util.FileUtils - Expanded plugin zip 'plugin-welcome-plugin-0.0.1.zip' in 'plugin-welcome-plugin-0.0.1'
-[main] INFO org.pf4j.AbstractPluginManager - Plugin 'welcome-plugin@0.0.1' resolved
-[main] INFO org.pf4j.AbstractPluginManager - Plugin 'KotlinPlugin@1.0.0' resolved
-[main] INFO org.pf4j.AbstractPluginManager - Plugin 'hello-plugin@0.0.1' resolved
-[main] INFO org.pf4j.AbstractPluginManager - Start plugin 'welcome-plugin@0.0.1'
-[main] INFO org.pf4j.demo.welcome.WelcomePlugin - WelcomePlugin.start()
-[main] INFO org.pf4j.demo.welcome.WelcomePlugin - WELCOMEPLUGIN
-[main] INFO org.pf4j.AbstractPluginManager - Start plugin 'KotlinPlugin@1.0.0'
-[main] INFO org.pf4j.demo.kotlin.KotlinPlugin - KotlinPlugin.start()
-[main] INFO org.pf4j.demo.kotlin.KotlinPlugin - KOTLINPLUGIN
-[main] INFO org.pf4j.AbstractPluginManager - Start plugin 'hello-plugin@0.0.1'
-[main] INFO org.pf4j.demo.hello.HelloPlugin - HelloPlugin.start()
-[main] INFO org.pf4j.demo.Boot - Plugindirectory:
-[main] INFO org.pf4j.demo.Boot - ../build/plugins
-
-[main] INFO org.pf4j.demo.Boot - Found 4 extensions for extension point 'org.pf4j.demo.api.Greeting'
-[main] INFO org.pf4j.demo.Boot - >>> Whazzup
-[main] INFO org.pf4j.demo.Boot - >>> Welcome
-[main] INFO org.pf4j.demo.Boot - >>> KotlinGreetings
-[main] INFO org.pf4j.demo.Boot - >>> Hello
-[main] INFO org.pf4j.demo.Boot - Extensions added by plugin 'welcome-plugin':
-[main] INFO org.pf4j.demo.Boot - Extensions added by plugin 'KotlinPlugin':
-[main] INFO org.pf4j.demo.Boot - Extensions added by plugin 'hello-plugin':
-[main] INFO org.pf4j.AbstractPluginManager - Stop plugin 'hello-plugin@0.0.1'
-[main] INFO org.pf4j.demo.hello.HelloPlugin - HelloPlugin.stop()
-[main] INFO org.pf4j.AbstractPluginManager - Stop plugin 'KotlinPlugin@1.0.0'
-[main] INFO org.pf4j.demo.kotlin.KotlinPlugin - KotlinPlugin.stop()
-[main] INFO org.pf4j.AbstractPluginManager - Stop plugin 'welcome-plugin@0.0.1'
-[main] INFO org.pf4j.demo.welcome.WelcomePlugin - WelcomePlugin.stop()
-```
-
+++ /dev/null
-dependencies {
- compile group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}"
- compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
-
- testCompile group: 'junit', name: 'junit', version: '4.+'
-}
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.api;
-
-import org.pf4j.ExtensionPoint;
-
-/**
- * @author Decebal Suiu
- */
-public interface Greeting extends ExtensionPoint {
-
- String getGreeting();
-
-}
+++ /dev/null
-apply plugin: 'application'
-
-mainClassName = 'org.pf4j.demo.Boot'
-run {
- systemProperty 'pf4j.pluginsDir', '../build/plugins'
-}
-
-dependencies {
- compile project(':api')
- compile group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}"
- annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
- compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
- compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'
-
- testCompile group: 'junit', name: 'junit', version: '4.+'
-}
-
-task uberjar(type: Jar, dependsOn: ['compileJava']) {
- zip64 true
- from configurations.runtimeClasspath.asFileTree.files.collect {
- exclude "META-INF/*.SF"
- exclude "META-INF/*.DSA"
- exclude "META-INF/*.RSA"
- zipTree(it)
- }
- from files(sourceSets.main.output.classesDirs)
- from files(sourceSets.main.resources)
- manifest {
- attributes 'Main-Class': mainClassName
- }
-
- archiveBaseName = "${project.name}-plugin-demo"
- archiveClassifier = "uberjar"
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo;
-
-import org.apache.commons.lang3.StringUtils;
-import org.pf4j.CompoundPluginDescriptorFinder;
-import org.pf4j.ManifestPluginDescriptorFinder;
-import org.pf4j.PropertiesPluginDescriptorFinder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.pf4j.DefaultPluginManager;
-import org.pf4j.PluginManager;
-import org.pf4j.PluginWrapper;
-import org.pf4j.demo.api.Greeting;
-
-import java.util.List;
-
-/**
- * A boot class that start the demo.
- *
- * @author Decebal Suiu
- */
-public class Boot {
- private static final Logger logger = LoggerFactory.getLogger(Boot.class);
-
- public static void main(String[] args) {
- // print logo
- printLogo();
-
- // create the plugin manager
- final PluginManager pluginManager = new DefaultPluginManager() {
- @Override
- protected CompoundPluginDescriptorFinder createPluginDescriptorFinder() {
- return new CompoundPluginDescriptorFinder()
- // Demo is using the Manifest file
- // PropertiesPluginDescriptorFinder is commented out just to avoid error log
- //.add(new PropertiesPluginDescriptorFinder())
- .add(new ManifestPluginDescriptorFinder());
- }
- };
-
- // load the plugins
- pluginManager.loadPlugins();
-
- // enable a disabled plugin
-// pluginManager.enablePlugin("welcome-plugin");
-
- // start (active/resolved) the plugins
- pluginManager.startPlugins();
-
- logger.info("Plugindirectory: ");
- logger.info("\t" + System.getProperty("pf4j.pluginsDir", "plugins") + "\n");
-
- // retrieves the extensions for Greeting extension point
- List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
- logger.info(String.format("Found %d extensions for extension point '%s'", greetings.size(), Greeting.class.getName()));
- for (Greeting greeting : greetings) {
- logger.info(">>> " + greeting.getGreeting());
- }
-
- // // print extensions from classpath (non plugin)
- // logger.info(String.format("Extensions added by classpath:"));
- // Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null);
- // for (String extension : extensionClassNames) {
- // logger.info(" " + extension);
- // }
-
- // print extensions for each started plugin
- List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins();
- for (PluginWrapper plugin : startedPlugins) {
- String pluginId = plugin.getDescriptor().getPluginId();
- logger.info(String.format("Extensions added by plugin '%s':", pluginId));
- // extensionClassNames = pluginManager.getExtensionClassNames(pluginId);
- // for (String extension : extensionClassNames) {
- // logger.info(" " + extension);
- // }
- }
-
- // stop the plugins
- pluginManager.stopPlugins();
- /*
- Runtime.getRuntime().addShutdownHook(new Thread() {
-
- @Override
- public void run() {
- pluginManager.stopPlugins();
- }
-
- });
- */
- }
-
- private static void printLogo() {
- logger.info(StringUtils.repeat("#", 40));
- logger.info(StringUtils.center("PF4J-DEMO", 40));
- logger.info(StringUtils.repeat("#", 40));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo;
-
-import org.pf4j.Extension;
-import org.pf4j.demo.api.Greeting;
-
-/**
- * @author Decebal Suiu
- */
-@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
-log4j.logger.org.pf4j.PluginClassLoader=WARN, Console
-log4j.additivity.org.pf4j=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
-subprojects {
- apply plugin: 'java'
-
- repositories {
- mavenLocal()
- mavenCentral()
- }
-}
-// plugin location
-ext.pluginsDir = rootProject.buildDir.path + '/plugins'
-
-task build(dependsOn: [':app:uberjar'])
-
-
+++ /dev/null
-# PF4J
-pf4jVersion=3.1.0
+++ /dev/null
-#Thu Nov 14 12:06:04 CST 2019
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-all.zip
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
+++ /dev/null
-#!/usr/bin/env sh
-
-#
-# Copyright 2015 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn () {
- echo "$*"
-}
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=`expr $i + 1`
- done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-exec "$JAVACMD" "$@"
+++ /dev/null
-@rem\r
-@rem Copyright 2015 the original author or authors.\r
-@rem\r
-@rem Licensed under the Apache License, Version 2.0 (the "License");\r
-@rem you may not use this file except in compliance with the License.\r
-@rem You may obtain a copy of the License at\r
-@rem\r
-@rem https://www.apache.org/licenses/LICENSE-2.0\r
-@rem\r
-@rem Unless required by applicable law or agreed to in writing, software\r
-@rem distributed under the License is distributed on an "AS IS" BASIS,\r
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-@rem See the License for the specific language governing permissions and\r
-@rem limitations under the License.\r
-@rem\r
-\r
-@if "%DEBUG%" == "" @echo off\r
-@rem ##########################################################################\r
-@rem\r
-@rem Gradle startup script for Windows\r
-@rem\r
-@rem ##########################################################################\r
-\r
-@rem Set local scope for the variables with windows NT shell\r
-if "%OS%"=="Windows_NT" setlocal\r
-\r
-set DIRNAME=%~dp0\r
-if "%DIRNAME%" == "" set DIRNAME=.\r
-set APP_BASE_NAME=%~n0\r
-set APP_HOME=%DIRNAME%\r
-\r
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"\r
-\r
-@rem Find java.exe\r
-if defined JAVA_HOME goto findJavaFromJavaHome\r
-\r
-set JAVA_EXE=java.exe\r
-%JAVA_EXE% -version >NUL 2>&1\r
-if "%ERRORLEVEL%" == "0" goto init\r
-\r
-echo.\r
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
-echo.\r
-echo Please set the JAVA_HOME variable in your environment to match the\r
-echo location of your Java installation.\r
-\r
-goto fail\r
-\r
-:findJavaFromJavaHome\r
-set JAVA_HOME=%JAVA_HOME:"=%\r
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
-\r
-if exist "%JAVA_EXE%" goto init\r
-\r
-echo.\r
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
-echo.\r
-echo Please set the JAVA_HOME variable in your environment to match the\r
-echo location of your Java installation.\r
-\r
-goto fail\r
-\r
-:init\r
-@rem Get command-line arguments, handling Windows variants\r
-\r
-if not "%OS%" == "Windows_NT" goto win9xME_args\r
-\r
-:win9xME_args\r
-@rem Slurp the command line arguments.\r
-set CMD_LINE_ARGS=\r
-set _SKIP=2\r
-\r
-:win9xME_args_slurp\r
-if "x%~1" == "x" goto execute\r
-\r
-set CMD_LINE_ARGS=%*\r
-\r
-:execute\r
-@rem Setup the command line\r
-\r
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
-\r
-@rem Execute Gradle\r
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
-\r
-:end\r
-@rem End local scope for the variables with windows NT shell\r
-if "%ERRORLEVEL%"=="0" goto mainEnd\r
-\r
-:fail\r
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
-rem the _cmd.exe /c_ return code!\r
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
-exit /b 1\r
-\r
-:mainEnd\r
-if "%OS%"=="Windows_NT" endlocal\r
-\r
-:omega\r
+++ /dev/null
-subprojects {
- jar {
- manifest {
- attributes 'Plugin-Class': "${pluginClass}",
- 'Plugin-Id': "${pluginId}",
- 'Plugin-Version': "${archiveVersion}",
- 'Plugin-Provider': "${pluginProvider}",
- 'Plugin-Dependencies': "${pluginDependencies}"
- }
- }
-
- task plugin(type: Jar) {
- archiveBaseName = "plugin-${pluginId}"
- into('classes') {
- with jar
- }
- into('lib') {
- from configurations.compile
- }
- archiveExtension ='zip'
- }
-
- task assemblePlugin(type: Copy) {
- from plugin
- into pluginsDir
- }
-}
-
-task assemblePlugins(type: Copy) {
- dependsOn subprojects.assemblePlugin
-}
-
-build.dependsOn project.tasks.assemblePlugins
+++ /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
-dependencies {
- // compileOnly important!!! We do not want to put the api into the zip file since the main program has it already!
- compileOnly project(':api')
- compileOnly(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
- exclude group: "org.slf4j"
- }
- annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
- compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
- testCompile group: 'junit', name: 'junit', version: '4.+'
-}
+++ /dev/null
-version=0.0.1
-
-pluginId=welcome-plugin
-pluginClass=org.pf4j.demo.welcome.WelcomePlugin
-pluginProvider=Decebal Suiu
-pluginDependencies=
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.welcome;
-
-import org.apache.commons.lang3.StringUtils;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.pf4j.Extension;
-import org.pf4j.Plugin;
-import org.pf4j.PluginWrapper;
-import org.pf4j.demo.api.Greeting;
-
-/**
- * @author Decebal Suiu
- */
-public class WelcomePlugin extends Plugin {
-
- private static final Logger logger = LoggerFactory.getLogger(WelcomePlugin.class);
-
- public WelcomePlugin(PluginWrapper wrapper) {
- super(wrapper);
- }
-
- @Override
- public void start() {
- logger.info("WelcomePlugin.start()");
- logger.info(StringUtils.upperCase("WelcomePlugin"));
- }
-
- @Override
- public void stop() {
- logger.info("WelcomePlugin.stop()");
- }
-
- @Extension
- public static class WelcomeGreeting implements Greeting {
-
- @Override
- public String getGreeting() {
- return "Welcome";
- }
-
- }
-
-}
+++ /dev/null
-dependencies {
- // compileOnly important!!! We do not want to put the api into the zip file since the main program has it already!
- compileOnly project(':api')
- compileOnly(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
- exclude group: "org.slf4j"
- }
- annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
- compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
- testCompile group: 'junit', name: 'junit', version: '4.+'
-}
+++ /dev/null
-version=0.0.1
-
-pluginId=hello-plugin
-pluginClass=org.pf4j.demo.hello.HelloPlugin
-pluginProvider=Decebal Suiu
-pluginDependencies=
+++ /dev/null
-/*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.hello;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.pf4j.Extension;
-import org.pf4j.Plugin;
-import org.pf4j.PluginWrapper;
-import org.pf4j.demo.api.Greeting;
-
-/**
- * A very simple plugin.
- *
- * @author Decebal Suiu
- */
-public class HelloPlugin extends Plugin {
- private static final Logger logger = LoggerFactory.getLogger(HelloPlugin.class);
-
- public HelloPlugin(PluginWrapper wrapper) {
- super(wrapper);
- }
-
- @Override
- public void start() {
- logger.info("HelloPlugin.start()");
- }
-
- @Override
- public void stop() {
- logger.info("HelloPlugin.stop()");
- }
-
- @Extension(ordinal=1)
- public static class HelloGreeting implements Greeting {
-
- @Override
- public String getGreeting() {
- return "Hello";
- }
-
- }
-
-}
+++ /dev/null
-buildscript {
- ext.kotlin_version = '1.3.50'
-
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
-apply plugin: 'kotlin'
-apply plugin: 'kotlin-kapt'
-
-repositories {
- mavenCentral()
-}
-
-dependencies {
- compileOnly project(':api')
- compileOnly(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
- exclude group: "org.slf4j"
- }
- kapt(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
- compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
- compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
-
- testCompile group: 'junit', name: 'junit', version: '4.+'
-}
+++ /dev/null
-version=1.0.0
-
-pluginId=KotlinPlugin
-pluginClass=org.pf4j.demo.kotlin.KotlinPlugin
-pluginProvider=Anindya Chatterjee
-pluginDependencies=
+++ /dev/null
-/*
- * Copyright (C) 2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.pf4j.demo.kotlin
-
-import org.apache.commons.lang3.StringUtils
-import org.slf4j.LoggerFactory
-import org.pf4j.Extension
-import org.pf4j.Plugin
-import org.pf4j.PluginWrapper
-import org.pf4j.demo.api.Greeting
-
-/**
- * A sample plugin written in Kotlin
- *
- * @author Anindya Chatterjee
- */
-class KotlinPlugin(wrapper: PluginWrapper) : Plugin(wrapper) {
- private val logger = LoggerFactory.getLogger(KotlinPlugin::class.java)
-
- override fun start() {
- logger.info("KotlinPlugin.start()")
- logger.info(StringUtils.upperCase("KotlinPlugin"))
- }
-
- override fun stop() {
- logger.info("KotlinPlugin.stop()")
- }
-}
-
-@Extension
-class KotlinGreeting : Greeting {
- override fun getGreeting(): String {
- return "KotlinGreetings"
- }
-}
+++ /dev/null
-include 'api'
-include 'app'
-
-include 'plugins'
-
-include 'plugins:plugin1'
-include 'plugins:plugin2'
-include 'plugins:plugin3'
<modules>
<module>pf4j</module>
- <module>demo</module>
+ <module>demo/maven</module>
<module>maven-archetypes/quickstart</module>
</modules>
mkdir demo-dist\plugins
REM copy artifacts to demo-dist folder
-xcopy demo\app\target\pf4j-demo-app-*.zip demo-dist /s /i
-xcopy demo\plugins\plugin1\target\pf4j-demo-plugin1-*-all.jar demo-dist\plugins /s
-xcopy demo\plugins\plugin2\target\pf4j-demo-plugin2-*-all.jar demo-dist\plugins /s
-xcopy demo\plugins\enabled.txt demo-dist\plugins /s
-xcopy demo\plugins\disabled.txt demo-dist\plugins /s
+xcopy demo\maven\app\target\pf4j-demo-app-*.zip demo-dist /s /i
+xcopy demo\maven\plugins\plugin1\target\pf4j-demo-plugin1-*-all.jar demo-dist\plugins /s
+xcopy demo\maven\plugins\plugin2\target\pf4j-demo-plugin2-*-all.jar demo-dist\plugins /s
+xcopy demo\maven\plugins\enabled.txt demo-dist\plugins /s
+xcopy demo\maven\plugins\disabled.txt demo-dist\plugins /s
cd demo-dist
mkdir -p demo-dist/plugins
# copy artifacts to demo-dist folder
-cp demo/app/target/pf4j-demo-*.zip demo-dist/
-cp demo/plugins/plugin1/target/pf4j-demo-plugin1-*-all.jar demo-dist/plugins/
-cp demo/plugins/plugin2/target/pf4j-demo-plugin2-*-all.jar demo-dist/plugins/
-cp demo/plugins/enabled.txt demo-dist/plugins/
-cp demo/plugins/disabled.txt demo-dist/plugins/
+cp demo/maven/app/target/pf4j-demo-*.zip demo-dist/
+cp demo/maven/plugins/plugin1/target/pf4j-demo-plugin1-*-all.jar demo-dist/plugins/
+cp demo/maven/plugins/plugin2/target/pf4j-demo-plugin2-*-all.jar demo-dist/plugins/
+cp demo/maven/plugins/enabled.txt demo-dist/plugins/
+cp demo/maven/plugins/disabled.txt demo-dist/plugins/
cd demo-dist