FindBugs raises a bug called EI_EXPOSE_REP caused by Array - java

FindBugs raises a bug called EI_EXPOSE_REP with the following description :
EI: May expose internal representation by returning reference to mutable object
Returning a reference to a mutable object value stored in one of the object's fields exposes the internal representation of the object. If instances are accessed by untrusted code, and unchecked changes to the mutable object would compromise security or other important properties, you will need to do something different. Returning a new copy of the object is a better approach in many situations.
class Person {
private String[] hobbies;
String[] getHobbies(){ return hobbies;}
void setHobbies(String[] hobbies){ this.hobbies = hobbies;}
}
I know some solutions:
getHobbies(){return hobbies.clone();}
use List instead of Array;
What I want to know is why just array raises this bug, a list doesn't have this problem? Why array is so different from other collections?

Findbugs (which is now replaced by Spotbugs) raises a security issue. It is not a bug since it doesn't create an unwanted behavior by itself. But this exposure of the internal data CAN create bugs later in caller methods.
You guessed it, there are two ways to protect your getter against exposure:
Return a copy of your array with Arrays.copyOf(..)
Convert it to an "Immutable" List with Collections.unmodifiableList(..) (you can also use List.of(..) since Java 9)
A List will raise a similar warning unless made unmodifiable.
It's a good practice to use Collections instead of Arrays unless you really have a good reason not to.
In some cases, when you have few writes and many reads, the Class CopyOnWriteArrayList is a great alternative to have a simple immutable list getter.
What I want to know is why just array raises this bug.
It's just a warning. Findbugs displays a severity level next to the report.
Exposure is a medium one for security, but low for bugs.
A list doesn't have this problem?
It does. An ArrayList is just an Array with an additional layer of abstraction.
Why array is so different from other collections?
An Array is a native type, while Collections are not.
The behavior is similar, but you have less control over an Array than you have over a Collection.

I got this issue for byte[] variable in my POJO class. If you want, you can suppress it using an annotation: #SuppressFBWarnings(value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2"})

Related

Is it possible to find out if some list is fixed size or not?

Is it possible to find out if some a list is fixed size or not?
I mean, for example this code:
String[] arr = {"a", "b"};
List<String> list = Arrays.asList(array);
returns fixed size List backed by an array. But is it possible to understand programmatically if List is fixed-size or not without trying to add/remove elements and catching the exception? For example:
try {
list.add("c");
}
catch(UnsupportedOperationException e) {
// Fixed-size?
}
A list created from a String[] by
List<String> list = Arrays.asList(array);
will have Arrays as enclosing class, while one created by for example new ArrayList() won't have the enclosing class. So the following should work to check if the List was produced as a result of calling Arrays.toList():
static <T> boolean wasListProducedAsAResultOfCallingTheFunctionArrays_asList(List<T> l) {
return Arrays.class.equals(l.getClass().getEnclosingClass());
}
Beware that this method relies on undocumented behavior. It will break if they added another nested List subclass to the Arrays class.
Is it possible to find out if some list is fixed size or not?
In theory - No. Fixed sizedness is an emergent property of the implementation of a list class. You can only determine if a list has that property by trying to add an element.
And note that a simple behavioral test would not reliably distinguish between a fixed sized list and a bounded list or a list that was permanently or temporarily read-only.
In practice, a fixed sized list will typically have a different class to an ordinary one. You can test the class of an object to see if it or isn't a specific class. So if you understand what classes would be used to implement fixed sized lists in your code-base, then you can test if a specific list is fixed sized.
For example the Arrays.asList(...) method returns a List object whose actual class is java.util.Arrays.ArrayList. That is a private nested class, but you could use reflection find it, and then use Object.getClass().equals(...) to test for it.
However, this approach is fragile. Your code could break if the implementation of Arrays was modified, or if you started using other forms of fixed sized list as well.
No.
The List API is identical regardless of whether a List is expandable or not, something that was deliberate.
There is also nothing in the List API that allows you to query it to determine this feature.
You can't completely reliably determine this information by reflection, because you will be depending on internal details of the implementation, and because there is an unbounded number of classes that are potentially fixed-size. For example, in addition to Arrays.asList, there is also Arrays.asList().subList, which happens to return a different class. There can also be wrappers around the base list like Collections.checkedList, Collections.synchronizedList and Collections.unmodifiableList. There are also other fixed-size lists: Collections.emptyList, Collections.singletonList, and Collections.nCopies. Outside the standard library, there are things like Guava's ImmutableList. It's also pretty trivial to hand-roll a list for something by extending AbstractList (for a fixed-size list you need only implement the size() and get(int) methods).
Even if you detect that your list is not fixed-size, the specification of List.add allows it to refuse elements for other reasons. For example, Collections.checkedList wrappers throw a ClassCastException for elements of unwanted type.
And even if you know your list is expandable, and allows arbitrary elements, that doesn't mean you want to use it. Perhaps it's synchronized, or not synchronized, or isn't serializable, or it's a slow linked list, or has some other quality that you don't want.
If you want control over the type, mutability, serializability, or thread-safety of the list, or you want to be sure that no other code has kept a reference to it, the practice is that you create a new one yourself. It's not expensive to do so when unnecessary (memcopies are blazing fast), and it lets you reason more definitely about your code will actually do at runtime. If you'd really like to avoid creating unnecessary copies, try whitelisting instead of blacklisting list classes. For example:
if (list.getClass() != ArrayList.class) {
list = new ArrayList<>(list);
}
(Note: That uses getClass instead of instanceof, because instanceof would also be true for any weird subclasses of ArrayList.)
There are immutable collections in java-9, but there is still no common #Immutable annotation for example or a common marker interface that we could query to get this information.
The simplest way I can think of would be simply to get the name of the class of such an instance:
String nameList = List.of(1, 2, 3).getClass().getName();
System.out.println(nameList.contains("Immutable"));
but that still relies on internal details, since it queries the name of the common class ImmutableCollections, that is not public and obviously can change without notice.

Returning a private collection using a getter method in Java

I have a number of Java classes that use private sets or lists internally. I want to be able to return these sets/lists using a get...List() method.
The alternatives I am considering:
return a reference to the internal object
construct a new set/list and fill it up (this seems bad practice?)
use Collections.unmodifiableList(partitions);
Which of these is the most common / best way to solve this issue?
There are many aspects to consider here. As others already have pointed out, the final decision depends on what your intention is, but some general statements regarding the three options:
1. return a reference to the internal object
This may impose problems. You can hardly ever guarantee a consistent state when you are doing this. The caller might obtain the list, and then do nasty things
List<Element> list = object.getList();
list.clear();
list.add(null);
...
Maybe not with a malicious intention but accidentally, because he assumed that it was safe/allowed to do this.
2. construct a new set/list and fill it up (this seems bad practice?)
This is not a "bad practice" in general. In any case, it's by far the safest solution in terms of API design. The only caveat here may be that there might be a performance penalty, depending on several factors. E.g. how many elements are contained in the list, and how the returned list is used. Some (questionable?) patterns like this one
for (int i=0; i<object.getList().size(); i++)
{
Element element = object.getList().get(i);
...
}
might become prohibitively expensive (although one could argue whether in this particular case, it was the fault of the user who implemented it like that, the general issue remains valid)
3. use Collections.unmodifiableList(partitions);
This is what I personally use rather often. It's safe in the sense of API design, and involves only a negligible overhead compared to copying the list. However, it's important for the caller to know whether this list may change after he obtained a reference to it.
This leads to...
The most important recommendation:
Document what the method is doing! Don't write a comment like this
/**
* Returns the list of elements.
*
* #return The list of elements.
*/
public List<Element> getList() { ... }
Instead, specify what you can make sure about the list. For example
/**
* Returns a copy of the list of elements...
*/
or
/**
* Returns an unmodifiable view on the list of elements...
*/
Personally, I'm always torn between the two options that one has for this sort of documentation:
Make clear what the method is doing and how it may be used
Don't expose or overspecify implementation details
So for example, I'm frequently writing documentations like this one:
/**
* Returns an unmodifiable view on the list of elements.
* Changes in this object will be visible in the returned list.
*/
The second sentence is a clear and binding statement about the behavior. It's important for the caller to know that. For a concurrent application (and most applications are concurrent in one way or the other), this means that the caller has to assume that the list may change concurrently after he obtained the reference, which may lead to a ConcurrentModificationException when the change happens while he is iterating over the list.
However, such detailed specifications limit the possibilities for changing the implementation afterwards. If you later decide to return a copy of the internal list, then the behavior will change in an incompatible way.
So sometimes I also explicitly specify that the behavior is not specified:
/**
* Returns an unmodifiable list of elements. It is unspecified whether
* changes in this object will be visible in the returned list. If you
* want to be informed about changes, you may attach a listener to this
* object using this-and-that method...
*/
These questions are mainly imporant when you intent do create a public API. Once you have implemented it in one way or another, people will rely on the behavior in one or the other way.
So coming back to the first point: It always depends on what you want to achieve.
Your decision should be based on one thing (primarily)
Allow other methods to modify the original collection ?
Yes : return a reference of the internal object.
No :
construct a new set/list and fill it up (this seems bad practice? -- No. Not at all. This is called Defensive programming and is widely used).
use Collections.unmodifiableList(partitions);
return a reference to the internal object
In this case receiver end can able to modify the object's set or list which might not be requirement. If you allow users to modify state of object then it is simplest approach.
construct a new set/list and fill it up (this seems bad practice?)
This is example shallow copy where collection object will not be modifiable but object would be used same. So any change in object state will effect the actual collection.
use Collections.unmodifiableList(partitions);
In this case it returns an unmodifiable view of the specified list. This method allows modules to provide users with "read-only" access to internal lists. This could be used as best practice in situation where you want to keep object's state safe.
I believe the best solution is to return an unmodifiable list. If compared to the construction of a new list, returning an unmodifiable "proxy" of the original list may save the client from implicitly generating a lot of unnecessary lists. On the other hand, if the client really needs to have a modifiable list, let it create a new list by itself.
The problem you still have to consider is that the objects contained into the list may be modified. There is no cheap and easy const-correctness in Java.
The second option is definitely the right way to go.
The other two options depend on your requirements.
If you are not going to modify the list values outside the class, return an unmodifiable list.
otherwise, just return the reference.

Best way to construct a read-only, empty List?

I'm creating an immutable representation of an "event" in my system, and thus for lists of owners passed in the constructor, I'd like to take a read only view of them. Further, if they pass in null for the list, I'd like to make a read-only empty list in that case.
Now, since Collections.unmodifiableList balks at null, I currently have this:
userOwners_ = Collections.unmodifiableList(userOwners != null
? userOwners
: new ArrayList<String>(0));
But that seems a bit ugly and inefficient. Is there a more elegant way to do this in Java?
Collections.emptyList(). But seriously, null should NPE.
An equally ugly, but marginally more efficient answer would be
userOwners_ = userOwners != null ?
Collections.unmodifiableList(userOwners) :
Collections.emptyList();
However there are a couple of other things to observe.
It appears that at some point, someone has decided to use null to represent an empty list. That is poor design ... and results in the need for special handling. Better to set it to either a new list, or emptyList() if you know the list is always empty.
If you haven't consciously decided that null is the way to represent an empty list, then that null is "unexpected" and you should juts let it throw an NPE so you can track down and fix the cause. (It could be a variable that you have assumed is initialized elsewhere ... but isn't. That's a bug.)
There is some confusion about whether you want a "read-only" list or an "immutable" list:
The unmodifiableList() method gives you a list that you cannot modify; i.e. it is "read only". But the original list can still be modified, and those changes will be visible via the "read only" wrapper.
If you want an "immutable" list (i.e. one that cannot be changed at all), you need to clone() the original list, and then wrap the clone using unmodifiableList().
Neither of these will make the elements of the list (the "owner" objects) immutable (if they are not already immutable).
The identifier userOwners_ is a code style violation in the most widely accepted / used Java style guide.
The resultant userOwners_ will still be mutable - any changes to userOwners will be part of userOwners_.
The right way to do this if you really want that member variable to be immutable:
private final List<String> userOwners;
public MyObject(List<String> userOwners){
this.userOwners = userOwners != null ? Collections.unmodifiableList(new ArrayList<String>(userOwners)) : Collections.emptyList();
}
As a minor point, your member variable naming isn't following Java style guidelines (userOwners_ is strange to those of us who read Java code on a regular basis)
To expand on what another poster wrote: Think really, really hard before you accept a null input to a public method (without throwing NPE). This sort of behavior can hide bugs - much better to fail fast and force the caller to think about what they are doing.
My preferred way would be using Guava:
this.userOwners = ImmutableList.copyOf(Preconditions.checkNotNull(userOwners));
Like tackline's answer, this also throws an exception rather than silently translating null into the empty list.
Unlike the other answers here, using ImmutableList.copyOf() ensures that the caller can't pass you a list that they can later mutate.

Java best practices, add to collection before or after object has been modified?

Say you are adding x number of objects to a collection, and after or before adding them to a collection you are modifying the objects attributes. When would you add the element to the collection before or after the object has been modified.
Option A)
public static void addToCollection(List<MyObject> objects) {
MyObject newObject = new MyObject();
objects.add(newObject);
newObject.setMyAttr("ok");
}
Option B)
public static void addToCollection(List<MyObject> objects) {
MyObject newObject = new MyObject();
newObject.setMyAttr("ok");
objects.add(newObject);
}
To be on the safe side, you should modify before adding, unless there is a specific reason you cannot do this, and you know the collection can handle the modification. The example can reasonably be assumed to be safe, since the general List contract does not depend upon object attributes - but that says nothing about specific implementations, which may have additional behavior that depends upon the object's value.
TreeSet, and Maps in general do no tolerate modifying objects after they have been inserted, because the structure of the collection is dependent upon the attributes of the object. For trees, any attributes used by the comparator cannot be changed once the item has been added. For maps, it's the hashCode that must remain constant.
So, in general, modify first, and then add. This becomes even more important with concurrent collections, since adding first can lead to other collection users seeing an object before it been assigned it's final state.
The example you provided won't have any issues because you're using a List collection which doesn't care about the Object contents.
If you were using something like TreeMap which internally sorts the contents of the Object keys it stores it could cause the Collection to get into an unexpected state. Again this depends on if the equals method uses the attribute you're changing to compare.
The safest way is to modify the object before placing it into the collection.
One of the good design rules to follow, is not to expose half-constructed object to a 3rd party subsystem.
So, according to this rule, initialize your object to the best of your abilities and then add it to the list.
If objects is an ArrayList then the net result is probably the same, however imaging if objects is a special flavor of List that fires some kind of notification event every time a new object is added to it, then the order will matter greatly.
In my opinion its depend of the settted attribure and tyle of collection, if the collection is a Set and the attribute have infulance on the method equal or hascode then definitely i will set this property before this refer also to sorterd list etc. in other cases this is irrelevant. But for this exapmle where object is created i will first set the atributes than add to collection because the code is better organized.
I think either way it's the same, personally I like B, :)
It really does boil down to what the situation requires. Functionally there's no difference.
One thing you should be careful with, is being sure you have the correct handle to the object you want to modify.
Certainly in this instance, modifying the object is part of the "create the object" thought, and so should be grouped with the constructor as such. After you "create the object" you "add it to the collection". Thus, I would do B, and maybe even add a blank line after the modification to give more emphasis on the two separate thoughts.

What is the Collections.checkedList() call for in java?

I just want to know for what java.util.Collections.checkedList() is actually used.
I have some code that I know is returning me a List<String> but it's being passed through a chain of messaging calls and returned to me as a java.io.Serializable. Is that checkedList call good for me to turn my Serializable into a List<String>? I know I can cast it to a java.util.List, but I'd rather not have to check each element and I'm not comfortable with assuming each element is a String.
It is used in part as a debugging tool to find where code inserts a class of the wrong type, in case you see that happening, but can't figure out where.
You could use it as part of a public API that provides a collection and you want to ensure the collection doesn't get anything in it of the wrong type (if for example the client erases the generics).
The way you could use it in your case is:
Collections.checkedList(
new ArrayList<String>(uncertainList.size()), String.class)
.addAll(uncertainList);
If that doesn't throw an exception, then you know you are good. That isn't exactly a performance optimized piece of code, but if the list contents are reasonably small, it should be fine.
Not quite:
Collections.checkedList will only decorate the list to prevent any future inserts with objects of the wrong class, it won't check all the elements that are already in the list.
However, you could make a new checkedList, and then call addAll and pass in the list you are unsure about - rather than writing the loop yourself.
A discussion of what checkedList could be used for is available in the documentation for checkedCollection. The reasons given are:
as a debugging aid (if someone has used an unchecked cast)
to ensure safety when passing a collection to be populated by third-party code.
You could use the following from google collections to check that the list does only contain strings:
Iterables.all(list, Predicates.instanceOf(String.class))

Categories

Resources