In software development we are all using the libraries by software providers. Consider in class A there are four functions viz., x,y,z. I just want my development team to avoid using the function x. So instead of telling them not to use, I found an idea. Inherit the class and override all the functions and for the function x an unsupportedmethod exception is thrown and for the rest I'm calling the super methods. There also I found a problem, developers can use the base class A directly, how to avoid the class A being used directly. I found a similar functionality in OSGi, the lib bundles can be brought in and then not exported and so on. Is there are any way to achieve this is java?
I suppose code reviews exist for these reasons. Consider situation where you can not edit the source of a third party, what would you do ? Like Siddharth says, sub class it and throw a meaningful exception and document it with a clear reasons. If someone is using base class even after that, mostly it may not out of ignorance,but it may out of curiosity. That kind of thing can be appreciated personally and for learning, but for the project sake developer has to follow the guidelines.
I think simply telling your developers what to do is preferred over a complex software solution. Sometimes the simple thing is better.
But, if you insist on going down this path, you can enforce your architecture standards using aspects if you're a Spring user. Weave the offending methods with an aspect that throws an exception if they're called.
You can edit library class file in hex editor and modify its access modifier from public to package private. Also you can rename it and then use inheritance to wrap this class. Here you can find class file specification. Once I've tried this technique to substitute jdbc driver class with wraper class that provide some additional logging and other useful tricks.
There is a variety of tools that check source code for adherence to certain rules, such as formatting, dead code, naming conventions for variables etc. Popular ones for Java include the Maven Enforcer plugin, checkstyle and PMD.
These might allow you to write a rule that forbids certain method calls. Then you could check automatically at compile time. As far as I can tell, unfortunately none of the tools above support "illegal method calls" out-of-the-box; however, at least for PMD writing new checks is fairly simple.
Related
I'm developing a library that needs to access layout items of the app implementing it. The only way I know how to do it is with reflection. In other words, if I create a constructor to my Library API like this:
public MyLibraryAPI(String packageName) {
Class appR = Class.forName(String.format("%s.R", packageName));
...
}
And the developer would instantiate the library with his package name as the parameter in the constructor.
What I ultimately need is to let my inner classes know the Android Views used in the developers layout (.xml files) - both the id and the type. Is there a way to achieve this without reflection and escape the performance overhead? I'm certain it cannot be done, but asking in case there's an expert that sees what I fail to notice.
EDIT: Additionally, proguard, by default, obfuscates the code for protection but, as a consequence, fails to provide JVM with means to achieve reflection at runtime, so if I use reflection I would have to ask the developer to turn off proguard obfuscation for his or her R class which is a bummer.
Reflection on Android is extremely costly. Some well-meaning and popular libraries like Roboguice have fallen over partly because of the performance cost of reflection.
I suspect some kind of code generation is the correct solution here. Dagger 2, Butter Knife and the Data Binding Library are successful examples of Android libraries that employ code generation. Since the data binding library performs inspections on the XML, it must be available to code generation libraries at that stage in the build and you may be able to base your implementation on that: here's a link to the source jars at Maven Central.
Apart from that, yes it seems there will be some compromise between ease of use and difficulty-to-implement. If you force your consumers to annotate their classes with your annotations, it becomes harder to use but probably much easier for you to implement. If you restrict yourself to inspecting XML and the generated R file and generating code from just that then I think your job will be a lot more difficult. On the other hand, using annotations has become rather commonplace and it may not be such an issue with your users.
Good luck!
I have created a library which supports an application, however in the newest version of the application the developer has changed the structure without changing the class names.
So version 1 of the application has classX in package A but version 2 has classX in package B. How can I develop my library in a way which allows supporting both of these in the same build?
Edit: My library is dependent on the application, not the other way around.
That is a bad decision, if you still want to make it work you need to provide skeleton classes with old structure and delegate calls to new version of class but it would get very dirty
better to not provide backward compatibility if you are firm with the renaming decision
Short answer: You can't.
Real answer: Your library should be able to exist independently of any application that uses it. The purpose of a library is to provide a set of reusable, modular code that you can use in any application. If your library is directly dependent on application classes, then it seems like a redesign should be seriously considered, as your dependencies are backwards. For example, have A.classX and B.classX both implement some interface (or extend some class) that your library provides, then have the application pass instances of those objects, or Class's for those objects, to the library.
If your "library" can't be designed this way then consider integrating it into application code, making it a direct part of the application, and come up with a better team workflow for you, the other developer, and others to work on the same project together.
Quick fix answer: Do not provide backward compatibility, as Jigar Joshi states in his answer.
Bad answer: You could hack a fragile solution together with reflection if you really had to. But please note that the "real answer" is going to last in the long run. You are already seeing the issues with the design you have currently chosen (hence your question), and a reflection based solution isn't going to prevent that from happening again (or even be reliable).
Background: I notice that in many projects almost all classes in the internal code are public and not final, even if they don't need to be. However, it seems sensible to me to make this decision not by default, but only make classes public if they are actually meant to be used from other parts of the system. Having package protected classes is an easy mechanism to enforce boundaries between modules, and serves as a documentation on the intended use of a class.
If there was a (preferrably free :-) tool to protect all classes that can be protected without breaking the program, and maybe make everything final that has no subclasses, that would be a good starting point to start a conscious use of protection mechanisms. (Of course you need to tweak things afterwards.) Do you know such tool?
Caveat: I am aware that there are better modularization mechanisms like OSGI and the planned superpackages and so forth. But in many current projects this is not an option, and using the plain old Java mechanisms is something you can easily do. Also, this works only if you have shared code ownership (such that everybody can change things back to public as needed) and if you are developing an endproduct, not a library for use by others. I am also not too sure about the benefits of making things final - this prevents AOP and mocking.
CLARIFICATION: As I said, I am not talking about libraries that are thrown over the fence to someone who can't change it, but about internal code of medium sized projects where everybody is encouraged to change and refactor everything as needed. When I am talking about package protected or final think of it as "protected until someone feels a compelling need to lift those restrictions". If someone feels the need to lift the restrictions set by the tool, he is welcome to do so.
Even if there was such a tool, (there isn't), a good programmer wouldn't use it... access specification is a design issue best understood and settled by the programmer himself. Think about it... you make a program and run the tool and get everything sorted (Assuming the tool is super-intelligent in the first place to actually understand your program).. then you decide to modify it... extend some classes, etc.. and you end up extending final classes and making objects of private classes.. (and these are few of the many problems you'll face)...
Thing is.. when the tool does its job, you would no longer even understand your own program.
Bottomline.. stop looking for tools to solve your design issues.. (its like asking for tools that will automatically debug your program)
You can have a look at ATL from Eclipse. Although ATL is used to create model to model transformations between different kinds of models, there is no restriction that source and target model are not of the same type. You could create a transformation from Java to Java that makes your current classes protected or final. MoDisco is a toolset of Eclipse makes use of that, just if you want to see examples.
As good as the Java API is, I need to change the code of some classes in the default API packages (for example java.util.Scanner) for a project I am working on.
Ideally, I would extend the classes I am interested and create my own sub-classes, but the classes I want to extend are declared 'final'. How do you suggest I do this? Will I get into trouble with the compiler if I customize the source code of these packages?
If you can, you should rather wrap and delegate, as suggested in another answer. See the Adapter Pattern.
But there are of course ways to do this if you really need it.
A straightforward approach is to simply modify the code in downloaded sources and substitute your own version of a jar in the classpath.
Another option is to use aspect-oriented programming techniques, likely with AspectJ to intercept and modify calls as needed.
It might also be possible to hack together a solution using reflection and home-grown classloaders, but it will be painful to code.
All of these are however quite risky if you don't know what you're doing. Frequently classes are made final for good reason.
If you tell us more specifically what it is you're hoping to change, we might be able to provide assistance in avoiding what you currently think you need.
you really cant extend a final class..
if u really want to add a functionality by extending a class you can do it by modifying class src. from JDK and save it as your own class and use it.
Don't do that. Write your own code which wraps around the original scanner and use that. To update internal packages, there is an endorsed directory property which you can provide at runtime.
Never do it! Never change core classes. If class is final - use composition not inheritance.
I'm trying to write rules for detecting some errors in annotated multi-threaded java programs. As a toy example, I'd like to detect if any method annotated with #ThreadSafe calls a method without such an annotation, without synchronization. I'm looking for a tool that would allow me to write such a test.
I've looked at source analyzers, like CheckStyle and PMD, and they don't really have cross-class analysis capabilities. Bytecode analysers, like FindBugs and JLint seem rather difficult to extend.
I'd settle for a solution to something even simpler, but posing the same difficulty: writing a custom rule that checks whether each overriden method is annotated with #Override.
Have you tried FindBugs? It actually supports a set of annotations for thread safety (the same as those used in Java Concurrency in Practice). Also, you can write your own custom rules. I'm not sure whether you can do cross-class analysis, but I believe so.
Peter Ventjeer has a concurrency checking tool (that uses ASM) to detect stuff like this. I'm not sure if he's released it publicly but he might able to help you.
And I believe Coverity's static/dynamic analysis tools for thread safety do checking like this.
You can do cross-class analysis in PMD (though I've never used it for this specific purpose). I think it's possible using this visitor pattern that they document, though I'll leave the specifics to you.
A simple tool to checkup on annotations is apt (http://java.sun.com/j2se/1.5.0/docs/guide/apt/ also part of Java 6 api in javax.annotation.processing) however this only has type information (ie I couldn't find a quick way to get at the inheritance hierarchy using the javax.lang.model api, however if you can load the class you can get that information using reflection).
Try javap + regexes (eg. Perl)