JiraActionFactory use the wrong plugin classloader to load class and dependencies

When loading webwork action and injecting dependencies, it looks JiraActionFactory is designed with a fragile assumption…: it search which plugin declared an action using the action class simplename (even not the full classname including package). When found, the action bean and its dependencies are loaded from the corresponding plugin classloader.

String actionSimpleName = actionClass.getSimpleName();
...
Action action = (Action) getAutowireCapableWebworkActionRegistry().getPlugin(actionSimpleName).getContainerAccessor().createBean(actionClass);

In case 2 plugins share the same action classname, this can result in Bean/Dependency not found exception.
Example:
Plugin1:

<webwork1 key="action-plugin1" ...>
    <actions>
      <action name="com.plugin1.BaseAction" alias="ActionPlugin1">...</action>
    </actions>
</webwork1>

Plugin2:

<webwork1 key="action-plugin2" ...>
    <actions>
      <action name="com.plugin2.BaseAction" alias="ActionPlugin2">...</action>
    </actions>
</webwork1>

My guess is that, JiraActionFactory should isolate action between plugins (eg: use plugin key in action name to load and cache action in the factory and use it to select correct plugin classloader, or find another way to keep track of which plugin has declared which action).

This could explain some existing issues: https://community.atlassian.com/t5/Jira-questions/Atlassian-spring-scanner-DI-not-injecting-to-webwork-constructor/qaq-p/839386

I haven’t found any mention in documentation about webwork action classname that should be unique cross plugin:

Tried to raise the point to Atlassian support but I’ve been redirected here.
So, if it can help someone, or if someone from Atlassian can confirm/invalidate my assumption.

Cheers!

1 Like