pf4j / pf4j-spring

Plugin Framework for Spring (PF4J - Spring Framework integration)
Apache License 2.0
346 stars 105 forks source link

The real implementation cannot be accessed through the api interface. #76

Closed free-leung closed 1 year ago

free-leung commented 1 year ago

Hello here. I wrote an sdk package to specify the extension interface.

import org.pf4j.ExtensionPoint;

/**
 * {@code Greeting}
 *
 * @author Tigers Leung
 * @version 1.0
 * @since 1.0
 */
public interface Greeting extends ExtensionPoint {
    String sayHello () ;
}

Then create plugins in the plugins module and implement the extensions in the sdk. code like:

import com.tigers.gateway.sdk.Greeting;
import org.pf4j.spring.SpringPlugin;
import org.pf4j.Extension;
import org.pf4j.PluginWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * {@code HelloPlugin}
 * Hello plugin.
 * @author Tigers Leung
 * @version 1.0
 * @since 1.0
 */
public class HelloPlugin extends SpringPlugin {

    private static final Logger logger = LoggerFactory.getLogger(HelloPlugin.class) ;

    public HelloPlugin(PluginWrapper wrapper) {
        super(wrapper);
    }

    @Extension
    public static class GreetingService implements Greeting {
        @Override
        public String sayHello() {
            return "hello";
        }
    }
}

The project started just as I had hoped, and the plug-in and corresponding extensions were loaded. The logger print:

18:33:02.588 DEBUG 12476 --- [ntloop-thread-0] org.pf4j.AbstractExtensionFinder         : Finding extensions from plugin 'HelloPlugin'
2023-04-11 18:33:02.588 DEBUG 12476 --- [ntloop-thread-0] org.pf4j.AbstractExtensionFinder         : Loading class 'com.tigers.gateway.HelloPlugin$GreetingService' using class loader 'org.pf4j.PluginClassLoader@3e598df9'
2023-04-11 18:33:02.589 DEBUG 12476 --- [ntloop-thread-0] org.pf4j.AbstractExtensionFinder         : Added extension 'com.tigers.gateway.HelloPlugin$GreetingService' with ordinal 0
2023-04-11 18:33:02.589 DEBUG 12476 --- [ntloop-thread-0] org.pf4j.AbstractExtensionFinder         : Found 1 extensions for plugin 'HelloPlugin'
2023-04-11 18:33:02.589 DEBUG 12476 --- [ntloop-thread-0] org.pf4j.spring.SpringExtensionFactory   :   Extension class ' com.tigers.gateway.HelloPlugin$GreetingService' belongs to spring-plugin 'HelloPlugin' and will be autowired by using its application context.
2023-04-11 18:33:02.589 DEBUG 12476 --- [ntloop-thread-0] org.pf4j.spring.SpringExtensionFactory   : Instantiate extension class 'com.tigers.gateway.HelloPlugin$GreetingService' by using constructor autowiring.
2023-04-11 18:33:02.589 DEBUG 12476 --- [ntloop-thread-0] org.pf4j.spring.SpringExtensionFactory   : Completing autowiring of extension: com.tigers.gateway.HelloPlugin$GreetingService@34871027
2023-04-11 18:33:02.590  INFO 12476 --- [ntloop-thread-0] com.tigers.gateway.api.HelloApi          : Class: class com.tigers.gateway.HelloPlugin$GreetingService

But I wonder, why did I pass Greeting.class to visit GreetingService got a null. The code like:

List<Greeting> greetingList = springPluginManagerAdapter.getExtensions(Greeting.class) ;

This code yields a list of 0. Then I look at the extension inside by the plug-in id:

List extensions = springPluginManagerAdapter.getExtensions("HelloPlugin") ;
        extensions.forEach(
                o -> {
                    logger.info("Class: {}", o.getClass());
                }
        );

Logger say:

Class: class com.tigers.gateway.HelloPlugin$GreetingService

I see in the example that the implementation can be accessed through the interface. Why isn't my code working?

free-leung commented 1 year ago

Additional version information: JDK 11 pf4j-spring 0.8.0

free-leung commented 1 year ago

Ok, I found out why. The plugins module packaging error. I introduced the corresponding packaging plug-in into the plugins module and the problem was solved. Problematic pom file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.tigers.gateway</groupId>
        <artifactId>edge-gateway</artifactId>
        <version>1.0-Alpha</version>
    </parent>

    <artifactId>plugins</artifactId>
    <packaging>pom</packaging>

    <modules>
        <module>hello-plugin</module>
    </modules>

    <dependencies>
        ....... Elliptic dependence
    </dependencies>

    <properties>
        <!-- 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>
                 <configuration>
                     <descriptorRefs>
                         <descriptorRef>jar-with-dependencies</descriptorRef>
                     </descriptorRefs>
                     <finalName>${project.artifactId}-${project.version}</finalName>
                     <appendAssemblyId>false</appendAssemblyId>
                     <attach>false</attach>
                     <archive>
                         <manifest>
                             <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                             <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                         </manifest>
                         <manifestEntries>
                             <Plugin-Id>${plugin.id}</Plugin-Id>
                             <Plugin-Version>${plugin.version}</Plugin-Version>
                             <Plugin-Provider>${plugin.provider}</Plugin-Provider>
                             <Plugin-Class>${plugin.class}</Plugin-Class>
                             <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
                         </manifestEntries>
                     </archive>
                 </configuration>
                 <executions>
                     <execution>
                         <id>make-assembly</id>
                         <phase>package</phase>
                         <goals>
                             <goal>single</goal>
                         </goals>
                     </execution>
                 </executions>
             </plugin>
        </plugins>
    </build>
</project>

Then I replace the corresponding plug-in:

 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <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>
            </plugin>
        </plugins>
    </build>

The code working now~