I'm in the midst of converting a legacy app to Spring. As part of the transition, we're converting our service classes from an "instantiate new ones whenever you need one" style to a Springleton style, so I need a way to make sure they don't have any state.
I'm comfortable on the *nix command-line, and I have access to IntelliJ (this strikes me as a good fit for Structural Search and Replace, if I could figure out how to use it), and I could track down an Eclipse install, if that would help. I just want to make absolutely sure I've found all the possible problems.
UPDATE: Sorry for the confusion. I don't have a problem finding places where the old constructor was being called. What I'm looking for is a "bullet-proof" why to search all 100+ service classes for any sort of internal state. The most obvious one I could think of (and the only one I've really found so far) is cases where we use memoization in the classes, so they have instance variables that get initialized internally instead of via Spring. This means that when the same Springleton gets used for different requests, data can leak between them.
Thanks.
In Eclipse you can just right click on a variable/type and there is an option for References (or Declarations) -> (Workspace / Project / Hierarchy) which can help you find all instances of it neatly.
I would suggest using Eclipse's built in refactoring tool, it will do its best to change every instance associated to the class accordingly. I would go a step further and rename the class of that you want to change so, at worst case, a full compile would fail and you can easily fix any of those issues.
Related
Rewriting this for greater clarity.
R.java is a great resource in Android. It's basically cheating, by dynamically changing at compile time to provide access to all of your resources.
It would be awesome to have something like this available for applications running core Java. However, I understand that R.java does some crazy hackery to make this work.
So, here are my goals. If anyone has any ideas to point me in the right direction, that would be great.
1) Public static fields that link to resources defined by the developer.
2) The fields are created dynamically, ie they are not hard-coded into existence.
3) The dynamic creation occurs at compile time, so the following statement would be accepted by the compiler: MyRJava.resourceName.
Is this even remotely possible? Where would I start looking to see if it can be done?
Java doesn't support this, but Groovy does. As a Java developer, you should have no problem picking up Groovy for something like this. One of the nice things about Groovy is that it coexists very well with Java code. Where I work, we frequently go back and forth between the two languages.
Remotely possible. We were successfully using APT and Maven to set up a compile time goal which generates additional Java classes. This however not a real dynamic class generation, as we're doing everything in compile time.
The advantage is that after saving (and the code generator has run), you can use all the genarated fields normally (i.e. in autocomplete, and so on).
It is also possible to create something similar in runtime, i.e. you can create a class file, compile it, and then get access to its fields and methods via reflection. In this case however accessing to the genrated fields are more problematic - and finally you'd better go with a simple Map to hold "resource ids" like R.java.
In any project with relatively big number of dependencies there are always a lot of commongly named classes in different libraries. For example, Configuration is very widely used:
It slows down the programmer as he has to carefully pick the right class from the list. It is also very irritating if you have to use different configurations in one class, so they have to be prepended with full package name.
I'm writing a library which also needs a Configuration class. Should I use this name? Or is it better to name it {Libname}Configuration? Is their any common way to avoid such problems?
I think you should name your class in the way that is most clear of it's usage and you shouldn't care too much if another classes with the same name exist. As you know, the usage of packages reduces the risk of naming collisions.
For any project I think it's good that the whole team should have a convention related to basic naming and formatting used. It's important to use a consistent naming convention so that when new people work on it, they pick it up faster. I think that conventions also help increase productivity since it's easier to remember names.
I think it's good to spend some time thinking about classes, not only in terms of algorithms but also as what business part they fill. To think about why is a class necessary and what brings to the project, can make you more aware of the way your method/class/variable works within the application workflow.
That being said, I think that maybe your IDE has some option to hide some of the classes is shows. I'm using IntelliJ and it has a feature for this situation, even though it's a bit hidden.
I think it is usually not a very good idea to start with library name for a class, simply because in the long run that will make it more difficult to remember, and because it diminishes readability.
There are ways to setup your IDE (depending on which IDE you use) so that autocomplete shows the most used classes first. You can also get to a class quickly by first typing the name, then the library, when using autocomplete. These are all dependent on you IDE. But generally it seems like a bad practice to start a classname with the name of the library.
I recently started working on a POORLY designed and developed web application.. I am finding that it uses about 300 properties files, and all the properties files are being read somewhat like this:
Properties prop= new Properties();
FileInputStream fisSubsSysten = new FileInputStream("whatever.properties");
prop.load(fisSubsSysten);
That is, it is reading the properties files from current working directory.. Another problem is the developers have chosen to use the above lines multiple times within the same java file. For example if there are 10 methods, each method will have the above code instead of having one method and calling it wherever necessary..
This means, we can NEVER change the location of the properties files, currently they are directly under the websphere profiles directory, isn't this ugly? If I move them somewhere else, and set that location in classpath, it does not work.
I tried changing the above lines like this using Spring IO utils library:
Resource resource = new ClassPathResource("whatever.properties");
Properties prop = PropertiesLoaderUtils.loadProperties(resource);
But this application has over 1000 files, and I am finding it impossible to change each file.. How would you go about refactoring this mess? Is there any easy way around?
Thanks!
In these cases of "refactoring" i use a simple find and replace approach. Notepad++ has a " find in files" feature but there are plenty of similar programs.
Create a class which does the properties loading with a method probably with a name parameter for the property file.
This can be a java singleton or a spring bean.
Search and replace all "new Properties()" lines with an empty line.
Replace all "load..." lines with a reference to your new class/ method. Notepad++ supports regex replacement, so you can use the filename as a parameter.
Once this is done go to eclipse and launch a "cleanup" or "organize imports" and fix some compile errors manually if needed.
This approach is quite straight forward and takes no more than 10min if you are lucky or 1 hour if you are unlucky, f.e. the code formatting is way of and each file looks different.
You can make your replace simpler if you format the project once before with a line length of 300 or more so each java statement is on one line. This makes find and replace a bit easier as you dont have newlines to consider.
I can only agree that I find your project a bit daunting, from your reference.
However, the choice of how to maintain or improve of it is a risk that merely needs to be assessed and prioritised.
Consider building a highrise and subsequently realising the bolts that holds the infrastructure have a design flaw. The prospect of replacing them all is indeed daunting as well, so considerations into how to change them and if they really, really needs to be replaced, few, many or all.
I assume it must be a core system for the company, which somebody built and they have probably left the project (?), and you have consideration about improvement or maintaining them. But again, you must assess whether it really is important to move your property files, or if you can just for instance use symbolic links in your file system. Alternatively, do you really need to move them all or is there just a few that would really benefit from being moved. Can you just mark all places in the code with a marker to-be-fixed-later. I sometimes mark bad classes with deprecation, and promise to fix affected classes but postpone until I have other changes in those classes until finally the deprecated class can be safely removed.
Anyway you should assess your options, leave files, replace all or partials, and provide some estimation of cost and consequences, and ask your manager which course to take.
Just note that always overestimate the solution you don't want to do, as you would be twice as likely to stop for coffee breaks, and a billboard of told-you-so's is a great leverage for decision making :)
On the technology side of your question, regex search and replace is probably the only option. I would normally put configuration files in a place accessible by classpath.
You can try using eclipse search feature. For example if you right click on load() method of the properties class and select References -> Project it will give you all location in your project where that method is used.
Also from there maybe you can attempt a global regex search and replace.
Every once in a while I'm in the Eclipse Debug mode, and wish I could simply pick the Object that I am currently inspecting/watching, put some kind of "Object Breakpoint" on it, and step to the next line of code that accesses it.
Now, I know that I can put breakpoints on Classes, but I usually have hundreds or even thousands of instances in memory, most of which have a long life time. They often go in and out of frameworks. They are wrapped into Collections, filtered and unwrapped again. In short: a regular, large application.
Usually I still find the problem by looking for rare features of that Object, using conditional method breakpoints and a lot of informed guessing. However, I think I sometimes could be much faster if I had something like the described feature.
What I found after some searching is the Debug Proxy (scroll down to examples). It is a container class that will use Javas reflection API to make itself look like the contained Object, thus you can use it instead of the contained Object in your application. Being an InvocationHandler, the DebugProxy can now "intercept" invocations of methods in the contained Object.
Using the proxy for actual debugging is as easy as adding this line to your application.
IMyObject = (IMyObject) DebugProxy.newInstance(new MyObject());
I can then set breakpoints inside the DebugProxies source code.
However, there are at least two problems with this approach.
It works but it is still a hack, and there are a lot of features missing, such as filtering options.
The Proxy-Object cannot be down-cast to the implementing class.
The 2. problem is the more serious one. I was able to use the DebugProxy with Classes generated by EMF, and there is no problem to follow the Object throughout the Framework. However, when I am trying to debug code that doesn't use interfaces for all interesting Classes, the DebugProxy will quickly fail.
Does anybody know about alternatives?
Maybe the Eclipse JDT Debugger already has such a feature and I simply don't see it!?
I know there is the Java instrumentation API, and frameworks such as AspectJ. Could these be used to get a practical solution?
I added basic filtering to the DebugProxy and modified the output so Eclipse Console View shows a link to the calling line of code:
Problem number two remains unsolved, though. I put up the source code on GitHub. Maybe somebody will come up with something.
A completely different way to approach this would be to automatically add breakpoints with conditions comparing the current hashCode() with the HashCode of the Object in question. This may not be too difficult for someone who knows more about the JDT internals.
Since the whole Android stuff is open source I was thinking about to do some minor modifications in a few internal classes from the com.android.internal.telephony package and of course then I would love if somehow my application could use the modified classes. I was thinking about replacing the classes with the original ones at runtime by using reflection or other kind of unknown java tricks :D ...maybe what I'm trying to do is impossible :( I don't know that's why I'm asking.
Note: The changes in the internal classes would not change their functionality in any way, its more about extending their functionality so even if other apps would use the modified versions it would not break them!
Why I want to do it? What I'm trying to achieve ?
Well i would like to modify the com.android.internal.telephony.gsm.CallTracker internal class so i could do proper call handling (call blocking etc..)
Maybe if you know about another way how to do what I want to I would like to hear about it :)
Note2: I know about the method when you handle the android.intent.action.PHONE_STATE, action , but its simply too late to react when this action is broadcasted. I'm really looking for a better solution even if that solution involve ugly hacks :)
As always thanks for all your replies...
You cannot do this :) I'll let you imagine what would happen if any application was allowed to freely replace core parts of the system. You can download the Android source code and you can modify it and you can upload the modifications to your phone (if your phone is rooted/unlocked) but you cannot apply such modifications with a simple app.
Changing a classes functionality (methods, byte code) after a class ha been loaded is impossible. Reflection/Invocation does not affect classes but static fields and instances only.
Your looking at a way to add additional methods or change existing methods of a running system, because the classes in question probably will be loaded already when your 'hacking' application is executed.
The only technical approach that I see is to change the classes in advance and deploy a modified system. I'm just ignoring possible licensing issues and security at the moment. But even with this way, your software would depend on a custom OS, a branch from some andorid version, disconnected from official updates, and you'd have to ask your customers to install a custom OS with, say, unknown features.
Sidenote - I'm very happy, that this is really impossible, otherwise my mobile would already be full of trojans, viruses, etc...
Romain is correct you can't and shouldn't try to change existing system classes.
That said, implementing call screening as you suggest should be possible by creating a replacement to the dialer application that handles phone calls.
Specifically the intent ACTION_ANSWER should be handled by your application, which could then either implement a dialer-like interface or open the dialer app (or any other call manager) explicitly.
There are actually ways to hack on Android framework classes, it just depends on which ones you want to hack.
You must extend the class you intent to hack on.
If you want to override package private methods and/or access package private variables you can put your class in the same package.
You can use reflection.
I've actually had to do this to work around bugs. Romain is correct, to an extent. It all depends on the structure of the code you are trying to hack on. You definitely can't hack on Android internals, but you can hack on other framework classes like Activity, View, etc.