0

I have a compiled war file that I downloaded from remote server. I could run the application locally. The problem is that I don't have a source code and all java files are already compiled .class files.

Now I want to add some new functionality to the existing project. The application is old and it uses web.xml file to declare servlets. E.g:

    <servlet>
        <servlet-name>ServletOne</servlet-name>
        <servlet-class>path.to.ServletOne</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>ServletTwo</servlet-name>
        <servlet-class>path.to.ServletTwo</servlet-class>
    </servlet>
...

I tried to add a new servlet path in web.xml file like:

    <servlet>
        <servlet-name>ServletOne</servlet-name>
        <servlet-class>path.to.ServletOne</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>ServletTwo</servlet-name>
        <servlet-class>path.to.ServletTwo</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>path.to.MyServlet</servlet-class>
    </servlet>
...

Then I added a new .java file under path.to.MyServlet and copy- pasted all the code from another (compiled) servlet into my new servlet class (I can see the content of .class files, because there is such a functionality in the IDE I'm using, but those classes are in read-only mode. However I cannot compile MyServlet file (cannot convert MyServlet.java to MyServlet.class. Because the rest of the classes are already compiled (.class format, not .java) and all the import codes are not working (MyServlet cannot see other files).

Here is one of the errors I'm getting when I try javac MyServlet.java:

error: package javax.servlet.http does not exist
import javax.servlet.http.HttpServlet;

Of course I can use something like javac -cp path/to/tomcat/servlet-api.jar MyServlet.java ,but what If I will need to import classes that are already in the project? It will get kinda messy, I suppose...

What is the most organic way of continuing development without having the source code?

What I was thinking is building a separate Spring Boot application, however it will be in a different port and there is a requirement of having one time authentification (Meaning, I cannot ask a user to login again when he/she switches between the applications).

I'm using java-8 and the application is deployed on tomcat-7 (If it's helpful)

1 Answers1

1

If you’re planning to make more changes ongoing, and if decompiling the classes is really permissible in your situation, I think the simplest solution is to create a new project, decompile all of the existing classes, and add them to the new project.

If it’s a one-time change, you can unzip the war file, add the unzipped WEB-INF/classes directory to the classpath for the new file you are compiling (for example, javac -cp path/to/tomcat/servlet-api.jar:path/to/unzipped-warfile/WEB-INF/classes MyServlet.java), then add the new compiled class to WEB-INF/classes and repackage into a war file.

Tim Moore
  • 8,958
  • 2
  • 23
  • 34
  • Thank you @Tim . The second approach seems more appropriate in my case, but I need to clarify: 1. The war file is already unziped. 2. Could you elaborate on `adding WEB-INF/classes directory to the classpath for the new file I'm compiling"? If I will add more classes in the future, do I have to repeat this thing again for all the new classes? – ali zhadigerov Dec 17 '21 at 23:46
  • 2. for example, `javac -cp path/to/tomcat/servlet-api.jar:path/to/unzipped-warfile/WEB-INF/classes MyServlet.java` (I updated the answer with this). Yes, if you need to add more classes, you'll need to repeat this, which Is why I'd recommend creating a new project in that case. If you don't want to decompile all classes, you could add the compiled class files to the new project. The more important thing is to have a reproducible way to compile new classes and rebuild the war (using a tool such as Maven, Gradle, etc.). – Tim Moore Dec 18 '21 at 00:09
  • I see. Quick Google search showed that there is no a tool which can decompile multiple classes with 100% accuracy. Could you share such a tool, If you know one? I have around +200 classes, decompiling all of them manually will take too long. – ali zhadigerov Dec 18 '21 at 00:14
  • 100% accuracy might not be possible (because some information from the source code is not present in the byte code), but it might be good enough for your purposes. Your IDE decompiler would not be 100% accurate, either. You didn't say which one you're using, but the engine for the IntelliJ IDEA decompiler is available from GitHub and can be used on the command line with an entire directory: https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine. Also see https://stackoverflow.com/q/28389006/29470 – Tim Moore Dec 18 '21 at 00:38
  • `(some information from the source code is not present in the byte code)` This line is abit ambiguous. I am totally okay If decompiled code will miss some comments, won't have the same alignment as the original source code etc. But If it will lose some important information, which might affect the business logic then I'm not sure how reliable it is... Sorry, I haven't mentioned it, but this project is very important and thousands of people are using it right now. I absolutely must not break it. And I'm using IntelliJ IDEA's default decompiler – ali zhadigerov Dec 18 '21 at 00:46
  • I wouldn’t expect it to break business logic (unless there is a bug in the decompiler). It will be missing comments, original formatting, potentially names of local variables. If you’re worried about it, don’t decompile the classes, just include the compiled classes in the project. – Tim Moore Dec 18 '21 at 01:01
  • Okay. I will include the compiled classes in the new project for now. Thank you, Tim! – ali zhadigerov Dec 18 '21 at 01:04