Solved

Edit java class file : decompile and recompile without reopening full application

Posted on 2011-02-23
22
2,135 Views
Last Modified: 2012-05-11
Hello Everyone,

We have a java application which needs to be amended to update an FTP password within a class file.

I have inherited this application from a developer who is no longer with us, we have no documentation and do not have access to the original source files. Is it possible to recompile an individual application class file without opening the whole project in eclipse?

This is the decompiled class file:
package com.abc.ftp;

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

public class FtpSender
{

    private static final String HOSTNAME = "xxx.xxx.xxx.xxx";
    private static final String USERNAME = "username";
    private static final String PASSWORD = "password";
    private FTPClient client;

    public FtpSender()
        throws SocketException, IOException
    {
        client = new FTPClient();
        client.connect("xxx.xxx.xxx.xxx");
        if(!FTPReply.isPositiveCompletion(client.getReplyCode()))
        {
            throw new IOException("Unable to connect to ftp server : xxx.xxx.xxx.xxx");
        }
        client.login("username", "password");
        if(!FTPReply.isPositiveCompletion(client.getReplyCode()))
        {
            throw new IOException("Unable to login as username to ftp server : xxx.xxx.xxx.xxx");
        } else
        {
            return;
        }
    }

    public void send(InputStream in, String desiredPath)
        throws IOException
    {
        client.storeFile(desiredPath, in);
        if(!FTPReply.isPositiveCompletion(client.getReplyCode()))
        {
            throw new IOException((new StringBuilder("Unable to store file at : ")).append(desiredPath).toString());
        } else
        {
            return;
        }
    }
}

Open in new window


Many thanks in advance,
Ian.
0
Comment
Question by:IW-SNK
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 6
  • 5
  • +1
22 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 34961009
Looks like you've been lucky there. Try compiling it standalone. Take a backup of the jar file or directory in which that class appears, then either update the jar or overwrite the class file depending on whether the class is in a jar or a directory
0
 

Author Comment

by:IW-SNK
ID: 34961457
Hi Cehj,

Thanks for your comment. The class file is located in a subdirectory of the .jar file.

Apologies if this is a really basic question, I'm not a java developer! but how do I compile the revised text file as a class file?

I initially decomplied with Cavaj to ensure the FtpSender.class file was the one that contained the FTP password.

In eclipse I can open the text version but I am unable to compile, how would I do this? Do I need to create a project first?

If I try to open the .class compiled file in eclipse I receive the following error:
Could not open the editor:
The Class File Viewer cannot handle the given input ('org.eclipse.ui.ide.FileStoreEditorInput').

Many thanks,
Ian.
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 50 total points
ID: 34961582
You don't want to try to open the class file.

>>how do I compile the revised text file as a class file?

Do you have the source code in Eclipse too?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:CEHJ
ID: 34961624
Sorry - you said not

Have you got a JDK installed on your system? If so, you can use javac

If not, start a separate, new, Eclipse project and add that source to your project. Add the necessary jars (Apache Commons Net etc) and let the source compile. Copy the resulting class file into the old project (which should have been backed up first)
0
 
LVL 27

Expert Comment

by:mrcoffee365
ID: 34961652
Or you can bypass Eclipse and compile your decompiled .java file with the different password (is that what you want to do?), then replace the previous .class file in the .jar file with your new .class file.
0
 

Author Comment

by:IW-SNK
ID: 34961752
I'm going to attempt to compile without using eclipse, using javac.
Does it matter which version of the SDK I install? Does it need to be the same version used for the original application?

0
 
LVL 27

Expert Comment

by:mrcoffee365
ID: 34961909
It's better to get the same SDK, but it might not matter.  It depends on the method signatures.  Don't you have javac on the machine with the jars?  If you don't, then you do have a jre -- get the sdk which matches it.
0
 

Author Comment

by:IW-SNK
ID: 34961927
Thanks for the info MrCoffee365.
I'll update the thread once i have installed and compiled the class.
Cheers,
Ian.
0
 

Author Comment

by:IW-SNK
ID: 34962780
I have installed the JDK and registered the PATH variables.

I ran the following from the command prompt with this result:

C:\java_app_path>javac FtpSender.class
javac: invalid flag: FtpSender.class
Usage: javac <options> <source files>
use -help for a list of possible options

Open in new window


Something is wrong somewhere.

I then changed the file from .class to .java and the following errors appeared:
FtpSender.java:6: package org.apache.commons.n
import org.apache.commons.net.ftp.FTPClient;

Open in new window


I am now going to try via eclipse, that way I can load the packages.

Many thanks,
Ian.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 34963412
Is that the real package name? If not, give me the real package name and i'll supply you with the files you need
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 34963592
The design of that class is poor:

a. there are hardcoded credentials in it - hence your current problem
b. the ftp connection isn't closed properly (i wonder if it even works?)

The following (assuming it DOES work) is about the minimum required to get it to work with arbitrary credentials without recompilation:
package com.abc.ftp;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.IOException;
import java.io.InputStream;

import java.net.SocketException;


public class FtpSender {
    private static final String HOSTNAME;
    private static final String USERNAME;
    private static final String PASSWORD;
    private FTPClient client;
    static {
	java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("credentials");
	HOSTNAME = bundle.getString("hostname");
	USERNAME = bundle.getString("username");
	PASSWORD = bundle.getString("password");
    }


    public FtpSender() throws SocketException, IOException {

        client = new FTPClient();

        client.connect(HOSTNAME);

        if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
            throw new IOException(
                "Unable to connect to ftp server : " + HOSTNAME);
        }

        client.login(USERNAME, PASSWORD);

        if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
            throw new IOException(
                "Unable to login as username to ftp server : " + HOSTNAME);
        } else {
            return;
        }
    }

    public void send(InputStream in, String desiredPath)
        throws IOException {
        client.storeFile(desiredPath, in);

        if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
            throw new IOException((new StringBuilder(
                    "Unable to store file at : ")).append(desiredPath).toString());
        } else {
            return;
        }
    }
}

Open in new window

0
 
LVL 27

Expert Comment

by:mrcoffee365
ID: 34964075
Or you can just add the jars to your classpath when you compile the .java file.

So: you compile .java files, you run .class files.  

Run these commands to compile your .java file.  Then you'll need to replace the .class file in the jar.

set CLASSPATH=.;comabc.jar
javac C:/java_app_path/FtpSender.java

Then you'll need to replace the .class file in comabc.jar (I don't know the name of the .jar file these are in -- you'll have to put the right name in):

jar uf comabc.jar com\abc\ftp\FtpSender.class
0
 

Author Comment

by:IW-SNK
ID: 34969155
Thanks so much for your support with this issue. Unfortunately my lack of experience/understanding of java has made this a difficult task.

I followed Cehj's approach with the revised file - updating teh .class file with the new code and saving as a text file with the .class extension. I then ran the application with the uncompiled .class but this did not produce the desired effect. The application generated an error which was not the error text as created in the new file. This makes me think that the application does not store the FTP details in this class file but perhaps somewhere else in the application.

I am going to reach out to the original developer in the hope that he can point me in the direction of the original eclipse project.

Thanks again for your support with this issue.
Ian.
0
 

Author Comment

by:IW-SNK
ID: 34969689
Hi Cehj,

Just for clarrification, when you wrote:
The following (assuming it DOES work) is about the minimum required to get it to work with arbitrary credentials without recompilation:

Does this means that a .class file can be used / accessed by the jar application without recompilation?

ie. decomplie, edit, save as uncompiled file with same name and the app can use it.

Many thanks,
Ian.
0
 
LVL 10

Expert Comment

by:gordon_vt02
ID: 34970161
IW, when you decompile the source, save it as a .java file instead of a .class file and make sure you put it in the same directory structure you found it in in the jar.  The javac compiler (or Eclipse, if you go that route) will create the .class file for you.
0
 
LVL 27

Expert Comment

by:mrcoffee365
ID: 34970197
>>Does this means that a .class file can be used / accessed by the jar application without recompilation?

No -- we mentioned this before.  A .java file is source code -- it cannot be run or executed by anything.  A .class file is the compiled code -- that is what is run.

CEHJ was suggesting you rewrite the code to behave differently.
0
 

Author Comment

by:IW-SNK
ID: 34971237
Hi Mrcoffee365,
Thanks for the clarrification, I thought that was the case.
Cheers,
Ian.
0
 

Author Comment

by:IW-SNK
ID: 35036400
Thanks for the great feedback on this issue. In the end I had to locate the original source files and the amend to the was very easy.
Cheers,
Ian.
0
 

Author Closing Comment

by:IW-SNK
ID: 35036420
My initial question was not answered, recompile .class without eclipse. The solution was to use eclipse so this was the best match comment.
0
 
LVL 27

Expert Comment

by:mrcoffee365
ID: 35036792
Too bad you didn't follow up with all the experts.  I was answering directly how to recompile a .java file into a .class file without using eclipse.   If you use EE again, try to work with the experts on the problem you want to solve.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 35036823
And i'd strongly advise  you to use the code i gave you or something like it or you could well have a similar problem again
0
 

Author Comment

by:IW-SNK
ID: 35038156
Thanks for the feedback, I will take this onboard.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
even odd program using while loop 3 74
by zero exception 10 70
How  can  i  resolve  HTTP Status 404 -? 8 60
Java List 4 41
An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question