Changing splash screen

You can modify the behavior of Intellij IDEA using a mechanism similar to videogame patching. Let's change the startup splash screen of our ide.

  1. Execute jar tf path/to/idea/lib/resources.jar | less and search for "logo.png". Note the file name.
  2. Copy the png image you want in a new directory with the name you found above. (you can pick one from here)
  3. Open the idea launcher script (idea.sh) in an editor
  4. Append this directory to the front of classpath: CLASSPATH="$PATCH_DIRECTORY:$IDE_HOME/lib/bootstrap.jar"

Now the chosen splash screen will be shown on startup.

Overriding Classes

This method can be used to override classfiles as well. Although the process is a bit more involved. This is the general procedure to follow when overriding classes:

  1. Note down the build id of your installation (grep buildNumber $IDE_ROOT/product-info.json)
  2. Goto intellij-community github repo, switch to the branch for your build id, and download the java file you wish to change.
  3. Make the changes you wish to make to that class.
  4. Compile the file and put the output in your patch directory (javac -cp $IDE_ROOT/lib/\* ModdedClass.java -d $PATCH_DIRECTORY)

Unfortunately that's not all there is to it. This is what the boot process of intellij looks like:

  1. The launcher script starts the intellij main class with a couple of utility JARs in the classpath.
  2. The bootstrap code switches to a custom intellij classloader.

This new classloader uses a caching algorithm that doesn't respect the order of classpath entries. So you'll have to write a patch for this classloader that disables caching if you want to override classes that will be loaded by this new classloader:

diff --git a/ClassPath.java b/ClassPath.java index d96fe17..b035481 100644 --- a/ClassPath.java +++ b/ClassPath.java @@ -175,7 +175,7 @@ public final class ClassPath { try { String fileName = className.replace('.', '/') + CLASS_EXTENSION; int i; - if (useCache) { + if (false) { Loader[] loaders = cache.getClassLoadersByName(fileName); if (loaders != null) { for (Loader loader : loaders) { @@ -200,7 +200,7 @@ public final class ClassPath { Loader loader; while ((loader = getLoader(i++)) != null) { - if (useCache && !loader.containsName(fileName)) { + if (!loader.containsName(fileName)) { continue; }

Class being patched: platform/util-class-loader/src/com/intellij/util/lang/ClassPath.java

Once you've added this override to your patch directory, you should be able to override any class in the intellij platform.

Notes

You might get some errors related to @NotNull/@Nullable annotations. You can either delete those annotations from the modified files (s/@NotNull//g) or add placeholder definitions of those annotations. This repository demonstrates how to patch the ide to improve nix integration for build number 211.7142.45.

Remember that this is a patching mechanism, not a plugin. That means that this method is much more flexible, but the modded classfiles are not guaranteed to work with anything other than the ide build number for which you made this change.