Win a copy of Building Blockchain Apps this week in the Cloud/Virtualization forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Liutauras Vilda
  • Knute Snortum
  • Bear Bibeault
Sheriffs:
  • Devaka Cooray
  • Jeanne Boyarsky
  • Junilu Lacar
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • salvin francis
Bartenders:
  • Tim Holloway
  • Piet Souris
  • Frits Walraven

Decompiled Jar File Questions

 
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a jar file that I de-compiled and used to create a project in Eclipse. There are tons of errors in the resulting source that I will need to resolve but out of the gate I am not understanding code like this:


The IDE is complaining about 'Stoker$1'. I have a vague idea about what that is but I don't understand where/how it is defined or how to fix it. Can someone help me with this as it is the most common error in the code.

P.S. The only source is from the compiled jar and no there are no proprietary issues involved.
 
Ranch Foreman
Posts: 129
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The dollar sign comes from an anonymous inner class being defined in the original source.
Not enough there to go into more detail, I'm afraid.
 
Saloon Keeper
Posts: 11487
247
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't you have access to the original source code?

If not, then are you licensed to reverse engineer the library you don't have the code to?
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Don't you have access to the original source code?

If not, then are you licensed to reverse engineer the library you don't have the code to?



No and yes. Unfortunately I am not a Java expert although I have done a fair amount of coding.

So, if these classes are defined in the original source but are not in the jar, how can that work?
 
Marshal
Posts: 68110
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have you contacted the program's author or maintainer? Simply try asking for copies of the source code.
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Have you contacted the program's author or maintainer? Simply try asking for copies of the source code.



The author has decided to no longer support the application and destroyed the source before agreeing to let us have the code. The only thing left is the jar file.
 
Marshal
Posts: 25215
65
Eclipse IDE Firefox Browser MySQL Database
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The jar file should also contain Stoker$1.class, I believe. You will be decompiling that too.

The original source code for Stoker will have contained an anonymous inner class, as Zachary mentioned. The source code for that inner class will come from Stoker$1.class.

I'm not certain where in Stoker.java you should put that inner-class source code, though. It's been a long time since I used decompiled Java code. So what I would suggest is this: Put aside that code for a bit. Write your own Java class which uses an anonymous inner class. Then decompile the compiled version of that and see what it looks like, and how it differs from the original.
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. I can see Stoker$1.class in the jar file. But why was that not de-compiled along with everything else? I am trying to understand anonymous inner classes but I'm not there yet. I am also seeing this type 'this.this$0'. That is even more difficult to understand.
 
Zachary Griggs
Ranch Foreman
Posts: 129
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What are the argument inputs to the Stoker_Switch constructor that is being executed there?
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Paul Clapham
Marshal
Posts: 25215
65
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Then StokerSwitch is a nested class, contained inside some other class of unknown name. Every nested class has a "secret" reference to its containing class which ends up being called "this$0" in the compiled code.

So if StokerSwitch was nested inside class StokerAbc, your line 13 in the original version would look like this:

 
Paul Clapham
Marshal
Posts: 25215
65
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And actually if you look at the constructor in the code you posted, you'll notice that the call to super(...) in that constructor isn't the first line executed. Us mere mortal Java programmers aren't allowed to do that, you can't have anything before the call to super(...).

But that line of code is inserted by the compiler to support the nested class mechanism. And I believe that the first parameter is also inserted by the compiler, in order to provide the instance of Stoker_Switch with a reference to its containing class. Which means that its containing class would be Stoker.

So perhaps Stoker_Switch is the mysterious Stoker$1.
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There  are many spots where the super method is not first. I don't know how the author was able to get away with that but that is one of the numerous things I am fixing. Anyway, perhaps if I posted the entire constructor for the class 'Stoker' (which implements runnable) it will help.
 
Campbell Ritchie
Marshal
Posts: 68110
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good grief How did you manage line 36? Rewrite that part of the code as an array initialiser; much easier and more reliable.
 
Paul Clapham
Marshal
Posts: 25215
65
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can get rid of all of the Stoker$1 references in that constructor because you never need to cast null to a type.
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. Yep, there are lots of weird statements in this thing. Maybe that is why the author destroyed the code. I don't understand how this worked but it did and very well.
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As I whittle down these errors, I am becoming convinced that the de-compiler is adding casts where it shouldn't.
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am almost sure many of my problems are from the de-compiler. This has all kinds of warnings from my IDE about linked lists but I don't see where any are used:
 
Bartender
Posts: 21756
148
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Good grief How did you manage line 36? Rewrite that part of the code as an array initialiser; much easier and more reliable.



Optimiser at work. The original source was probably this:


And the casts might not have actually been needed in the original, but I don't know about that. Certainly casting null is overkill.

The thing that makes it look so horrible breaks down to

because the optimiser knew that that was the same thing as:

And the decompiler didn't expand it back.

It's actually a lot like the more common C construct:


Which is admittedly error-prone, especially before compilers began flagging possible "=" versus "==" confusion, but is a terse way of handling how C deals with reading strings.
 
Paul Clapham
Marshal
Posts: 25215
65
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Sam Ritter wrote:I am almost sure many of my problems are from the de-compiler.



No, remove "almost" from that statement. The decompiler isn't guaranteed to produce the same source that was in the original version. It does its best, I guess, but see Tim's just-posted example for why it can't be perfect.
 
Stephan van Hulst
Saloon Keeper
Posts: 11487
247
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Sam Ritter wrote:I don't know how the author was able to get away with that but that is one of the numerous things I am fixing.


They didn't. It's things that Java bytecode is allowed to get away with. Apparently the decompiler is not smart enough to understand that this$0 is a reference to the enclosing class, and that it should not include it as a constructor parameter or initialize it explicitly.
 
Greenhorn
Posts: 9
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I would recommend some other de-compiler like JD-GUI.
 
Paul Clapham
Marshal
Posts: 25215
65
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lexi-Mae Erickson wrote:
I would recommend some other de-compiler like JD-GUI.



I think that could be an interesting thing to do. It might return different decompiled code than Procyon and the differences could be instructive.
 
Tim Holloway
Bartender
Posts: 21756
148
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually, the "this$0" is a reference to the outer class, I believe, and it establishes a connection that wouldn't otherwise be freely available. Note that the assigment makes the parent reference a member variable in the anonymous inner class.

There's a Java source construct that goes with that, but it has been a very long time and I don't remember it. It's something to do with making outer class members available to the inner class and it has to do with the fact that an anonymous inner class is not the same thing as a subclass.
 
Sam Ritter
Ranch Hand
Posts: 182
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for all the help. I used a different de-compiler and the  result was much better. I am now dealing with other issues that are probably not the de-compiler per se. In any case all the incorrect casts are gone, including the references to anonymous inner classes.
 
Campbell Ritchie
Marshal
Posts: 68110
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Sam Ritter wrote:. . . I used a different de-compiler . . . .

After all that effort, you have found such a simple solution
 
Sam Ritter
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, but having no previous experience with de-compilers, I had no idea one would add all that apparent unnecessary junk.
 
Paul Clapham
Marshal
Posts: 25215
65
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Sam Ritter wrote:Yes, but having no previous experience with de-compilers, I had no idea one would add all that apparent unnecessary junk.



I wouldn't have guessed that either. (The last time I used a decompiler was over a decade ago.) But that's what the forum is for, sometimes people will chime in with unexpected useful information.
 
And inside of my fortune cookie was this tiny ad:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!