7

This may, and should be, a question that has been asked and answered many times over, but I just cant find the answer.

If I have a compiled application running on a server, can I compile the application on my local machine, and swap a class that I compiled on my local machine, with the one on the server?

In other words, can I replace a file that has been compiled and is on the server side, with a file almost identical that has been compiled, and is located, on my local machine?

Since the version on the server side has some hard-coded connections in other files, and I dont know all of the places, I would prefer to only swap the one file that I need, instead of doing a recompile for the application as a whole.

3 Answers 3

7

The answer to your question is yes, you can replace a class file, but it is somewhat complicated in that you have to be sure that no other dependencies have changed.

For example, if the class you are compiling involved changing method signatures of methods that are used in other classes, you will need to replace those as well. As long as the method signatures of public, protected, or default methods aren't changed, you should be okay.

As a side-note, if this is something you do often, you'll quickly realize why objects are often passed into methods instead of individual parameters.

public MyObject getObject(MyObject2 mySecondObject)

vs

public MyObject getObject(int a, int b, int c)

When you need to add a new property to an object passed into a method, the method signatures don't change, but when you add or remove a parameter on the method signature itself, it creates a chain reaction on all dependencies, requiring that you compile and replace those class files as well.

As a final point to highlight, it's worth noting that changes you make to private methods or private variables, or even the definitions of a method, have no bearing or impact on other class files. The only thing that matters is that you uphold the contract that your methods have with other classes in that the inputs and outputs always take and return the same data types.

This highlights the importance of encapsulation of instance variables and how those dependencies are hidden from other classes.

Sign up to request clarification or add additional context in comments.

2 Comments

how about JDK version? i think the new class file must be compiled using the same JDK as the one to be replaced.
Hi @Cam, I'm almost certain that you're right, but honestly it's been so long since I decompiled some Java class files that I can't remember. ;)
2

Yes, you can do it. Moreover due to hot spot the class will be even reloaded at runtime, so you do not have to restart the server. This is very useful during development cycle.

But be careful replacing one separate class. If the class has references to other classes changed in your environment the replacement will fail on server.

1 Comment

It introduces a deployment risk like forgetting local classes, probably unneeded, as hot swapping can detect which classes did not change (classes calculated serialVersionID). It may take longer to deploy a war, but one can make that automatical.
1

I assume you're talking about an 'offline' substitution (I mean you can restart the server).

In this case the following solution can be viable: Java uses classpath variable. There you define series of jars/folders where your process will look for files.

So you can do the following:

  1. Create your new class (it should be with the same name and reside in the same package) and compile.
  2. Create on server the folder where you're planning to store your updated class.

  3. Update the classpath variable (probably in the startup script of your application) so that this folder will appear before the rest of your classes.

  4. Restart your server. Now your new class will be resolved before the old one and loaded.

Caution: This works for 'standalone' applications and in general for those that don't fiddle with custom class loaders (for example this is the case in application servers).

More complex solution can be based on define your class loader that will take a look on such a folder (as I've described) and try to load resources from there.

Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.