Col-E / Recaf

The modern Java bytecode editor
https://recaf.coley.software
MIT License
6.02k stars 465 forks source link

Recompiling class with inner classes corrupts class #195

Closed nordleuchte closed 4 years ago

nordleuchte commented 4 years ago

I used Recaf to manipulate a proprietary jar file so that it would log more information that is needed to analyze a problem.

Adding some System.log.println to various classes and recompiling the classes worked fine, until I changed something in a class that had an inner class. Recompiling was allegedly successful, but the exported jar is unusable. When trying to decompile the respective class again, Recaf freezes.

Not sure if this is a general problem or somehow related to this particular jar file. If needed I can provide the jar.

Col-E commented 4 years ago

I take it you've done this with the latest release?

I've been rewriting basically everything from the ground up on the redesign branch (https://github.com/Col-E/Recaf/tree/redesign). Could you see if the issue has been resolved with that version? If not I'll see if I can reproduce the problem myself since I imagine you don't want to provide a proprietary jar publicly.

Col-E commented 4 years ago

0f08442b891937d3d3026791a9cab848a0c59bf4 - should fix your problem

nordleuchte commented 4 years ago

Yes I did this with v1.15.10. Just tested with v2.0.0 but I seem to have general problems with that version. Is recompiling here done by simply saving the changed file with CTRL + S ? When I do that, I get a ton of errors, for example all imported packages do supposedly not exist.

Col-E commented 4 years ago

Yes, Control + S is how saving is handled.

Do the imported classes exist in the jar that contains the classes you are editing? Recompiling requires those imports be in the workspace.

In 2.0.0 there's support for multiple input files per workspace. So you could add in the jar you want to edit then add in all the needed dependencies. The UI for adding additional libraries isn't finished yet but it is supported if you specify them in the as a workspace json file. You could then drop the json file into Recaf and it will load all the files specified.

The json layout looks like this:

{
  "primary": {
    "kind": "jar",
    "source": "temp/tower.jar"
  },
  "libraries": [
    {
      "kind": "jar",
      "source": "src/test/resources/InnerTest.jar"
    },
    { 
        "kind": "url",
        "source": "https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war"
    },
    {
        "kind": "maven",
        "source": "org.ow2.asm:asm:7.3.1"
    }
  ]
}
nordleuchte commented 4 years ago

The imported classes exist in the same jar, yes. Some of the imported classes may require an external jar themselves. Are they being recompiled as well? I just tried with a workspace json file that has an external jar library but I still get the same errors.

Btw: thanks for your prompt responses!

Col-E commented 4 years ago

Recompiling is no different than using javac so every import needs to be located by Recaf. Those external files aren't recompiled, they're only being used as classpath items in the compile process for the current file.

nordleuchte commented 4 years ago

This is strange. Just tried with a different jar and I see the same behaviour. Basically all imports which are not part of Java runtime libraries cannot be found. Did not see anything like this with v1.15.10.

Col-E commented 4 years ago

:thinking:

If you don't mind waiting a few hours I can see about reproducing this case myself when I'm free.

nordleuchte commented 4 years ago

Sure, whenever you have time. Can't expect any support with an open-source project, so I highly appreciate you taking time for this :) Let me know if I can provide any information that may help.

Col-E commented 4 years ago

If I can't reproduce this later, I'd like the jar. But its proprietary so I would like to avoid asking for it.

And no problem :+1:

Col-E commented 4 years ago

Basically all imports which are not part of Java runtime libraries cannot be found.

I've experienced this in a few cases while testing, but it doesn't seem to be consistent across classes.

For instance if I have:

import net.whatever.Example;

/// ... somewhere

Example.method();

But then in some cases where I have removed ONE class in a package, it says it fails to find classes that STILL EXIST... Now that's odd.

Col-E commented 4 years ago

Oh. I've mishandled some temporary caches I reworked a while back...

Col-E commented 4 years ago

11d513014024b1b0b1935c93b6aab9576d837e76 Should fix this for 2.0.0

nordleuchte commented 4 years ago

Works perfectly now, thanks a lot!

Col-E commented 4 years ago

Me: The UI for adding additional libraries isn't finished yet but it is supported if you specify them in the as a workspace json file.

Actually this was a brain-fart on my end. Adding libraries is supported in the 2.0 branch:

image