Retrieve field values using BeanUtils - java

I want to extract private field values that are not marked by certain custom annotation, is this possible via BeanUtils? If yes, how?

Yes, assuming that you know the fields names. You can use PropertyUtils.getSimpleProperty(...). See also here for an example.

No, it is not possible with BeanUtils. But you can use Java's own reflection tools like this:
public class BeanUtilTest {
public static void main(String[] args) throws ... {
MyBean bean = new MyBean();
Field field = bean.getClass().getDeclaredField("bar");
field.setAccessible(true);
System.out.println(field.get(bean));
}
public static class MyBean {
private final String bar = "foo";
}
}
Please consider: Accessing private fields with reflection is very bad style and should be done only for tests or if you are sure there is no other way. If you don't have the ability to change the sources of the class you're trying to access, it might be a last resort. But consider that the behavior might change in the future (e.g. as an update of the library you're using) and break your code.
Edit: If BeanUtils or PropertyUtils are working, this means there is a public getter for this property and you should be using it instead of using reflection. Using PropertyUtils on a private field without a public getter throws a NoSuchMethodException.

Related

Maintain path constants for RestControllers

I'd like to know whats the common style to maintain path constants for Rest Controllers.
For example you have something like that:
#RequestMapping(method = RequestMethod.GET, value = ANY_PATH_VALUE)
I do maintain those constants (in the example ANY_PATH_VALUE) at the moment in a class called PathConstants which looks like this:
public abstract class PathConstants {
public static final String ANY_PATH_VALUE = "/path/{SOME_ID}";
...
}
Is it a common way to keep those values straight at the method of the RestController class or is it like I do currently? Or is there a even more common way how to maintain this kind of stuff?
There are two sides to this,
It actually has close to zero performance problem. This has to something with readability.
The first view is keeping the values as native strings there itself in the controllers. This is more readable in the sense that you can directly check the exact API route when you enter the controller.
The second view is keeping it in some other file with static constants. Keeping all the routes like this actually gives you one common place where you can get to know all the API routes you currently support in your application.
I personally prefer the second i.e. keeping all the paths in a file called APIRoutes and further divided by domains.
public class APIRoutes {
public class SYSTEM {
public static final String HEALTH_CHECK = "api/v1/healthcheck";
public static final String LB_HEALTH_CHECK = "lb/v1/healthcheck";
}
public class API {
public static final String SAVE_X = "api/v1/save";
public static final String GET_X = "api/v1/get";
}
public class CACHE {
public static final String RELOAD_X = "cache/v1/load/x";
public static final String RELOAD_Y = "cache/v1/load/y";
}
}
This way in your controller, you have something like
#RequestMapping(method = RequestMethod.GET, value = APIRoutes.API.SAVE_X)
Using constants seems to be a quite reasonable approach. I would, however, define the constants in a final class with a private constructor throwing an AssertionError to enforce noninstantiability:
public final class PathConstants {
// Suppress default constructor for noninstantiability
private PathConstants() {
throw new AssertionError("No instances for you!");
}
public static final String PATH_TO_FOO = "foo";
public static final String PATH_TO_BAR = "bar";
}
Quoting the Item 4 from Effective Java 3rd edition from Joshua Bloch:
Because the explicit constructor is private, it is inaccessible outside the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive because the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown earlier.
As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.
You also could use something like #RequestMapping("${foo.bar}"), where foo.bar is a value defined in a property souce (such as an application.properties file or YAML variant).
Quoting the Spring MVC documentation:
URI path patterns can also have embedded ${…​} placeholders that are resolved on startup by using PropertyPlaceHolderConfigurer against local, system, environment, and other property sources. You can use this, for example, to parameterize a base URL based on some external configuration.
I think it is a reasonable way to maintain paths. Just make sure you always build the paths from other constants. For example, if your path has version, you define the version as another variable.
public static final String VERSION_1 = "/v1";
public static final String USERS_V1 = VERSION_1 + "/users";

How to handle empty constructor with final fields

I have a class like this
public class Test {
private String m_username;
public Test() {}
public Test(String username) {
m_username = username;
}
}
And with Moxy. I can post this POJO to other API using Jersey client without any converting operation. But I need to set the m_username as a final field and that will need the empty constructor to initiate m_username. And also the Moxy doesn't work. How can I fix that?
The question isn't very well asked.
AS far as I understand:
You have to make your field final
You have to keep the empty constructor because your object is automatically serialized/deserialized in a format like JSON, using a library such as those you can find in Spring
Unfortunately, these two constraints can't be held at the same time. You will need to abandon final if you want to keep the empty constructor, and conversely.

Using Java Spring injection with `public static final` objects (for Jakarta Unstandard)

Disclaimer: I understand that trying to use Spring to inject static variables is considered bad practice (and I know there are ways around it, e.g. here). So ultimately I plan to redesign, but am curious about possible solutions or workarounds.
I am using Jakarta's Unstandard tag library (particularly useConstants) to easily expose public static final objects to my JSP pages. I want these static objects to initialize themselves from my database, which means I need to inject a JDBC Template or Data Source. So I want something like:
public class MyGroup {
// #Autowire or inject somehow?
private static /*final?*/ NamedParameterJdbcTemplate jdbcTemplate;
public static final MyGroup GROUP_A = new MyGroup("GROUP_A");
public static final MyGroup GROUP_B = new MyGroup("GROUP_B");
public static final MyGroup GROUP_C = new MyGroup("GROUP_C");
// Instance fields
private int id;
private String name;
private String description;
/**
* Construct a group
*/
public MyGroup() {}
/**
* Construct a group using information from the database
* #param key the key to match
*/
public MyGroup(String key) {
// Do DB stuff using injected JDBC template
this.id = id_from_DB;
this.name = name_from_DB;
this.description = desc_from_DB;
}
}
In my JSP, I could simply do ${MyGroup.GROUP_A.id} and anywhere else in the Java code I could just MyGroup.GROUP_B.getName().
So the problem is that these groups must be final for the Jakarta library to pick them up, but I can't static initialize them via Spring. Thoughts?
This isn't a problem with spring so much as with a conflict between what you want and what java allows. You cannot delay the assignment of a static final property. It has to be set when the class is loaded. Therefore, by the time spring could inject, it is too late.
If you don't have to have it be final, you can open up some options.
Another possibility is it might be possible to create an aspect when intercepts the access of the property, and returns the value you want rather than the stored value. You could then inject the desired value into the aspect.
I've never done it before specifically with static properties, but I presume it is possible. It is not possible to use constant fields (static final fields bound to a constant string object or primitive value) as a JoinPoint since java requires those to be inlined, but since you are pointing to a non-String object, I think using an aspect could work.
To make sure spring injects into your aspect, make sure you tell spring about it via via something like this:
<bean id="someId" class="com.yourdomain.YourAspect" factory-method="aspectOf"/>

How to mock Objects that are not passed as arguments

Imagine the following class
public class ClassToBeTested{
private AnotherClass otherClass;
public void methodToBeTested(){
otherClass = new AnotherClass();
String temp = otherClass.someMethod()
// ...some other code that depends on temp
}
}
Now, if methodToBeTested was designed to accept an instance of AnotherClass I could easily create a mock of AnotherClass and tell Mockito to return a value i prefeer when someMethod() is called. However as the above code is designed AFAIK it's not possible to mock AnotherClass and testing this method will depend on what someMethod() returns.
Is there anyway I can test the above code without beeing dependent on what someMethod() returns using Mockito or any other framework?
If available you can use the Spring ReflectionTestUtils setField method:
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/test/util/ReflectionTestUtils.html#setField%28java.lang.Object,%20java.lang.String,%20java.lang.Object%29
If not write your own its pretty straight forward using reflection, some info here:
http://www.java2s.com/Code/Java/Reflection/Setprivatefieldvalue.htm
Something like the below, you will need additional error handling to get this to work properly:
public void setField(Object obj, String fieldName, Object value) {
Field f = obj.getDeclaredField(fieldName);
f.setAccessible(true);
f.set(obj, value);
}
It can then be called like this:
setField(objUnderTest, "fieldToSet", mockObject);
edit
I have just noticed that you are instantiating it inside the method. If that is absolutely necessary then you should follow the possible duplicate link posted by cyroxx.
Although that practice is often a sign of bad design so if you can take it out I would.
Setting the field by reflection as suggested in the other answer will work.
But if you're doing this sort of thing often, I'd recommend PowerMock (in conjunction with Mockito) or JMockIt to achieve this. Both allow you to mock constructors, statics, final fields... in short, just about anything. Very useful with legacy code.
However, when you're writing new code, and your class has a dependency on another class that you want to isolate in this way, you should consider changing the design so that the other object is passed in to your class instead of being instantiated by it. Search for "Dependency injection" and you'll find plenty...
As a quick fix, I usually wrap the call to new:
protected newAnotherClass() { return new AnotherClass(); }
That way, I can overwrite this method from a unit test. It's dirty but it's quick :-)
Here is a JMockit test which does what you want, very simply:
#Test
public void testTheMethodToBeTested(#Mocked final AnotherClass dep)
{
new NonStrictExpectations() {{ dep.someMethod(); result = "whatever"; }};
new ClassToBeTested().methodToBeTested();
new Verifications() {{
// verify other calls to `dep`, if applicable...
}};
}

How can I access private class members in Java?

I have data model classes that contain private fields which are meant to be read-only (via a getter function). These fields are set by my JPA persistence provider (eclipselink) during normal operation, using the contents of the database. For unit tests, I want to set them to fake values from a mockup of the persistence layer. How can I do that? How does eclipselink set these values, anyway?
Simplified example:
#Entity
class MyEntity
{
#Id
private Integer _ix;
public Integer ixGet()
{
return this._ix;
}
}
Can you just Mock the Entity itself, providing your own implemenations of the getters?
You could create an anonymous extension in your mock persistence layer:
MyEntity x = new MyEntity() {
public Integer ixGet() { return new Integer(88); }
};
You need to use the Reflection API. Use Class.getField() to get the field, then call setAccessable(true) on that field so that you may write to it, even though it is private, and finally you may call set() on it to write a new value.
For example:
public class A {
private int i;
}
You want to set the field 'i' to 3, even though it is private:
void forceSetInt(Object o, String fieldName, int value) {
Class<?> clazz = o.getClass();
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(o, value);
}
There are a number of exceptions that you will need to handle.
You can use a test library like Mockito to access objects internal state in read and write mode. For example with Mockito use:
//read
Integer i = Whitebox.getInternalState(myEntity,"_ix")
//Write
Whitebox.setInternalState(myEntity,"_ix", 123)
You can use a mocking framework like powermock to by pass encapsulation. In powermock you'd use Whitebox.setInternalState(..) to set a private member.
A less invasive method would be to mock the getter method. Whether this is feasible would depend on what else depends on the internal state but if it is enough, it's the cleaner solution.
Some methods I've used in the past:
Make _ix protected, create a subclass where you implement a setter
Make a constructor taking the value for _ix as a parameter
Use reflection
Another option, if you really hate to make things public, is to create a subclass for testing, and provide public access there.
You have a few options:
Create stubs to replace your entity (extract an interface first)
Use Reflection
Add a public setter for testing
Keep your tests within the package and use a default scope
For a bunch of useful techniques, have a look at Michael Feather's book, Working Effectively With Legacy Code
You can add constructor with parameter for your read-only variable. Don't forget to add a default (zero parameter) constructor.
#Entity
class MyEntity
{
#Id
private Integer _ix;
public MyEntity(Integer ix) {
_ix = ix;
}
public MyEntity() {
/*
* Default constructor
*/
}
public Integer ixGet()
{
return this._ix;
}
}
The constructor is a best way I think. If this entity has to be really readonly (not allowed to create new instances in production code at all) you can make constructor with package access and use it only within the tests. And there is a possibility that even if you make your default constructor private or with package access, your persistance provider still be able to work with such entity, but not sure though - check with eclipselink docs.

Categories