What is the best practice for Java code file modification? - java

This question might sound duplicate of this question but they are not the same. I am dealing with some legacy code in which logging was done at entry and exit of most (not all) of the functions of a some (not all) classes. This logging at the two points was added programmatically using Antlr or some similar tool. Now what I have is that legacy code which I want to migrate to the new style. The new style should add an annotation (which would instrument the code to add logging at entry and exit) at the top of each of those functions which had these type of logging and removing the code from those functions.
Taking the approach of Antlr to do this task is problematic because it is unable to understand the new syntax and semantics of Java and fails at multiple places. So what could be the best approach to for this problem?

When maintainability is concerned, keeping the ANTLR based (or for that matter any custom code generation utility) is going to be a challenge especially when there are language changes.
I believe that you could look at the following:
AspectJ
Spring AOP
NOTE: When looking at 3rd party libraries, make sure that the library is being maintained and it fits your requirements without having to customize it much.

Related

Should anyone use unit test library methods and classes in live development environment?

This questions looks weird or may be pointless at all.
Recently, I was reviewing some code in java language where the developer used one of the methods from a unit testing library "org.easytesting".
Example: He was using a method "Strings.isNullOrEmpty" of "Strings" class from this library to verify the non-nullability of some values and was using other classes/methods at other places in the code.
I know a library is developed to make our life easier(basic principles of Java) and can be used anywhere/everywhere, but is there a recommendation about using a unit test library in live development code ?
I know using it won't led to a compatibility issue because unit test cases are executed always.
I searched at many places may be I'm missing a good word to search.
It could be argued that a unit-test library is just a library, but I don't see it like this.
First, the purpose of a unit-test library is to be used in code that is not production code. Which means, that certain quality criteria relevant for production code might not be met. For example, if there is a bug in a unit-test library it is annoying, but normally does not harm the production code. Or, performance may not be quite as relevant, thread safety and so on. I don't want to say that the popular unit-testing frameworks are of a bad quality. But, the developers of these libraries have all the right in the world to take design decisions based on the assumption that their code will not be part of production code.
Secondly, using a library should be done in accordance to the philosophy of the respective library. For example, if you use a certain gui library, this brings implications on the way event handling is done in your application. And, unit-testing frameworks come under the assumption that the framework is in control of the executable (from the test runner). Therefore, all functions from that library may depend on the test runner being set up and running. If some function from the library does not have this dependency, that is an implementation detail which may change with a new version of the library.
Finally, code should communicate intent. That includes includes (pun intended). It was not the intent of the developer to write unit-testing code, but that would be what the inclusion of a unit-testing library would communicate.
Considering that there are other, production-oriented libraries out there which check if a string is empty or null, any use of the testing framework's method should be treated as a strong code smell and identified in code reviews.
In the future, this testing library may introduce a change in other parts which make running it in production either prohibitively expensive or insecure, as the code running through this empty or null check could be leveraged as an area of attack. Worse, if your team wants to pivot away from this testing framework, you now have to change production code which many teams would be reluctant to do if all they're doing is changing test dependencies.
Without looking specifically at test libraries, here's an answer to this more general question:
Should you use the general-programming utility classes that are provided by any framework or library? (For example, should you use the StringUtils/CollectionUtils/etc provided by a web/UI/logging/ORM/... framework).
The arguments by the other answers are still mostly valid even in this more general case. Here are some more:
These utilities have been developed specifically for use by the framework. They likely only contain very specific methods with narrow use cases (those that are actually required by the framework) and nothing more. They might be optimized for specific internal behavior of the framework and not for general purposes.
Framework developers may introduce breaking changes without much thought, since they don't expect many users outside of their framework.
It would be alarming to see imports from e.g. a UI library in your back end code, it looks like code smell.
In modular projects, you wouldn't want to introduce additional dependencies to the framework's utilities (again, a dependency to an UI framework from you back end modules is code smell). It would also add a bunch of unnecessary transitive dependencies that may aren't even compatible with other dependencies.
So I would say generally you shouldn't use the utilities of frameworks, except in those places where you are actually working with those frameworks. But even then you should consider using Apache Commons or Guava etc. for consistency.
Now you could also replace the terms UI and back end with test and production in the last two points. Test frameworks are also special in the sense that you usually don't include them as run-time dependency. So you would need to change the scope of the test dependencies to make them available at run-time. You should avoid this for the reasons given in the last point.

Refactoring java code using scripts

Is there an eclipse based solution to refactor Java code using scripts?
I've read about the Eclipse Language toolkit, but it seems that it implies the creation of a plugin, which sounds like overkill for a one-off operation.
Are there some kind of bindings to a scripting language, or at least a way to call refactoring code from java but without a plugin?
Sample use case : I have a project which uses castor generated classes, and I want to migrate to JAXB 2. It implies a lot of refactoring in the existing code, which cannot be done by search and replace, nor regular expressions, because of the context-sensitveness.
When the refactoring is complex, I usually write a transformation pipeline with Recoder. The only drawback of this tool is that it sometimes breaks the code format (e.g. moving comments around, or adding/deleting whitespace), but so far it has been enough for my requirements.
Eclipse provides some refactoring help. For eg if you select the portion of code you want to refactor and right click, you get an option for Refactor. From which you can extract to a method(the one i commonly use while refactoring), extract interface, superclass etc.
You can also check these:
http://www.eclipse.org/articles/article.php?file=Article-Unleashing-the-Power-of-Refactoring/index.html
Eclipse: Most useful refactorings

Alternatives to Java bytecode instrumentation

I'm starting a project that will have to instrument java applications for coverage purposes (definition-usage of variables, etc). It has to add trace statements and some logic to the application and maybe remove statements.
I have searched for ways of instrument Java code and what I always find is about bytecode instrumentation.
My question is: It's the only way to instrument Java applications? There is any other way to do that? What are the advantages of bytecode instrumentation over the others?
I'll probably use the bytecode solution, but I want to know what are the problems with the other approaches (if any) to decide precisely.
Thanks!
The other method close to changing bytecode is using AOP (Aspect Oriented Programming).
The main library is AspectJ which also mostly defines the area.
The third option that might be interesting (since you are just starting out with the program) is using Spring.
It means you will have to learn a bit about IOC (inversion of control) but it basically means that instead of creating your objects yourself you let spring do it for you, and it has it advantages because when spring is incharge of the creation it can add all sorts of things in the creation process without you having to really declare it all yourself in aspectj.
In terms of complexity I would probably rate it:
spring (easiest)
aspectj
bytecode instrumentation (hardest)
but it's exactly the other way around when talking about capabilities (power). for example doing something like substracting code is only possible using the last one (I think)
You should definitely check out AspectJ
From what you describe you will be able to do what you want with it.
Doing bytecode instrumentation yourself is absolutely possible but it much more complicated.
I think you should check out AsepctJ first and got back to do bytecode instrumentation yourself as last resort.
See my paper on building coverage tools using program transformation engines. This approach has the advantage that it can be used on arbitrary programming languages. In addition, it sees the source code the way the programmer sees it, not as compiled byte codes (as generics get more complex, and get ground into finer byte codes, it gets harder to understand that source code by inspecting the byte code).
It is perhaps worth noting that program transformation generalizes aspect-oriented programming.

What are the risks with Project Lombok?

I'm coming up with performance goals for the new year, and I thought I'd be fun to put a goal to reduce the size of the code base, especially boilerplate. One action I've come up with to address this is to use Project Lombok to make beans as short as they should be. But I have a habit of overlooking downsides to new software and approaches, so I'm relying on the Stack Overflow community: Can anyone tell me why Lombok is a bad idea?
A limitation of Lombok is the fact that it is closely tied to the java compiler. Since the annotation processor API only allows creation of new files during the compilation (and not the modification of the existing files) lombok uses that API as a entry point to modify the java compiler. Unfortunately these modifications of the compiler make heavy usage of non-public APIs. Using lombok may be a good idea but you must be aware that upgrading your compiler may break your code. The probability is low but I always feel uncomfortable using non-public APIs.
In my opinion source code in "Java+Lombok" is not Java source code anymore. I see it as something similar Borland company made many years ago in their Borland C++ Builder IDE for VCL - they introduced "properties" in C++ code effectively introducing some kind of a new programming language that wasn't C++ anymore (not C++ in sense of standard of C++ language). Sources using "Java+Lombok" are not valid sources in sense of Java language specification. Moreover I think annotations were not designed to influence language semantic.
A major downside is IDE support. Since Lombok is not actually a language change, and since your IDE only understands java, you will need an IDE that supports Lombok to get things working right. As of now, that's only Eclipse that includes Eclipse and IntelliJ. If you use eclipse that might be ok, but remember that you are making a decision for future developers as well.
I'd suggest you consider moving some of your code into a less ceremonial language such as groovy. We've had success moving some of our business logic and models into groovy and it works really smoothly.
One potential disadvantage to something like Lombok is that with the setters/getters "missing", source tools may not "recognize" aspects of the resulting object that give it "bean" qualities, since those qualities only manifest in the compiled class.
Another disadvantage is that it's Yet Another piece of "black magic" within the tool chain. Fortunately, it seems to be a rather benign piece (I have not used it), and the fact that it happens at compile time rather than runtime is actually a blessing (IMHO). But, you're not going to be able to reuse or share your code without the project since it's adding artifacts to your code base. So, while the compiled class file may be a "POJO", I'd argue that your source code is NOT a POJO.
Neither of these are crippling downsides, rather just aspects to be aware of looking forward.
As pointed out by user #Jcs in another answer, i would like to add more.
In our project we, are using mapstruct which is used to generate mapper classes, before the code is compiled, using mvn generate-sources command, this is done at process phase using maven processor plugin.
project lombok adds the bytecode for the getter/setter in class file at compile phase.
since process phase is executed before the compile, it finds that there is no getter/setter available in class.
There are some workarounds available to execute compile phase more than one.
See this git hub ticket for more details.
Note : I am using STS ide by Spring and it is supported by lombok :)
It's a third party library, and there are developers who don't know it well.
IDE should support annotations processing (there are plugins for IDEA and Eclipse).
As was mentioned above, your code will be without getters/setters. It leads to sonar/checkstyle violations.
In my opinion, The most obvious risk with Project Lombok is that when you decide to use lombok, you also decide that everyone else who deals with your code uses lombok. This is a true statement for all libraries, but Lombok is special in that it is a build-time dependency and your IDE needs plugins to figure out what is going on. That means anyone who has reason to touch your code ex. someone trying to debug weird behavior, etc.) needs to know how to set it up and how it works. That can be a little frustrating.
To add to other responses.
The main reason to not use it is a new record keyword added as experimental feature in Java 14. Java 16 brings records out of preview which will make project Lombok obsolete in most cases.
Since Java 14 one is able able to write:
record Book(String title, String author, String isbn);
which gives automatically access to the constructor, getters/setter, hashCode, equals and toString methods without any annotations.

How to understand Open Source projects/libraries?

There are few open source projects/APIs/libraries that we use in our project (Spring, Struts, iBatis etc.) and I want to understand their design and how they work internally.
What is the best way to understand these projects? Note that I am already using these libraries in my project. And I know the input-output interaction/configurations for these libraries. What I don't understand is how these APIs/libraries work internally.
The problems I face is:
Finding the entry class of the library. Is there any way I can know the entry class for the library - something which is kicking the whole API?
Tools/Plugins to use in Eclipse to get an overview of the design of the library. Going through each and every class of the library, can be a very daunting task. Is there any tool you would like to recommend which can generate the class diagrams of the API in Eclipse.
Thanks in advance!!
UPDATE: I need some inputs on eclipse plugins which can help me in getting an overview/class diagram of the library
I always use the same strategy for this: I never try to "understand" the code base as a whole, and I usually try to follow the request flow. I read enough of the documentation to determine what is necessary to use the application, and I read that code (Keep all source code loaded in your IDE).
For example, in struts you'll be installing a servlet filter in web.xml. Start reading the filter and follow the path a single request takes through your stack.
Likewise for spring, there are two main entry points, the filter and "getBean", both of which are mentioned real early in the documentation. Read those two.
For both of these cases you'll find one or two classes that represent the "core" of the framework real quickly. Read those really well and let actual use cases & needs drive your further exploration.
Approaching "understanding" of an open source library (or any other code base for that matter) by trying to find all the pieces is usually not a very good way of approaching these things, it will usually just lead nowhere because a lot of these things contain too much code. When following the request flow I find making diagrams can also be quite distracting, it tends to draw attention/focus away from understanding (and since my understanding increases rapidly most of them are out-of-date even before they reach the printer).
Nice question!!!, what I've done, specially in the case of Spring, apart from consulting the Documentation and their API's is to attach the sources of the project to my project on Eclipse, that way I'm able to navigate through the source code, not just the API. Its been quite helpful specially in the case of the Spring-Security project, there were some concepts that I just couldn't understand until I inspected the source code.
That's one of the advantages of using Open Source libraries.
Regards.
Tools like Structure101 (http://www.headwaysoftware.com/products/structure101/index.php), and Lattix (http://www.lattix.com/) let you analyze code and produce architecture diagrams / dependency matrices.
This is not exactly class diagram - the main focus is on layering. So the entry point is usually the topmost layer.
But then again, as I specified above, you will notice that some libs are just a mess, and these tools will not be helpful enough.
See the S101 online demo: http://www.structure101.com/java/
This for example is the Sonar project architecture: http://www.structure101.com/java/tracker/sonar/1.11.1/arch.html
Your best bet for those three would be to consult the official documentation (make sure you are looking at the version you are using) or to get a book on the technology.
Most APIs don't have a class with a main method; they're running in the webserver called by the server itself. Unless they're running as their own server, they won't have a main method.

Categories

Resources