#java – How to use javap
Explore tagged Tumblr posts
Text
How to Decompile Java Class Files

Decompiling Java class files is an invaluable skill for Java developers. It allows one to delve into the source code of open-source or proprietary libraries used in a project. While it's always beneficial to attach source files in development environments like Eclipse for commonly used libraries, it's not always feasible. This is where Java decompilers come into play. With these tools, developers can easily retrieve the source of any .class file. sequenceDiagram participant Developer participant Eclipse IDE participant JD-Eclipse participant javap Developer->>Eclipse IDE: Opens Java project Eclipse IDE->>JD-Eclipse: Uses JD-Eclipse for decompilation Developer->>javap: Uses javap command javap->>Developer: Returns decompiled code or bytecode
Advantages of Using Java Decompilers in Eclipse
Eclipse IDE has revolutionized the way Java developers work. With a plethora of free plugins available, developers can arm themselves with powerful decompilation tools. One such tool was JadEclipse, an Eclipse plugin that integrated seamlessly with the JAD decompiler. However, with JAD's lack of support for Java 1.5 source, the hunt for a more versatile plugin began. Enter JD-Eclipse, a free Eclipse plugin designed for non-commercial and personal use. JD-Eclipse offers a straightforward installation process, and its website provides a step-by-step guide for those unfamiliar with Eclipse plugin installations. Decompiling Class Files in Eclipse IDE After installing JD-Eclipse and restarting Eclipse, you're all set to decompile Java class files. To do this: - Open any Java project in Eclipse. - Navigate to Maven dependencies or libraries to view the jar files included in your project. - Expand any jar file without an attached source in Eclipse. - Click on any .class file. The source code will be displayed in the Java editor. While decompiled code offers a glimpse into the workings of a class file, it's always recommended to attach the original source code for frequently used libraries. This ensures better code visibility and access to original comments.
Using the javap Command for Decompilation
For those who often work on command prompts, especially on Linux development servers, the javap command offers a quick way to decompile .class files. Bundled with the JDK installation, javap resides in the JAVA_HOME/bin directory and works directly with .class files. To use javap, ensure that JAVA_HOME is set in your system path. Once set up, javap can provide detailed information about a class file, including its methods and constructors. By using the -private option with javap, you can even view private members of a class. Viewing Bytecode from .class Files For a deeper dive into the workings of a class file, javap can display the bytecode of compiled class files. By running javap with the -c option, developers can view the bytecode, offering insights into the low-level operations of the Java Virtual Machine (JVM). sequenceDiagram participant Developer participant Decompiler participant Build Tool Developer->>Decompiler: Initiates decompilation Decompiler->>Developer: Returns initial decompiled code Developer->>Build Tool: Integrates decompiler for automated decompilation Build Tool->>Developer: Decompiles dependencies during build Developer->>Decompiler: Handles obfuscated code with advanced decompilers
Advanced Decompilation Techniques
Enhancing Code Readability While decompilers can retrieve the source code from a .class file, the output might not always be as readable as the original source code. Variable names might be obfuscated or replaced with generic names, and original comments will be absent. To enhance the readability: - Code Beautifiers: Use code beautifiers or formatters to structure the decompiled code. Tools like Eclipse's built-in formatter can automatically format the code to make it more readable. - Variable Renaming: Manually rename obfuscated or generic variable names to more meaningful ones. This can make the code easier to understand and maintain. - Comments: Add comments to the decompiled code, especially in complex sections. This will help in understanding the logic and purpose of the code. Handling Obfuscated Code Some Java class files might be obfuscated to protect intellectual property and prevent easy decompilation. Obfuscation tools rename classes, methods, and variables to nonsensical names, making the decompiled code hard to understand. In such cases: - Use Advanced Decompilers: Some decompilers are designed to handle obfuscated code better than others. Research and find a decompiler that's known for handling obfuscated code well. - Manual Analysis: It might require a combination of manual analysis and testing to understand the functionality of obfuscated code. Be patient and break down the code section by section. Integrating Decompilers with Build Tools For projects with multiple dependencies, integrating decompilers with build tools can streamline the decompilation process. Tools like Maven and Gradle can be configured to automatically decompile certain dependencies during the build process.
Best Practices for Decompilation
- Legal Considerations: Before decompiling any code, ensure you have the legal right to do so. Decompiling proprietary software without permission can lead to legal consequences. - Backup: Always backup your original .class files before attempting any decompilation. This ensures you can revert to the original state if needed. - Documentation: Maintain documentation of the decompilation process, especially if manual modifications are made to the decompiled code. This will be helpful for future reference and for other developers working on the project.
Conclusion
Decompiling Java class files provides a wealth of information for developers, whether they're working in an IDE like Eclipse or directly from the command line. Tools like JD-Eclipse and javap make the process seamless, ensuring that developers always have access to the source code they need. For those still using JDK versions below Java 5, the JAD decompiler and JADEclipse plugin remain viable options. The Eclipse marketplace also offers a myriad of other decompilation tools worth exploring. Read the full article
1 note
·
View note
Text
java – How to use javap
Javap works against the .class bytecode. So point the classpath at the VariablesTestProject/out or whatever.
If you want perform operations using the javap command, first go to the jar location in cmd prompt.
Eg:
cd /usr/lib/jvm/java-6-openjdk-i386/jre/lib (Linux)
cd D:javasoftwareJavajdk1.6.0_43jrelib (Windows)
The above locations are the rt.jar locations. java.lang.String is the one of the classes in this jar.
0 notes
Text
Java se development kit 12 mac os

#JAVA SE DEVELOPMENT KIT 12 MAC OS HOW TO#
#JAVA SE DEVELOPMENT KIT 12 MAC OS MANUAL#
#JAVA SE DEVELOPMENT KIT 12 MAC OS CODE#
#JAVA SE DEVELOPMENT KIT 12 MAC OS LICENSE#
#JAVA SE DEVELOPMENT KIT 12 MAC OS CODE#
Currently, Java Development Kit is also one of the most popular development environments in which to code Java. Java is one of the most popular coding languages out there, and Java Development Kit (or JDK) is its official development package. You then need a compiler to run as an interpreter to translate your code into something understandable. Programming in any computer language simply requires a text editor and knowledge of syntax, as well as a clear idea of what is you're trying to create. Java Development Kit is the official development kit for the Java programming language. If you're a seasoned Java programmer, Java Development Kit is an absolutely essential coding tool. Coding novices might find this kit a bit over their heads, although there are some demos and example codes provided within the kit itself. Unfortunately, if you have very little or no previous experience coding in Java, Java Development Kit is incredibly complicated to learn without aid. You'll find them in Java Development Kit's subdirectory bin.
#JAVA SE DEVELOPMENT KIT 12 MAC OS HOW TO#
The following steps explain how to configure OpenJDK as default Java Platform in IntelliJ IDEA and how to set each project to use it.Ģ) Open the Project Structure dialog (menu File > Project Structure).ģ) In the leftmost panel, under Platform Settings, click SDKs.Ĥ) Above the panel to the right, click + and select JDK.ĥ) In the dialog that opens, select the installation directory of OpenJDK to be used and click OK.Ħ) If necessary, configure your custom profile and specify the preverify options on the SDK page (in the right-hand part of the dialog).ħ) Click OK in the Project Structure dialog.In addition to the Java Virtual Machine that is essential to perform certain Java-based program types, Java Development Kit has a wide range of tools such as javac, the Java bytecode compiler, javap, disassembler class, and jdb, which is a debugger. In the dialog that opens, select Java > Compilerĥ) Click on "Configure Project Specific Settings." (to the top-right), you should see an empty list.Ħ.2) Right click the project and select "properties"Ħ.3) Select “Java Build Path” on left, then “JRE System Library”, click Edit… In the dialog that opens, select Java > Installed JREģ) Browse to the OpenJDK installation folder and adjust the settings:Ĥ) Open the menu menu Windows -> Preferences. The following steps explain how to configure OpenJDK as default Java Platform in Eclipse and how to set each project to use it.ġ) Open the menu Windows > Preferences.
#JAVA SE DEVELOPMENT KIT 12 MAC OS MANUAL#
Javac manual /usr /lib /jvm /java- 8-openjdk-amd64 /bin / javac Java2groovy auto /usr /share /groovy /bin /java2groovy Java manual /usr /lib /jvm /java- 8-openjdk-amd64 /jre /bin / java Jarsigner manual /usr /lib /jvm /java- 8-openjdk-amd64 /bin /jarsigner Jar manual /usr /lib /jvm /java- 8-openjdk-amd64 /bin / jar Idlj manual /usr /lib /jvm /java- 8-openjdk-amd64 /bin /idlj $ sudo update-alternatives -get-selections OpenJDK is the official reference implementation of Java SE since version 7. Were it not for the GPL linking exception, components that linked to the Java class library would be subject to the terms of the GPL license.
#JAVA SE DEVELOPMENT KIT 12 MAC OS LICENSE#
The implementation is licensed under the GNU General Public License (GNU GPL) version 2 with a linking exception. It is the result of an effort Sun Microsystems began in 2006. OpenJDK (Open Java Development Kit) is a free and open-source implementation of the Java Platform, Standard Edition (Java SE). Legacy components work on JDK from Oracle and are still maintained, but active development is not done under this platform. As of May 2019, OpenJDK 8 is the official Java platform supported by gCube.

0 notes
Photo

JDBC with MySql Learn how to connect your java code with database (MySql) using jdbc driver, com.mysql.jdbc.Driver Released Date: Aug 23, 2020 YouTube Channel Name: aducators #aducators #java #jee #jse #jvm #jdbc #mysql #javaconnection #driver #connectivity #notepad #code #advancejava #javac #javap #learnjava #javatutorial #windows #terminal #beginner #tutorial #installation #guide #subscribe #youtube #programming #coding #follow (at Delhi, India) https://www.instagram.com/p/CHPbcQXnXI4/?igshid=1049t1gt198bl
#aducators#java#jee#jse#jvm#jdbc#mysql#javaconnection#driver#connectivity#notepad#code#advancejava#javac#javap#learnjava#javatutorial#windows#terminal#beginner#tutorial#installation#guide#subscribe#youtube#programming#coding#follow
0 notes
Text
How I Made A Dysfunctional Language In The JVM
Part 1: Introduction
I remember when I first considered making my own language. I was googling how to make an abstract static variable in C#. Turns out you can't. Why? Don't know. You just can't. So this was pretty annoying. But what was even more annoying were the programmers that said not only that you couldn't but you also shouldn't.
They gave some flimsy justification about how it broke OOP or something. It was infuriating. On that day I saw the truth. These languages that were the blueprints of modern programming were just as flawed and opinionated as I was. They weren't better, they weren't worse they just were. And on that day I swore I would write my own language. One where I was in charge.
...
But you know, writing a language is hard. And C#... it's not perfect, but it's good enough. So I let my dream sit on the sidelines for several years.
But one day I saw this coding event called Code With Friends. It was one month to code whatever you want. And I was like, "Hey, you know that language you wanted to make since forever ago? Why don't you just make it?" And then I was like, "That sounds like a good idea." So I did. I entered and made a new language called Muse. And here's how I did it.
Part 2: People VS JVM
So to make a language you need to do two things. First you have to transform the code you write into what's called an abstract syntax tree. And then you have to transform that into instructions that the computer can actually understand, in my case JVM bytecode.
Step one is not too hard. I ended up using a program called ANTLR to do it.
ANTLR... let's just say if I had to do this project over I probably wouldn't use ANTLR. It's buggy. I'll be like, "What are you doing? That is obviously an addition operation!" And ANTLR will be like "No, no, no, I see an assignment operation." despite the fact that the code does not look anything like an assignment.
It is frustrating. And to top it all off the debugging tools for ANTLR are almost non-existent. The tool I used was this IntelliJ plugin. It would only tell you the raw output, not how it got there, but it was good enough. Although the plugin did occasionally crash IntelliJ.
So once you have the abstract syntax tree you have to write JVM bytecode. I used this blog post about writing hello world in the JVM to get the structure of a JVM class file. In fact I started my project by just hard coding the code from the post in my program.
So apart from the various metadata such as how many bytes your code is and the header which says 0xCAFEBABE a JVM file has basically 3 parts. The 'constant pool' part, the actual code, and attributes for the code. It's a big of a simplification. If you want to learn more go read the official JVM documentation here and here.
Anyways the constant pool as you might expect holds constant strings. In fact it's basically a grab bag of different constants. But it's most important job is to tell the code which methods/variables each class has and their type.
So then you have the code. If you've worked with assembly code at all you know what to expect here. The only difference is there are no registers, only a stack. So for example to add 1 and 2 together you'd push them both onto the stack and then use the add operation which would pop 1 and 2 and then push 3 onto the stack.
It's pretty neat. I mean, it's not the most efficient thing in the world. There is a command dup and all it does is duplicate the top value on the stack, but it does simplify things a bit.
And now lastly there's the attributes. Most of the attributes are optional. But there is one that is not. That is the Stack Map Table. This one took me forever to figure out. Basically whenever you use a jump instruction (so in an if or a while or a goto (which I really wanted in my language)) you have to use the Stack Map Table to tell Java what should be the current state (in terms of what's on the stack and what variables are defined) at that instruction address.
I mean, there's technically a flag -noverify which makes it so you don't have to have a Stack Map Table, but this pops up a scary warning about the flag being removed in a future version of Java.
So for the longest time I couldn't get the StackMapTable to work. I should probably mention the javap -v FILE_NAME command. This actually prints out the entirety of the JVM class file in a surprisingly readable way.
It was a lot easier than using a hex editor to view the files, that's for sure. In fact the strategy I was using was write a program in Java, compile it, view the JVM class file, and then copy it in my language. And this worked really well.
Until I hit the Stack Map Table. It didn't make any sense how the JVM was generating the values to put in the table. But after sleeping on it I finally got it.
The stack map entries don't hold the actual instruction numbers. They hold the instruction relative to the last instruction subtracted by 1 for whatever reason. So finally I got it working.
So that's it. You can view the project here. It's not fantastic. I mean, it doesn't support basic things like 64 bit ints and orders of operation. But for a month of work I'm pretty proud of it. And it supports things that some other languages don't support. Things like: variables that start with a number (a worryingly high number of languages don't support this), do while (not supported in python), goto statements,
)
unix directory syntax for global variables (like use ../globalVar to access something in global scope, it always bothered me how you can access a global variable identically to a local one and they can have the same name too, that's a bug just waiting to happen), named return types (it always annoyed me to no end when I had a function that returned a bool. What is it returning? If the operation succeeded? Some information about the operation?), and there are no constructors which brings me to...
Part 3: A Dysfunctional Language
This is a class in C#.
And this is a function in C#.
So this is a class.
And a function.
A class with two variables.
A function with two variables.
A class.
A function.
Class.
Function.
Are you getting it? These are not two separate things. This is one thing. And it's called a Dysfunction.
This is one of the epiphanies I had. A class and a function are fundamentally the same thing. We just use different syntax for each and under the hood they're treated a little differently.
So what if I made a language where you define a function the same way you define a class? Well, version 1 of Muse actually did just that. But I was never happy with it. Because you get a class file whether you want it or not and a random function.
So version 2 of Muse I did away with that entirely. No more functions. Only classes. But what if you actually want to use a function. Something like a square root function? Well, we can do that.
Simply instantiate a class (let's call it squareRoot), do some work in the constructor, save that work to a variable (called squareRootValue) and get that variable in the caller (which in Muse can be done on the same line we create the object). Easy.
This is what Dysfunctional Programming is. Will it take off? Well, probably not in the JVM because we have to make new objects on the heap which is much slower than on the stack.
But if I were to port this to something like LLVM and make it so dysfunctions that aren't assigned to a variable are allocated on the stack sure, why not?
Dysfunctional programming could be the next big thing.
0 notes
Text
How to find out the jdk version which compiled a class in java
How to find out the jdk version which compiled a class in java
You can easily determine the jdk version with which a given java file was compiled using the below command.
javap –verbose <class file name>
The above command should be executed at the location where the class file is placed or otherwise the entire path of class file needs to be given. [the_ad id=”651″] Open the command prompt on windows or terminal on linux/mac systems and navigate to the…
View On WordPress
0 notes
Link
In our previous blog The Story of Trait – Part 2, we have discussed that traits can have implementation too and how they behave under the hood.
In this blog, we will discuss mixins one of the most charming features of traits.
Mixins are the wonderful concept of object-oriented programming. Sadly, some of the mainstream object-oriented programming languages like C++, Java, C#, have not provided mixins. But we can use mixins in languages like Groovy, Scala etc.
What are mixins?
In layman terms, suppose you go to an ice cream shop. You can have ice creams like vanilla, butterscotch etc. But you prefer to take vanilla flavour with chocolate topping with some peanuts. Chocolate toppings and peanuts are mixins. So you can get lots of mixins on top of your ice cream. And another person can enjoy same flavoured ice cream but with different mixins like strawberry and cherries on top of it. The point is you can have any number of mixins on top of it.
So, traits give us the ability to add mixins to the class we have.
For example, we have a class Human which has a method listen,
scala> class Human(val name: String){ | def listen() = println(s"i am $name, listening...") | } defined class Human scala> val mahesh = new Human("Mahesh") mahesh: Human = Human@51a9ad5e scala> mahesh.listen i am Mahesh, listening...
We know that Dog is also the best friend of Human. So, we want another class Dog which has a method listen. But it will violate the DRY principle. We will go creating a trait Friend which will have listen method and abstract field name and mix will trait Friend into Human and Dog class.
scala> trait Friend{ | val name: String | def listen = println(s"i am $name, listening...") | } defined trait Friend scala> class Human(val name: String) extends Friend defined class Human scala> val mahesh = new Human("Mahesh") mahesh: Human = Human@cdc3aae scala> mahesh.listen i am Mahesh, listening... scala> class Animal defined class Animal scala> class Dog(val name: String) extends Animal with Friend defined class Dog scala> val scooby = new Dog("Scooby") scooby: Dog = Dog@173b9122 scala> scooby.listen i am Scooby, listening...
If a class does not extend from other classes or traits use extends keyword. And if a class extends from class and traits. Use extends to class and with for traits. Here class Human and Dog mixes in Friend trait.
So, we can say the trait is also a behaviour that can be mixed or assimilated into a class hierarchy. Traits look similar to classes but have some differences. First, the mixed-in class has to implement the abstract variable and values declared them. Second, trait constructor can not take parameters whereas class constructors can have.
Traits also provide the facility of selective mixins. We can also mix in traits selectively at an instance level. This will allow you to treat a specific instance of a class as a trait.
For example,
scala> class Cat(val name: String) extends Animal defined class Cat
Cats are generally not good friends of Human so they don’t have listen method too. But if you have a special cat Tom which listens to you. We do want to treat some cats as a friend. It won’t be hard to make some cats friendly. What we can do is we can mix friend trait at the instance level.
scala> val tom = new Cat("Tom") with Friend tom: Cat with Friend = $anon$1@17d2ed1b scala> tom.listen I am Tom, listening...
So you can see, Tom is listening. So, in general, cats are not treated as friendly. We can take selected objects of cat and make them friendly. This is the ability to provide traits or mixin traits at an instance level.
Let’s see how it works under the hood:
After compiling above code, we will see Scala compiler creates three .class files for Sample i,e. Sample.class, Sample$$anon$1.class and Sample$delayedInit$body.class.
If you look at Sample$delayedInit$body.class using javap, you will notice,
javap -c Sample\$\$anon\$1.class Compiled from "Sample.scala" public final class Sample$$anon$1 extends Cat implements Friend { public void listen(); Code: 0: aload_0 1: invokestatic #16 // Method Friend$class.listen:(LFriend;)V 4: return public Sample$$anon$1(); Code: 0: aload_0 1: ldc #21 // String Tom 3: invokespecial #24 // Method Cat."":(Ljava/lang/String;)V 6: aload_0 7: invokestatic #27 // Method Friend$class.$init$:(LFriend;)V 10: return }
Notice anonymous inner class extends from class Cat and implements Friend. Scala implements instance level traits using anonymous inner classes which extend from that particular class and implement the trait as well. So tom is an instance of the anonymous inner class created by Scala compiler.
We have seen how traits provide mixins and selective mixins as well. How selective mixins are handled at bytecode level. In next blog, we will look how Scala solves the problem of multiple inheritence. Till then, Stays tuned
Please feel free to suggest and comment.
References:
Pragmatic Scala
0 notes
Link
In our previous blog The Story of Trait – Part 1, we have discussed how traits are the just regular interfaces at the very basic form. In this blog, we will explore about traits can have method implementation too.
We will continue with our previous example and modify it and see how trait behaves in different scenarios.
Here we have implemented two method and other method is abstract in trait Animal and class Cat will extend it and give an implementation of abstract method comeToMaster. Let’s see how trait looks now under the hood.
If you take a trait with an implementation in it, it quickly becomes two things instead of one i.e an interface and an abstract class as well.
After compiling Sample.scala, use ls for .class files. And you will notice there will be two class files for Animal i.e Animal.class, Animal$class.class.
If you take a look at them, Animal class will have an interface and Animal$class will have abstract base class. Let see first Animal.class, that should be an interface.
javap -c Animal.class Compiled from "Sample.scala" public abstract class Animal$class { public static void speak(Animal); Code: 0: getstatic #13 // Field scala/Predef$.MODULE$:Lscala/Predef$; 3: ldc #15 // String speaking.. 5: invokevirtual #19 // Method scala/Predef$.println:(Ljava/lang/Object;)V 8: return public static void walk(Animal); Code: 0: getstatic #13 // Field scala/Predef$.MODULE$:Lscala/Predef$; 3: ldc #24 // String walking fastly.. 5: invokevirtual #19 // Method scala/Predef$.println:(Ljava/lang/Object;)V 8: return public static void $init$(Animal); Code: 0: return }
Oh! , wait a minute, this does not show the interface, it is an abstract class. And if you see the Animal$class it will show the same bytecode as above. What exactly is happening?
Let’s dig deeper, we are being fooled by the tool. Let’s remove the Animal$class.class and now we are having only Animal.class.
javap -c Animal.class Compiled from "Sample.scala" public interface Animal { public abstract void speak(); public abstract void walk(); public abstract void comeToMaster(); }
Now you can see how the tool is fooling us. In Animal.class file, there is an interface. And All methods become abstract in interface i.e speak, walk, comeToMaster. We know that speak and walk have already implemented and the only comeToMaster is truly abstract in a trait.
What exactly happens at the bytecode level?
We can think about it slightly differently, we can provide our implemented method in abstract AnimalClass. In other words, when we give the implementation in a trait.
What Scala does under the hood, it moves an implementation to an abstract base class and keeps the trait as an interface all the way.
Let’ see the bytecode of Cat class,
Compiled from "Sample.scala" public class Cat implements Animal { public void walk(); Code: 0: aload_0 1: invokestatic #17 // Method Animal$class.walk:(LAnimal;)V 4: return public void speak(); Code: 0: getstatic #26 // Field scala/Predef$.MODULE$:Lscala/Predef$; 3: ldc #28 // String meow.... 5: invokevirtual #32 // Method scala/Predef$.println:(Ljava/lang/Object;)V 8: return public void comeToMaster(); Code: 0: getstatic #26 // Field scala/Predef$.MODULE$:Lscala/Predef$; 3: ldc #35 // String catch me if you can.. 5: invokevirtual #32 // Method scala/Predef$.println:(Ljava/lang/Object;)V 8: return public Cat(); Code: 0: aload_0 1: invokespecial #38 // Method java/lang/Object."":()V 4: aload_0 5: invokestatic #41 // Method Animal$class.$init$:(LAnimal;)V 8: return }
Notice, Cat class implements the Animal trait. However, it does implement the walk method. walk method makes an invokestatic call to walk method of abstract class Animal$class. Since we have overridden method speak in Cat, so it won’t make an invokestatic call to an abstract class.
So, we saw how trait behaves when it has an implemented methods also and how things work under the hood. In next blog, we will see the mixin of traits. Till then Stay tuned
Please feel free to suggest and comment.
References:
Scala CookBook
0 notes