Browse Source

Post `PluginState.UNLOADED` event when plugins are unloaded (#567)

tags/release-3.11.0
Sebastian Lövdahl 2 months ago
parent
commit
b92ec9ed53
No account linked to committer's email address

+ 1
- 0
pf4j/src/main/java/org/pf4j/AbstractPluginManager.java View File

} }


// remove the plugin // remove the plugin
pluginWrapper.setPluginState(PluginState.UNLOADED);
plugins.remove(pluginId); plugins.remove(pluginId);
getResolvedPlugins().remove(pluginWrapper); getResolvedPlugins().remove(pluginWrapper);
getUnresolvedPlugins().remove(pluginWrapper); getUnresolvedPlugins().remove(pluginWrapper);

+ 9
- 2
pf4j/src/main/java/org/pf4j/PluginState.java View File

* <p> * <p>
* Lifecycle of a plugin: * Lifecycle of a plugin:
* <pre> * <pre>
* CREATED -> RESOLVED -> STARTED -> STOPPED
* CREATED -> RESOLVED -> STARTED -> STOPPED -> UNLOADED
* CREATED -> DISABLED * CREATED -> DISABLED
* CREATED -> FAILED * CREATED -> FAILED
* *
/** /**
* Plugin failed to start. * Plugin failed to start.
*/ */
FAILED("FAILED");
FAILED("FAILED"),

/**
* The plugin has been unloaded. After this event has been completed, the plugin's
* {@link ClassLoader} will be closed.
*/
UNLOADED("UNLOADED"),
;


private final String status; private final String status;



+ 43
- 0
pf4j/src/test/java/org/pf4j/DefaultPluginManagerTest.java View File

import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
private DefaultPluginDescriptor pluginDescriptor; private DefaultPluginDescriptor pluginDescriptor;
private PluginWrapper pluginWrapper; private PluginWrapper pluginWrapper;


private List<PluginStateEvent> receivedEvents;

@TempDir @TempDir
Path pluginsPath; Path pluginsPath;


@BeforeEach @BeforeEach
public void setUp() throws IOException { public void setUp() throws IOException {
receivedEvents = new ArrayList<>();

pluginManager = new DefaultPluginManager(pluginsPath); pluginManager = new DefaultPluginManager(pluginsPath);
pluginManager.addPluginStateListener(event -> receivedEvents.add(event));


pluginDescriptor = new DefaultPluginDescriptor(); pluginDescriptor = new DefaultPluginDescriptor();
pluginDescriptor.setPluginId("myPlugin"); pluginDescriptor.setPluginId("myPlugin");
pluginManager = null; pluginManager = null;
pluginDescriptor = null; pluginDescriptor = null;
pluginWrapper = null; pluginWrapper = null;
receivedEvents = null;
} }


@Test @Test


PluginManager pluginManager = new DefaultPluginManager(pluginsPath) { PluginManager pluginManager = new DefaultPluginManager(pluginsPath) {


@Override
protected PluginStatusProvider createPluginStatusProvider() { protected PluginStatusProvider createPluginStatusProvider() {
return statusProvider; return statusProvider;
} }
assertTrue(deleted); assertTrue(deleted);


assertFalse(pluginZip.file().exists()); assertFalse(pluginZip.file().exists());

Optional<PluginStateEvent> unloadedEvent = receivedEvents.stream()
.filter(event -> event.getPluginState() == PluginState.UNLOADED)
.findFirst();

assertTrue(unloadedEvent.isPresent());
} }


@Test @Test
assertTrue(deleted); assertTrue(deleted);


assertFalse(pluginJar.file().exists()); assertFalse(pluginJar.file().exists());

Optional<PluginStateEvent> unloadedEvent = receivedEvents.stream()
.filter(event -> event.getPluginState() == PluginState.UNLOADED)
.findFirst();

assertTrue(unloadedEvent.isPresent());
} }


@Test @Test
assertThrows(DependencyResolver.CyclicDependencyException.class, () -> pluginManager.loadPlugins()); assertThrows(DependencyResolver.CyclicDependencyException.class, () -> pluginManager.loadPlugins());
} }


@Test
public void deleteZipPluginForPluginThatHasNotBeenStartedPostsUnloadedEvent() throws Exception {
PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
.pluginVersion("1.2.3")
.build();

pluginManager.loadPlugin(pluginZip.path());

assertEquals(1, pluginManager.getPlugins().size());

boolean deleted = pluginManager.deletePlugin(pluginZip.pluginId());
assertTrue(deleted);

assertFalse(pluginZip.file().exists());

Optional<PluginStateEvent> unloadedEvent = receivedEvents.stream()
.filter(event -> event.getPluginState() == PluginState.UNLOADED)
.findFirst();

assertTrue(unloadedEvent.isPresent());
}
} }

Loading…
Cancel
Save