Identify valid getters and setters - java

I have a requirement like to scan a directory of java(POJO) files, go through each among them, and find out the corresponding variables defined in those POJO's, and to check whether it is having the correct getter and setter name. For Eg:- if empName is the variable name, then it should have getter as getEmpName() and not getempName().
This is because our J2EE application which was build on long time back started failing because of the use of invalid getters and setters, which is not recognizable with the front end technologies.
I have done a basic program in which this can be determined. My exact problem is like on what basis can i identify a variable in a line. In my logic i have written assuming the third word in a line which contains private keyword will be the variable name. just want to know whether this approach is right or do i need to try something different, as it seems the requirement is very generic.

Trying to scan the source files yourself will be painful and involve a lot of edge cases etc.
For example the qualifiers on variables can be in any order, there can be multiple ones. Array brackets can be before or after the variable name, variable's may or may not be being initialized, etc. Some may be commented out or in an inner class.
Your best approach will be to use reflection and scan the objects using that.
Reflection is what allows running Java code to find out about itself. You can write a small program and add the code to scan as libraries for that program. The program can then scan through the classes in those Jars, and for each one use reflection to query the list of methods and variables within.
http://docs.oracle.com/javase/tutorial/reflect/

You are forgetting that variables can have more qualifiers than just the visibility qualifier:
private transient volatile int someVariable;
is valid syntax. It is a private variable which is not serialized and which is shared between threads.
It is also possible to have no visibility-qualifier, which results in a package-private variable (can be accessed by classes in the same package but not from classes in other packages).
int otherVariable;
What you can rely on is that the variable name itself is always followed by 0-n whitespaces and a = or a ;. Unless it is an array, but exposing arrays with simple getters and setters is usually not a good idea.
Method names are always followed by 0-n whitespaces and a (.

Most Of IDE's(Eclipse, Netbeans and IntelliJ IDEA) are having plugins for quality tools(Checkstyle, PMD and FindBug).
Externals tools like SONAR, FISHEYE are also you can use.
Kindly check this link for PMD startup.

Related

Java Constants across packages

I have a project that consists of 5 different packages in Java. All of them contain classes that have magic numbers and hardcoded strings for which I'm looking to create constants. I would like to know what is best practice. Should I create one Constants class for all of the constants in the program that all classes can import? Or would it be more efficient to split up the constants into multiple, smaller files?
In terms of best practices, see the Principle of Least Privilege.
You should extract inline hard coded constants, but you should not put all constants into one monolithic class. Instead, split the constants into contextually appropriate classes ("multiple smaller files") and keep those classes only at the package level they need to be referenced properly.
If the value applies only to one particular class (aka private static final), there is no need to lift this value out of the class. It would only create more work to keep it elsewhere if it is only referenced in that one place.
If the value acts like a global variable or needs to be accessed in many different classes (aka public static final), extracting related values into a separate class makes sense but is probably a code smell you should investigate.
Since you are using packages, consider using package-private (static final) to isolate your configuration values to a single package that needs it.
Consider using configuration/properties files to inject values instead of explicitly hard coding them in a class at all. Depending on your needs, you may use simple Java Properties or there are many libraries/frameworks which can help you handle properties, such as Spring.

Is it possible to compare two .java files methods and fields in all cases?

I am currently taking a project management class and the professor gave this assignment to compare two .java files methods and fields in all cases programmatically. I don't think it's actually possible to do but maybe I am wrong!
The assignment spec is as following (its extremely ambiguous I know)
In this assignment, you are required to write a comparison tool for two
versions of a Java source file.
Your program takes as input two .java files representing those two versions
and reports the following atomic changes:
1. AM: Add a new method
2. DM: Delete a method
3. CM: Change the body of a method (note: you need to handle the case where a method is
relocated within the body of its class)
4. AF: Add a field
5. DF: Delete a field
6. CFI: Change the definition of an instance field initializer (including (i) adding an initialization to a
field, (ii) deleting an initialization of a field, (iii) making changes to the initialized value of a field,
and (iv) making changes to a field modifier, e.g., private to public)
So that's what I am working with and my approach was to use reflection as it allows you to do everything but detect differences in the method body.
I had considered the idea that you could create a parser but that seemed ridiculous, especially for a 3 credit undergrad class in project management. Tools like BeyondCompare don't list what methods or fields changed, just lines that are different so don't meet the requirements.
I turned in this assignment and pretty much the entire class failed it with the reason as "our code would not work for java files with external dependencies that are not given or with java files in different projects" - which is completely correct but also I'm thinking, impossible to do.
I am trying to nail down a concrete answer as to why this is not actually possible to do or learn something new about why this is possible so any insight would be great.
What you got wrong here is that you have started to examine the .class files (using reflection). Some of the information listed above is not even available at that stage (generics, in-lined functions). What you need to do is parsing the .java files as text. That is the only way to actually solve the problem. A very high-level solution could be writing a program that:
reads the files
constructs a specific object for each .java file containing all the informations that needs to be compared (name of the functions, name of the instance variables, etc)
compares the constructed objects (example: addedFunctions = functionsFromA.removeAll(functionsFromB)) to provide the requested results
Note: if this is an assignment, you should not be using solutions provided by anybody else, you need to do it on your own. Likely you will not get a single point if you use a library written by somebody else.

Unused private methods, private fields and local variables

We are using Sonar to review our codebase. There are few violations for Unused private method, Unused private field and Unused local variable.
As per my understanding private methods and private fields can be accessed outside of the class only through reflection and Java Native Interface. We are not using JNI in our code base, but using reflection in some places.
So what we are planning is to do a complete workspace search for these methods and fields and if these are not used anywhere even through reflection, then these will be commented out. Again chances for accessing private methods and fields through reflection are very less. This is for safer side.
Unused local variables can’t be accessed outside of the method. So we can comment out these.
Do you have any other suggestions about this?
I love reflection myself, but to put it in a few words: it can be a nightmare. Keep java reflection to a very controlable (that is, stateless, no global/external variable usage) and minimal scope.
What to look for?
To find private fields and methods turned public, look for Field#setAccessible() and Method#setAccessible(), such as the examples below:
Field privateNameField = Person.class.getDeclaredField("name");
privateNameField.setAccessible(true);
Method privatePersonMethod = Person.class.getDeclaredMethod("personMeth", null);
privatePersonMethod.setAccessible(true);
So, setAccessible() will get you some smoke, but getDeclaredField() and getDeclaredMethod() are really where the fields are accessed (what really makes the fire).
Pay special attention to the values used in them, specially if they are variables (they probably will be), as they are what determine the field accessed.
Do a plain text search
Also, doing a plain text search for the field/method name on the whole project folder is very useful. I'd say, if you are not sure, don't delete before doing a full text search.
If you have many other projects that depend on this one you are trying to change; and if you weren't (or didn't know) the guy who planted those (bombs), I'd let it go. Only would change if really really needed to. The best action would be to get them one by one when you need to make a change to a code around it.
Ah, and, if you have them, running tests with code coverage can also help you big time in spotting unused code.
Calling an unused method via reflection is just weird. And unused fields are could only be used as a deposit via reflection, and used via reflection. Weird too.
Reflection is more in use as a generic bean copying tool.
So a radical clean-up should be absolutely unproblematic. It would be time better spent to look into the usages of java.reflect; whether the reflection code is legitimate. That is more intelligent work than looking for usage of private fields in strings.
And yes, remove it from the source code, which speeds up reading by seconds.
(Of course I understood that this a question of the type: did I oversee something.)

ProGuard obfuscation variable naming, how to avoid local and param prefixes?

I am trying to obfuscate a spring web application using ProGuard. I want to keep class and method names, especially the ones used as spring beans.
But ProGuard renames local variables to local[class name], for example if I have a User object it renames the local variable to localUser. It also renames method parameters to param[Class name], for example if I have a User parameter the variable name in obfuscated method becomes paramUser. So the obfuscated code becomes pretty readable.
I want to prevent ProGuard using local and param prefixes and class names. For example I want it to use x1 instead of localUser. I checked configuration options but I could not find how to do that.
ProGuard manual > Troubleshooting > Unexpected observations after processing > Variable names not being obfuscated
If the names of the local variables and parameters in your obfuscated
code don't look obfuscated, because they suspiciously resemble the
names of their types, it's probably because the decompiler that you
are using is coming up with those names. ProGuard's obfuscation step
does remove the original names entirely, unless you explicitly keep
the LocalVariableTable or LocalVariableTypeTable attributes.
The variable x1 isn't giving away any more information than paramUser, given that the viewed code would be:
public void foo(User x1)
{
...
}
Unless your methods are really long, it wouldn't be hard for anyone reading the method to remember that it's a parameter of type User, which is all that paramUser is saying. Yes, there's a bit of a difference in readability but I wouldn't say it's worth worrying about, personally - if someone's investing enough time to decompile your code to start with, a very small difference like that would be unlikely to deter them. If the class names were obfuscated as well, that makes a bigger difference IMO.
The naming scheme, you are describing, looks like the names regenerated by JD when the LocalVariableTable has been skipped by a Java compiler (see javac -g:var). For me, this is not a bug of ProGuard.
To make more efficient the obfuscation of your applications,
try to replace "protected" by "private" each time that is possible : ProGuard will replace the class, method and field names by short names,
try to use anonymous classes in your code,
and try to split your algoritms in a large number of classes to complexify the understanding of the execution flows.

Efficiently populating a POJO with a large amount of getters and setters

I have a POJO which represents all the properties of my application. It contains a huge amount of Strings ints and booleans (class variables, and their getters/setters).
The problem is that every time a new property gets added, i have to add the variable, the getter, setter, the code that sets it from loading the property file and the code that uses the getter.
My Idea was to refactor this into a getString(String stringToGet), getInt and getBoolean method that pulls from 3 hashmaps. The problem with doing it this way is that I can no longer use EL to get properties eg. ${Properties.telephoneNumber}
Anyone have any other ideas?
Since JSF 2.0 you can invoke methods with parameters in EL:
#{properties.getString('telephoneNumber')}
If you have a class that you are absolutely sure you'll have get/set for every variable, I would just make the variables public. Usually the reason for not doing this is if it's possible you'll want to change the implementation or change variable names or something like that. If you KNOW it's not going to happen, I would go ahead and change the access to public.
Also, if you're using Eclipse (probably other IDEs, but I'm not familiar with them), it can automagically create get/set methods for you, so that shouldn't be a hassle.
I wouldn't use the solution you suggested. It would eliminate the convenience of auto-completion, which is especially needed when there are a lot of methods/variables.
Use your IDE to generate all those setters and getters.

Categories