0

I used DJ JAVA DECOMPILER tool to get back the source code from .class file in java. What the source file it generated was having different code than what i coded earlier in the original source program.

What my doubt is:

  1. Is this because of JVM does code optimization before creating the target code for better execution speed & reduce space and time complexity?
  2. Or the decompiler tool modify the .class file code to generate the source program again?

See the original source program was this:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;


public class Test1 {
    /**
     * @param args
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public static void main(String args[]) throws SQLException, ClassNotFoundException{
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection con= DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:choxx","choxx","choxx");
        if(con==null){
            System.out.println("not established");
        }else{
            System.out.println("established");
        }

        Statement st= con.createStatement();
        //st.executeQuery("create table student if not exists(sno number(10), name varchar2(30), addr varchar(20))");
        if(st!=null){
            System.out.println("table created..");
        }

        st.execute("delete from student where addr='hyderabad'");
        ResultSet rs= st.executeQuery("select * from student");
        while(rs.next()){
            System.out.println(rs.getInt(1)+"   "+rs.getString(2)+"   "+rs.getString(3));
        }


    }
}

After decompilation what i got is:

// Decompiled by DJ v3.12.12.99 Copyright 2015 Atanas Neshkov  Date: 29-03-2015 10:55:31
// Home Page:  http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   Test1.java

import java.io.PrintStream;
import java.sql.*;

public class Test1
{

    public Test1()
    {
    }

    public static void main(String args[])
        throws SQLException, ClassNotFoundException
    {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:choxx", "choxx", "choxx");
        if(con == null)
            System.out.println("not established");
        else
            System.out.println("established");
        Statement st = con.createStatement();
        if(st != null)
            System.out.println("table created..");
        st.execute("delete from student where addr='hyderabad'");
        for(ResultSet rs = st.executeQuery("select * from student"); rs.next(); System.out.println(rs.getInt(1) + "   " + rs.getString(2) + "   " + rs.getString(3)));
    }
}
vrwim
  • 13,020
  • 13
  • 63
  • 118
Choxx
  • 945
  • 1
  • 24
  • 46
  • Can you please explain any of the changes you've observed ? – sathya_dev Mar 29 '15 at 05:21
  • So it's done the compiler for Optimization purposes. If you compare the for loop you've done in your source and the while loop in the decompiled version you can get the idea. – sathya_dev Mar 29 '15 at 05:30
  • see the example i edited in the question. In the original source code i used **while loop**. Later after decompilation i saw that the while loop is replaced with **for loop** and still the code was working fine. – Choxx Mar 29 '15 at 05:30

2 Answers2

0

The Java compiler does virtually no optimization of the code produced (though there is a little, like evaluating constant expressions and inlining certain static final fields).

The thing though is that you can't realistically expect to get back the exact code you started with. Java is not a scripting language, and the code is actually compiled into bytecode - the original textual source code is not stored anywhere in the classfiles.

The output you posted is as good as you can possibly expect. You're always going to lose stuff like whitespace, comments, and formatting given that that's not stored at all in the classfile. For the loop at the bottom, there are obviously multiple ways to write the same code, and the decompiler just chose a different way of expressing the same code. Since there is no way to tell which of all the possible equivalent code styles was originally used, the decompiler just guesses.

It's probably just the result of a heuristic that people more commonly write for loops than while loops like you originally had. In this particular case, noone would actually put print statements in a for loop expression like that, but heuristics can't be perfect.

Antimony
  • 37,781
  • 10
  • 100
  • 107
  • Well that's correct you explained but still not satisfied. Can you explain the generated for loop a little bit? – Choxx Mar 29 '15 at 06:13
  • @choxx If you look closely at the for loop, you'll notice that it's doing the same thing as your while loop. The statements in the for loop are usually used to just increment a variable, but there's nothing saying they have to. – Antimony Mar 29 '15 at 16:49
  • yeah i got that exactly. I am just wondering how the decompiler tools developed such internal logics and the code conversion takes place in this manner. That's really great!! – Choxx Mar 29 '15 at 17:13
  • @choxx You'll have to ask the developers of JAD (the engine used by DJ). Which might be difficult since JAD is so old. – Antimony Mar 29 '15 at 21:11
0

Java Compiler does only, minimal set of optimization.

Most optimization is done by JIT compiler only.(Since it has the most information about the Platform and runtime environment.)

for-loops and while-loops use an identical pattern in byte code. This is not surprising because all while-loops can be re-written easily as an identical for-loop

http://blog.jamesdbloom.com/JavaCodeToByteCode_PartOne.html

Since in bytecode version,, the for loop and while loop looks same, the decompiler might decompile it into while loop.

sathya_dev
  • 513
  • 3
  • 15