I have a webapp running that has a bug. I know how to fix it in the sources. However I cannot redeploy the app as I would have to take it offline to do so. (At least not right now).
I now want to fix the code "at runtime". Surgery on the living object, so to speak.
The app is implemented in Java and is build on top of Seam. I have added a Groovy Console to the app previous to the last release. (A way to run arbitrary code at runtime)
The normal way of adding behaviour to a class with Groovy would be similar to this:
String.metaClass.foo= { x -> x * x }
println "anything".foo(3)
This code added the method foo to java.lang.String and prints 9. I can do the same thing with classes running inside my webapp container. New instances will thereafter show the same behaviour:
com.my.package.SomeService.metaClass.foo= { x -> x * x }
def someService = new com.my.package.SomeService()
println someService.foo(3)
Works as excpected. All good so far.
My problem is now that the container, the web framework, Seam in this case, has already instantiated and cached the classes that I would like to manipulate (that is change their behaviour to reflect my bug fix).
Ideally this code would work:
com.my.package.SomeService.metaClass.foo= { x -> x * x }
def x = org.jboss.seam.Component.getInstance(com.my.package.SomeService)
println x.foo(3)
However the instantiation of SomeService has already happened and there is no effect.
Thus I need a way to make my changes "sticky". Has the groovy magic gone after my script has been run? Well, after logging out and in again, I can run this piece of code and get the expected result:
def someService = new com.my.package.SomeService()
println someService.foo(3)
So the foo method is still around and it looks like my change has been permanent...
So I guess the question that remains is how to force Seam to re-instantiate all its components and/or how to permanently make the change on all living instances...?
The hotfix is not persistent because the calling code is pure Java, not Groovy.
The Groovy magic in fact stays. But only when called from the groovy environment, that is through other groovy code.
Turns out that in a Java environment, the "Keyhole Surgery Pattern", as coined by Dierk König is only usable to change data at runtime, not code. The full power of the pattern is only accessible in a pure Groovy environment.
Not Groovy, but an alternative approach that works - as long as you don't change / add / remove and method signatures - is to set the Server in debug mode and use Java Hot Code Replacement functionality. Most IDE's support this. The changes are permanent and applied to instantiated components as well.
Requires of course that the app server is already configured with the a debug console or allows to enable it after the start.
Related
This is not your usual "my breakpoints don't work" question.
Consider the following code:
Runnable runnable = new Runnable()
{
#Override public void run()
{
Log.debug( "in run()" ); // <-- place one breakpoint here
}
};
#Test public void test()
{
Log.debug( "in test()" ); // <-- place another breakpoint here
runnable.run();
}
If you were to run this test from within IntellijIdea, using IntellijIdea's built-in JUnit support, the following things would happen:
Both logging statements produce output.
Both breakpoints hit.
However:
If you were to run this test from within some other framework, (e.g. Testana) which discovers the test class at runtime, loads it dynamically, and executes each test method in it, then the following happens:
Both logging statements produce output.
The breakpoint in the test() method hits.
The breakpoint in the run() method does not hit.
As a matter of fact, when the breakpoint in the test() method hits, you can see that the breakpoint in the run() method remains a red circle without a checkmark, which means that IntellijIdea does not recognize it as being on executable code.
Just in case it matters, I am currently using macOS, in a few days I am hoping to be able to try under Windows.
There were a couple of similar issues in IntellijIdea reported and fixed a long time ago:
https://youtrack.jetbrains.com/issue/IDEA-79268 (10 years ago)
https://youtrack.jetbrains.com/issue/IDEA-133881 (7 years ago)
Judging by a comment by CrazyCoder (a well known JetBrainiac on Stackoverflow) from May 29 '13 at 13:11 on this question Line breakpoints don't work in some classes which mentions some "debug scope" I suspect that the problem is something along these lines:
The testing framework is launched with its own classpath which does not include the test class.
The testing framework discovers the module containing the test class, creates a new ClassLoader with the class path of the module, uses that ClassLoader to load the test class, and runs the test methods in it.
The IntellijIdea debugger somehow detects that the test class was dynamically loaded, and includes it in whatever that "debug scope" is, so the breakpoint in the test() method hits.
The IntellijIdea debugger fails to detect that the anonymous inner class is also loaded, so it fails to include it in the "debug scope", so the breakpoint in the run() method does not hit.
And now the question:
Is there any workaround that would make the IntellijIdea debugger hit the breakpoint in the anonymous inner class?
Ideally, the workaround would be a general-purpose solution that can be implemented in the testing framework to take care of any similar situation.
A workaround that would make breakpoints work in anonymous inner classes by extra bureaucracy on the side of the test class would also be (barely) acceptable.
(But if you were going to suggest that I convert my anonymous inner class to a separate top-level class, please don't.)
EDIT
Behavior is same on Windows.
Steps to reproduce:
Check out this project: https://github.com/mikenakis/Public
Go to class T01_CompilingIntertwine
Place a breakpoint on line 57 (first line of function run())
Hit your Debug key to bring up the run configurations dialog
There will be a run configuration called Testana - All; launch it.
The breakpoint will not hit.
Make a minor modification to the file and save it (because testana does not run tests that have not changed.)
Place a breakpoint on line 53 (new Runnable())
Relaunch (Debug) Testana - All.
The breakpoint on line 53 will hit. If you resume, then the breakpoint on line 57 will also hit.
So, Konstantin Annikov from JetBrains found this worthy of creating an new issue for it on the IntelliJ IDEA issue tracker, see https://youtrack.jetbrains.com/issue/IDEA-287858
Then, Egor Ushakov from JetBrains looked into it, and found that this is happening because the testing framework is loading the classes in a non-standard order, while IntelliJ IDEA contains some logic that relies on the assumption that the classes will be loaded in the standard order.
The standard order of loading classes (when classes are being loaded by their classloader as they are being executed) is to have the outermost class loaded first, and the inner classes loaded afterwards.
Testana was loading the classes in the order in which the class files are yielded by java.nio.file.Files.walkFileTree(), which is apparently alphabetic, and it just so happens that $ sorts before ., so Testana was loading the inner classes first, and the outermost class last.
I fixed the problem in Testana, and Egor expressed the intention to try and implement a workaround for this case in IntelliJ IDEA. (This is such an edge case that I am not sure it is worth fixing, but anyway, it is his call.)
Whenever I program, I seem to accumulate a lot of "trash" code, code that is not in use anymore. Just to keep my code neat, and to avoid making any expensive and unnecessary computations, Is there an easy way to tell if there is code that is not being used?
One of the basic principles which will help you in this regard is to reduce visibility of everything as much as possible. If a class can be private don't make it default, protected or public. Same applies for methods and variables. It is much easier when you can say for sure if something is not being used outside a class. In cases like this even IDEs like Eclipse and IntelliJ Idea will suggest you about unused code.
Using this practice while developing and refactoring code is the best way to clean unused code confidently without the possibility of breaking the application. This will help in scenarios even when reflection is being used.
It's difficult to do in Java since it's a reflective language. (You can't simply hunt for calls to a certain class or function, for example, since reflection can be used to call a function using strings that can only be resolved at runtime.)
So in full generality, you cannot be certain.
If you have adequate unit tests for your code base then the possibility of redundant code should not be a cause for concern.
I think "unused code" means the code that is always not executed at runtime. I hope I interpreted you correctly.
The way to do a simple check on this is very easy. Just use IntelliJ IDEA to write your code. It will tell you that parts of your code that will never be executed and also the parts where the code can be simplified. For example,
if (x == 5) {
}
And then it will tell you that this if statement is redundant. Or if you have this:
return;
someMethod();
The IDE will tell you that someMethod() can never be reached. And it also provides a lot of other cool features.
But sometimes this isn't enough. What if you have
if (x == 5) {
someMethod();
}
But actually in your code, x can only be in the range of 1 to 4? The IDE won't tell you about this. You can use a tool that shows your code coverage by running lots of tests. Then you can see which part of your code is not executed.
If you don't want to use such a tool, you can put breakpoints in your methods. Then run some tests by hand. When the debugger steps through your code, you can see exactly where the code goes and exactly which piece(s) of code is not executed.
Another method to do this is to use the Find/Replace function of the IDE. Check if some of your public/private methods are not being called anywhere. For example, to check whether someMethod() is called, search for someMethod in the whole project and see if there are occurrences other than the declaration.
But the most effective way would be,
Stop writing this kind of code in the first place!
i think the best way to check that is to install a plugin of coverage like eclemma and create unit and integration tests to get 100% of coverage of the code that accomplish the use code/task you have.
The code that don't need to be tested or don't pass over it after the tests are completed and run, is code that you are not using
Try to avoid accumulating trash in the first place. Remove stuff you don't need anymore. (You could make a backup or better use a source code management system.)
You should also write unit tests for your functions. So you know if it still works after you remove something.
Aside from that, most IDEs will show you unused local variables and private methods.
I do imagine situation when you have app developed by years and some part of your functions doesn't used anymore even they still working. Example: Let's assume you make some changes on internal systems when specific event occured but it is not occurs anymore.
I would say you could use AspectJ to obtain such data / log and then analyze after some time.
I am using a Java library, with two classes Foo and FooConfig; I am unable to change the library code, but can read it. Here are the relevant functions of a Foo:
public class Foo
{
/** Install a configuration on this Foo */
void configure(FooConfig config);
/** Uninstall the current configuration */
void unconfigure();
}
The library creates Foos at times I can't control, and installs configurations shortly after creation. A Foo can only have on configuration at a time. I would like to use MyFooConfig, inherited from FooConfig, instead. Is there any way to intercept the configure call, or the FooConfig constructor, or anything like that to use my class instead?
My current solution is to get a reference to the Foo object shortly after its creation and configuration, uninstall the current configuration,and then install a MyFooConfig instead. This could work, but it causes several different problems (both with being a difficult solution to implement and with some inelegancies which can't be hidden from the user). Is there a better way, preferably using features of Java to intercept the constructor call to FooConfig, or the configure method, or something similar? The closest thing to an alternate solution I've found is to try to use a different ClassLoader to replace FooConfig with my own class behind the scenes, but I don't actually have access to the object that creates the FooConfigs so I don't think that's possible. Other things that looked promising but ultimately didn't pan out are proxy objects (I can't make the Foos be proxy objects), seeing if I could somehow get notified when a FooConfig was created without actually intercepting the constructor (so I could find its Foo and reconfigure it in a better way than I`m currently doing), and changing the library code itself (which, for various reasons, turns out to not be possible).
I don't know much about aspect-oriented programming, but it seems like it could help. Unfortunately, all the AOP Java tools seem to require special compilers, and I don't want to change the build process.
I wrote program in java which is using some kind of win lib and now I want to write one more program to simulate other one. I mean, it should be going like that :
first program asking lib for some simple data ( just true false)
and other program in this same time by using function from this lib setting some variable in this lib which might be return to first program...
both programs are independent first (lets say "getter") in java and second ("setter") in c++... I have already set all variables in lib as static but it didn't solved problem.
Is this kind of solution even possible? or I have to use maybe some kind of socket or else
thanks for replay
I've been working with this kind of stuff (Java + dll + another programs) and I can tell that the libraries executed from another program and Java doesn't share the static variables, so I think you won't be able to do it that way.
The example that I have uses a window, whose size is 0, to exchange messages between the two programs (Java and VB 6.0), the first call between the two programs share the window handler, but I think this isn't the best way to do it, and, in addition, it has some limitations.
I expose the ways I think that could match your problem:
Shared file: pretty easy, just must take care with the encoding.
Memory area: You can use in the dll a memory area for data exchange, this is a truly "static" context
Socket: Maybe is the most flexible since it will work with any program/system.
The last one would be the one that I'll use if I must implement something like that, but that depends on you.
I've always wanted to write a simple world in Java, but which I could then run the 'world' and then add new objects (that didn't exist at the time the world started running) at a later date (to simulate/observe different behaviours between future objects).
The problem is that I don't want to ever stop or restart the world once it's started, I want it to run for a week without having to recompile it, but have the ability to drop in objects and redo/rewrite/delete/create/mutate them over time.
The world could be as simple as a 10 x 10 array of x/y 'locations' (think chessboard), but I guess would need some kind of ticktimer process to monitor objects and give each one (if any) a chance to 'act' (if they want to).
Example: I code up World.java on Monday and leave it running. Then on Tuesday I write a new class called Rock.java (that doesn't move). I then drop it (somehow) into this already running world (which just drops it someplace random in the 10x10 array and never moves).
Then on Wednesday I create a new class called Cat.java and drop that into the world, again placed randomly, but this new object can move around the world (over some unit of time), then on Thursday i write a class called Dog.java which also moves around but can 'act' on another object if it's in the neighbour location and vice versa.
Here's the thing. I don't know what kinda of structure/design I would need to code the actual world class to know how to detect/load/track future objects.
So, any ideas on how you would do something like this?
I don't know if there is a pattern/strategy for a problem like this, but this is how I would approach it:
I would have all of these different classes that you are planning to make would have to be objectsof some common class(maybe a WorldObject class) and then put their differentiating features in a separate configuration files.
Creation
When your program is running, it would routinely check that configuration folder for new items. If it sees that a new config file exists (say Cat.config), then it would create a new WorldObject object and give it features that it reads from the Cat.config file and drops that new object into the world.
Mutation
If your program detects that one of these item's configuration file has changed, then it find that object in the World, edit its features and then redisplay it.
Deletion
When the program looks in the folder and sees that the config file does not exist anymore, then it deletes the object from the World and checks how that affects all the other objects.
I wouldn't bet too much on the JVM itself running forever. There are too many ways this could fail (computer trouble, unexepected out-of-memory, permgen problems due to repeated classloading).
Instead I'd design a system that can reliably persist the state of each object involved (simplest approach: make each object serializable, but that would not really solve versioning problems).
So as the first step, I'd simply implement some nice classloader-magic to allow jars to be "dropped" into the world simulation which will be loaded dynamically. But once you reach a point where that no longer works (because you need to modify the World itself, or need to do incompatible changes to some object), then you could persist the state, switch out the libraries for new versions and reload the state.
Being able to persist the state also allows you to easily produce test scenarios or replay scenarios with different parameters.
Have a look at OSGi - this framework allows installing and removing packages at runtime.
The framework is a container for so called bundles, java libraries with some extra configuration data in the jars manifest file.
You could install a "world" bundle and keep it running. Then, after a while, install a bundle that contributes rocks or sand to the world. If you don't like it anymore, disable it. If you need other rocks, install an updated version of the very same bundle and activate it.
And with OSGi, you can keep the world spinning and moving around the sun.
The reference implementation is equinox
BTW: "I don't know what kinda of structure/design" - at least you need to define an interface for a "geolocatable object", otherwise you won't be able to place and display it. But for the "world", it really maybe enough to know, that "there is something at coordinates x/y/z" and for the world viewer, that this "something" has a method to "display itself".
If you only care about adding classes (and not modifying) here is what I'd do:
there is an interface Entity with all business methods you need (insertIntoWorld(), isMovable(), getName(), getIcon() etc)
there is a specific package where entities reside
there is a scheduled job in your application which every 30 seconds lists the class files of the package
keep track of the classes and for any new class attempt to load class and cast to Entity
for any newlly loaded Entity create a new instance and call it's insertIntoWorld().
You could also skip the scheduler and automatic discovery thing and have a UI control in the World where from you could specify the classname to be loaded.
Some problems:
you cannot easily update an Entity. You'll most probably need to do some classloader magic
you cannot extend the Entity interface to add new business bethod, so you are bound to the contract you initially started your application with
Too long explanation for too simple problem.
By other words you just want to perform dynamic class loading.
First if you somehow know the class name you can load it using Class.forName(). This is the way to get class itself. Then you can instantiate it using Class.newInstance(). If you class has public default constructor it is enough. For more details read about reflection API.
But how to pass the name of new class to program that is already running?
I'd suggest 2 ways.
Program may perform polling of predefined file. When you wish to deploy new class you have to register it, i.e. write its name into this file. Additionally this class has to be available in classpath of your application.
application may perform polling of (for example) special directory that contains jar files. Once it detects new jar file it may read its content (see JarInputStream), then call instantiate new class using ClaasLoader.defineClass(), then call newInstane() etc.
What you're basically creating here is called an application container. Fortunately there's no need to reinvent the wheel, there are already great pieces of software out there that are designed to stay running for long periods of time executing code that can change over time. My advice would be to pick your IDE first, and that will lead you someways to what app container you should use (some are better integrated than others).
You will need a persistence layer, the JVM is reliable but eventually someone will trip over the power cord and wipe your world out. Again with JPA et al. there's no need to reinvent the wheel here either. Hibernate is probably the 'standard', but with your requirements I'd try for something a little more fancy with one of the graph based NoSQL solutions.
what you probably want to have a look at, is the "dynamic object model" pattern/approach. I implemented it some time ago. With it you can create/modify objecttypes at runtime that are kind of templates for objects. Here is a paper that describes the idea:
http://hillside.net/plop/plop2k/proceedings/Riehle/Riehle.pdf
There are more papers but I was not able to post them, because this is my first answer and I dont have enough reputation. But Google is your friend :-)