Skip to content

feat: load global GUI plugins without decompiler, add first IMainWindow method - #2960

Closed
mostafaNazari702 wants to merge 3 commits into
skylot:masterfrom
mostafaNazari702:gui-todos
Closed

mostafaNazari702 wants to merge 3 commits into
skylot:masterfrom
mostafaNazari702:gui-todos

Conversation

@mostafaNazari702

@mostafaNazari702 mostafaNazari702 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

❗ Please review the guidelines for contributing

Description

Quick follow-up to #2945 / #2913, i finished the two TODOs:

  • Global plugins no longer need a decompiler just to load. A decompiler is only created when initializing project plugins.
  • Added IMainWindow.open(files) so global plugins can open APKs without relying on GUI internals.

Also added/updated tests for the plugin manager, global plugin lifecycle, and the new API.

A couple things i would like feedback on:

  • Is the "decompiler only needed for init" approach what you meant by unbinding?
  • Is open a good first IMainWindow API? What should come next?
  • Should the internal plugin data class be renamed now that it no longer implements JadxPluginContext?

@mostafaNazari702

mostafaNazari702 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Things i noticed while working on this (not changed in this PR)

  • Disabling or uninstalling a global plugin only takes effect after restart: it keeps running and is still added to new projects.
  • A global plugin whose global init failed is still added to every project and gets project init/unload.
  • A project plugin with the same id as a global plugin silently replaces it in that project (no duplicate id error).
  • Global and project scope share one options object so a project's own option values stay visible to the global plugin after the project is closed.
  • While global plugins are still initializing, the settings page already lists them but without their options.
  • On Windows, a running global plugin keeps its jar locked so Uninstall removes it from the list but silently leaves the jar on disk. Other plugin jars are also kept open by the global loader until GC.
  • Global plugin init runs on the same background thread as project open/close so a slow global init delays opening a project and closing the window. The same thing is what guarantees global plugins init before the first project.
  • Calling open from a plugin menu action logs "UI thread interrupted": open cancels background jobs including the menu action's own task. The project still reloads fine.
  • Older behavior: opening plugin settings with no project open unloads the temporary plugins twice and deletes the shared temp directory (possibly related to jadx.core.utils.exceptions.JadxRuntimeException: Failed to clear directory C:\Users\XXXX\AppData\Local\Temp\jadx-temp-9028579072555110246\jadx-instance-16828034844905192271 #2575).
  • The Plugins menu is sometimes updated from background threads instead of the UI thread.
  • With Windows default encoding, ResNameUtilsTest and ModifiedUTF8DecoderTest fail because of non-ASCII literals. This is unrelated and the same on master.

Should any of these become separate issues? I can open them.

@mostafaNazari702

Copy link
Copy Markdown
Contributor Author

@skylot I would be thankful if you review this PR ASAP. I have also some other ideas of my own that depend on this PR. Thanks and good luck while reviewing!

@mostafaNazari702

Copy link
Copy Markdown
Contributor Author

@skylot Any progress with this? or have you looked at anything yet?

@skylot

skylot commented Sep 30, 2026

Copy link
Copy Markdown
Owner

Any progress with this? or have you looked at anything yet?

I checked this PR, but decided to try another approach to understand if better solution is possible.

@mostafaNazari702

mostafaNazari702 commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Any progress with this? or have you looked at anything yet?

I checked this PR, but decided to try another approach to understand if better solution is possible.

I might be able to help you if you maybe share some details regarding the "another approach".

@skylot

skylot commented Oct 1, 2026

Copy link
Copy Markdown
Owner

I commit my approach to master, in short:
Plugin manager don't require decompiler instance for plugin loading, only some info stored (in PluginRuntime class). Decompiler instance required only to create PluginContext and for call plugin init method. If plugin context is null, this mean plugin not yet initialized.
Such approach cause a lot of changes in class name returned from plugin manager, but these are mostly trivial.
As a result a staged plugin loading/initialization and global plugin can be loaded without decompiler instance.

@mostafaNazari702 we still need to fix all issues mentioned by you in #2960 (comment), because this commit only apply code refactoring, so work on global plugins feature continues 🙂

@skylot skylot closed this Oct 1, 2026
@mostafaNazari702

Copy link
Copy Markdown
Contributor Author

I commit my approach to master,

Understood.

@mostafaNazari702 we still need to fix all issues mentioned by you in #2960 (comment),

Will get started soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants