Is Cloneable needed here? - java

Findbugs gives me for public GsmSignalStrength clone() following warning:
Class defines clone() but doesn't implement Cloneable.
Why do I have to implement Cloneable? Is it because of shallow and deep copy? I have to apologize for my bad Java skills, but I'm a Java newbie.
Here is my code:
class GsmSignalStrength
{
static final byte SIGNAL_STRENGTH_UNKNOWN = 99;
static final byte SIGNAL_STRENGTH_1 = 1;
static final byte SIGNAL_STRENGTH_2 = 2;
static final byte SIGNAL_STRENGTH_3 = 3;
static final byte SIGNAL_STRENGTH_4 = 4;
static final byte SIGNAL_STRENGTH_5 = 5;
/* Constructors */
GsmSignalStrength(byte signalStrength)
{
initClassVars(signalStrength);
}
GsmSignalStrength()
{
initClassVars(SIGNAL_STRENGTH_UNKNOWN);
}
GsmSignalStrength(byte[] serializedData, IntClass deserializationIndex)
{
initClassVars(SIGNAL_STRENGTH_UNKNOWN);
setClassProperties(serializedData, deserializationIndex);
}
byte value;
/* Methods */
public void copyTo(GsmSignalStrength destination)
{
destination.value = this.value;
}
public GsmSignalStrength clone()
{
GsmSignalStrength clonedValue = new GsmSignalStrength();
this.copyTo(clonedValue);
return clonedValue;
}
private void initClassVars(byte signalStrength)
{
this.value = signalStrength;
}
}

Cloneable is not needed here.
This is because your implementation of clone() does not actually clone the object. In Java, cloning specifically means using Object.clone(), which does JVM magic to copy the object. Although your code does something sort of equivalent to cloning (and better, IMHO - it avoids using magic), it is not true cloning.
However, findbugs doesn't know that, so it's worried that you might be trying to clone a non-Cloneable object.
One solution here might be to rename your method to something else (copy()?), so it doesn't appear to be a clone.

You can read the documentation.
A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class.
Invoking Object's clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown.
However you are not using clone() method in the right way. Look at this wiki page.

if you implement clone as
public GsmSignalStrength clone()
{
try{
GsmSignalStrength clonedValue = (GsmSignalStrength )super.clone();
this.copyTo(clonedValue);
return clonedValue;
}catch(CloneNotSupportedException e){thrown new RunTimeException(e);}
}
(which if you are ever going to subclass GsmSignalStrength you are going to need to be according to the documention of Object.clone())
the super.clone call will throw a CloneNotSupportedException

Related

Does it make sense to create a `Copyable` type interface instead of using `Cloneable`?

I have a bit of code that requires a copy of an object be sent in. This requirement is because a service (runtime library) that is called modifies the object sent. This object also needs to expose setters, in case the doThing method below needs to set any field in the ImportantObj class. This implementation is pending change, but does not have a reasonable expectation to be changed in the near future. My workaround is to provide a class that does as follows:
public class DangerousCallWrapper<T> implements DangerousCaller<T> {
public T doThing(T dataObject) {
T cloneOfDataObject = #Clone of dataObject
// This service modifies the cloneOfDataObject... dangerous!
Optional<T> result = service.doThing(cloneOfDataObject);
return result.orElseThrow(() -> new RuntimeException("No data object returned");
}
}
public interface DangerousCaller<T> {
/**
* Performs the functionality of the DangerousService
*/
public T doThing(T);
}
public DangerousService<T> {
public T doThing(T data) {
data.importantField = null;
data.thing = "Done!";
return data;
}
}
public static void main() {
DangerousService service = new DangerousService<ImportantObj>();
ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
service.doThing(important);
//would fail this check
assertNotNull(important.importantField);
DangerousCallWrapper wrapper = new DangerousCallWrapper<ImportantObj>();
ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
service.doThing(important);
//would not fail this check
assertNotNull(important.importantField);
}
So the first line of that method is where I am stuck. It is a generic type, so I can't explicitly call some cloning utility like Jackson, or similar.
So I thought I would just add T extends Cloneable to the method... but I opened the can of worms that Cloneable is beyond taboo (https://www.artima.com/intv/bloch13.html). I have also read that copy constructors are probably the best way to handle this... However, I am unsure of how to denote that using the generics.
So my thought was to provide an interface Copyable that does what you would expect Cloneable to do: expose a method, copy() that will create a new instance of the class.
Does this constitute a viable approach?
To solve your problem you need to polymorphically make a copy of dataObject like this:
T cloneOfDataObject = dataObject.clone();
and the issue is that Cloneable does not have a clone() method, so the above does not compile.
Given this premise, it does make sense to create your own Copyable interface that defines a clone() method so you can leverage already-implemented clone() methods (if they exist) on the classes of your data object. For maximum effectiveness this interface would need to be generic as well:
interface Copyable<T> {
public T clone();
}
and the type bound:
public class DangerousCallWrapper<T extends Copyable<T>>
implements DangerousCaller<T> {

Dealing with final fields when overriding clone

I'm writing a class in which I have to override the clone() method with the infamous "super.clone() strategy" (it's not my choice).
My code looks like this:
#Override
public myInterface clone()
{
myClass x;
try
{
x = (myClass) super.clone();
x.row = this.row;
x.col = this.col;
x.color = this.color;
//color is a final variable, here's the error
}
catch(Exception e)
{
//not doing anything but there has to be the catch block
//because of Cloneable issues
}
return x;
}
Everything would be fine, except that I can't initialize color without using a constructor, being it a final variable... is there some way to both use super.clone() AND copying final variables?
Since the call to super.clone(); will already create a (shallow) copy of all the fields, final or not, your full method will become:
#Override
public MyInterface clone() throws CloneNotSupportedException {
return (MyInterface)super.clone();
}
This requires that the superclass also implements clone() properly (to ensure that the super.clone() eventually reaches the Object class. All the fields will be copied properly (including final ones), and if you don't require deep clones or any other special functionality, you can use this and then promise that you'll never try to implement clone() again (one of the reasons being that it's not easy to implement it correctly, as evident from this question).
Under the assumption that you don't have another choice you can use Reflection. The following code shows how this forks for the field color.
You need some try-catch around it.
Field f = getClass().getDeclaredField("color");
f.setAccessible(true);
f.set(x, this.color)
One thing to keep being mindful of, when mixing clone and final fields, especially the one with initializers, is that (as one of the comments rightfully says), the values are copied from the original, no matter whether that field is final or not, and initializer be damned.
So if a final field has a dynamic initializer, it's actually not executed. Which, IMHO, is breaking a serious expectation that if I have a final instance field in a class, every new instance of this class is going to initialize the field to whatever value the initializer says it should be.
Here is an example where this can be a (insert your level of seriousness) problem:
import lombok.SneakyThrows;
import java.util.HashMap;
import java.util.Map;
public class App {
public static void main(String[] a) {
Cloned c1 = new Cloned();
c1.d.put("x", "x");
Cloned c2 = c1.clone();
System.out.println("c2.x="+c2.d.get("x"));
c1.d.clear();
System.out.println("c2.x="+c2.d.get("x"));
}
static class Cloned implements Cloneable {
public final Map<String, String> d = new HashMap<>();
#Override
#SneakyThrows
public Cloned clone() {
return (Cloned) super.clone();
}
}
}
Output:
c2.x=x
c2.x=null

How to make a java proxy object to java.nio.ByteBuffer instance?

I have a public abstract class java.nio.ByteBuffer instance which is actually an instance of private class java.nio.HeapByteBuffer and I need to make a proxy object which would call some invocation method handler to check access permissions and then call the invoked method on the actual instance.
The problem is that the java.nio.ByteBuffer class has only private constructors and also has some final methods, thus I can not create proxy instances with javassist.util.proxy.ProxyFactory class.
So, how can I make a proxy object to control the invocation of a java.nio.ByteBuffer instance including those final methods invocation?
Please be aware that I am presenting a solution based on my own (FOSS) framework Byte Buddy which is however already mentioned as a potential solution in one of the comments.
Here is a simple proxy approach which creates a subclass. First, we introduce a type for creating proxies for ByteBuffers:
interface ByteBufferProxy {
ByteBuffer getOriginal();
void setOriginal(ByteBuffer byteBuffer);
}
Furthermore, we need to introduce an interceptor to use with a MethodDelegation:
class Interceptor {
#RuntimeType
public static Object intercept(#Origin(cacheMethod = true) Method method,
#This ByteBufferProxy proxy,
#AllArguments Object[] arguments)
throws Exception {
// Do stuff here such as:
System.out.println("Calling " + method + " on " + proxy.getOriginal());
return method.invoke(proxy.getOriginal(), arguments);
}
}
This interceptor is capable of intercepting any method as the #RuntimeType casts the return type in case that it does not fit the Object signature. As you are merely delegating, you are safe. Plase read the documentation for details. As you can see from the annotations, this interceptor is only applicable for instances of ByteBufferProxy. Bases on this assumption, we want to:
Create a subclass of ByteBuffer.
Add a field to store the original (proxied) instance.
Implement ByteBufferProxy and implement the interface methods to access the field for the stored instance.
Override all other methods to call the interceptor that we defined above.
This we can do as follows:
#Test
public void testProxyExample() throws Exception {
// Create proxy type.
Class<? extends ByteBuffer> proxyType = new ByteBuddy()
.subclass(ByteBuffer.class)
.method(any()).intercept(MethodDelegation.to(Interceptor.class))
.defineField("original", ByteBuffer.class, Visibility.PRIVATE)
.implement(ByteBufferProxy.class).intercept(FieldAccessor.ofBeanProperty())
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
// Create fake constructor, works only on HotSpot. (Use Objenesis!)
Constructor<? extends ByteBufferProxy> constructor = ReflectionFactory
.getReflectionFactory()
.newConstructorForSerialization(proxyType,
Object.class.getDeclaredConstructor());
// Create a random instance which we want to proxy.
ByteBuffer byteBuffer = ByteBuffer.allocate(42);
// Create a proxy and set its proxied instance.
ByteBufferProxy proxy = constructor.newInstance();
proxy.setOriginal(byteBuffer);
// Example: demonstrates interception.
((ByteBuffer) proxy).get();
}
final methods are obviously not intercepted. However as the final methods in ByteBuffer only serve as convenience methods (e.g. put(byte[]) calls put(byte[],int,int) with the additional arguments 0 and the array length), you are still able to intercept any method invocation eventually as these "most general" methods are still overridable. You could even trace the original invocation via Thread.currentCallStack().
Byte Buddy normally copies all constructors of its super class if you do not specify another ConstructorStrategy. With no accessible constructor, it simply creates a class without constructors what is perfectly legal in the Java class file format. You cannot define a constructor because, by definition, this constructor would need to call another constructor what is impossible. If you defined a constructor without this property, you would get a VerifierError as long as you do not disable the verifier altogether (what is a terrible solution as it makes Java intrinsically unsafe to run).
Instead, for instantiation, we call a popular trick that is used by many mocking frameworks but which requires an internal call into the JVM. Note that you should probably use a library such as Objenesis instead of directly using the ReflectionFactory because Objenesis is more robust when code is run on a different JVM than HotSpot. Also, rather use this in non-prduction code. Do however not worry about performance. When using a reflective Method that can be cached by Byte Buddy for you (via cacheMethod = true), the just-in-time compiler takes care of the rest and there is basically no performance overhead (see the benchmark on bytebuddy.net for details.) While reflective lookup is expensive, reflective invocation is not.
I just released Byte Buddy version 0.3 and I am currently working on documentation. In Byte Buddy 0.4, I plan to introduce an agent builder which allows you to redefine classes during load-time without knowing a thing about agents or byte code.
I can suggest you 2 solutions.
First, simple, not universal, but probably useful for you.
As far as I can see ByteBuffer has several package-private constructors that allow its subclassing and the following final methods:
public final ByteBuffer put(byte[] src) {
public final boolean hasArray() {
public final byte[] array() {
public final int arrayOffset() {
public final ByteOrder order() {
ByteBuffer extends Buffer that declares some of these methods:
public final boolean hasArray() {
public final Object array() {
public final int arrayOffset() {
As you can see, put() and order() are absent here, return type of array() is a little bit confusing, but still can be used.
So, if you use only these 3 methods you can subclass Buffer and create universal wrapper that wraps any other Buffer including ByteBuffers. If you want you can use javaassist's proxy although IMHO it is not necessarily here.
Second, more universal but more tricky solution. You can create agent that removes final modifiers from speicific class (ByteBuffer in your case) during class loading. Then you can create javassist proxy.
Variation of second solution is following. Copy ByteBuffer soruce code to separate project. Remove final modifiers and compile it. Then push it into bootstrap classpath. This solutions is probably easier than second.
Good luck anyway.
Thanks to #raphw I have managed to make a proxy object construction class which makes a proxy for java.nio.ByteBuffer but that class has final methods which I can not overcome and they are extensively used in the required code, those final methods are Buffer.remaining() and Buffer.hasRemaining(), thus they just can not be proxy mapped.
But I would like to share the classes I have made, just as a report.
public final class CacheReusableCheckerUtils {
private static ByteBuddy buddy = new ByteBuddy();
private static Objenesis objenesis = new ObjenesisStd();
public static <T> T createChecker(T object) {
return createChecker(new CacheReusableCheckerInterceptor<>(object));
}
public static <T> T createChecker(CacheReusableCheckerInterceptor<T> interceptor) {
return objenesis.getInstantiatorOf(createCheckerClass(interceptor)).newInstance();
}
private static <T> Class<? extends T> createCheckerClass(CacheReusableCheckerInterceptor<T> interceptor) {
Class<T> objectClass = interceptor.getObjectClass();
Builder<? extends T> builder = buddy.subclass(objectClass);
builder = builder.implement(CacheReusableChecker.class).intercept(StubMethod.INSTANCE);
builder = builder.method(MethodMatchers.any()).intercept(MethodDelegation.to(interceptor));
return builder.make().load(getClassLoader(objectClass, interceptor), Default.WRAPPER).getLoaded();
}
private static <T> ClassLoader getClassLoader(Class<T> objectClass, CacheReusableCheckerInterceptor<T> interceptor) {
ClassLoader classLoader = objectClass.getClassLoader();
if (classLoader == null) {
return interceptor.getClass().getClassLoader();
} else {
return classLoader;
}
}
}
public class CacheReusableCheckerInterceptor<T> {
private T object;
private boolean allowAccess;
private Throwable denyThrowable;
public CacheReusableCheckerInterceptor(#NotNull T object) {
this.object = object;
}
#SuppressWarnings("unchecked")
public Class<T> getObjectClass() {
return (Class<T>) object.getClass();
}
#RuntimeType
public final Object intercept(#Origin(cacheMethod = true) Method method, #This T proxy, #AllArguments Object[] arguments) {
try {
switch (method.getName()) {
case "allowAccess":
allowAccess();
return null;
case "denyAccess":
denyAccess();
return null;
default:
return invokeMethod(method, arguments);
}
} catch (Exception e) {
throw new CacheReusableCheckerException(method, object, proxy, e);
}
}
private Object invokeMethod(Method method, Object[] arguments) throws IllegalAccessException, InvocationTargetException {
checkMethodAccess(method.getName());
return method.invoke(object, arguments);
}
private void allowAccess() {
if (allowAccess) {
error("double use");
}
allowAccess = true;
onAccessAllowedAfter(object);
}
private void denyAccess() {
if (!allowAccess) {
error("double free");
}
onAccessDeniedBefore(object);
allowAccess = false;
denyThrowable = new Throwable();
}
private void checkMethodAccess(String name) {
if (!allowAccess) {
switch (name) {
case "hash":
case "equals":
case "toString":
case "finalize":
break;
default:
error("use after free");
}
}
}
private void error(String message) {
throw new CacheReusableCheckerException(message, denyThrowable);
}
protected void onAccessAllowedAfter(T object) {
}
protected void onAccessDeniedBefore(T object) {
}
}
public interface CacheReusableChecker {
void allowAccess();
void denyAccess();
}

How to Avoid Constructor calling During Object Creation?

I want to avoid the constructor calling during object creation in java (either default constructor or user defined constructor) . Is it possible to avoid constructor calling during object creation???
Thanks in advance......
Simply extract the intialization logic that you want to avoid into another method called init. You can not avoid calling exactly one constructor.
No matter what pattern or strategy you use, at some point your will need to call a constructor if you want to create an object.
Actually, its possible under some circumstances by using classes from the JVM implementation (which do not belong to the JRE API and are implemenation specific).
One example here http://www.javaspecialists.eu/archive/Issue175.html
It should also be possible using sun.misc.Unsafe.allocateInstance() (Java7)
Also, the constructor is apparently bypassed when using the clone()-method to create a copy of an object (and the class doesn't override clone to implement it different from the Object.clone() method).
All of these possibilities come with strings attached and should be used carefully, if at all.
You can mock the constructors of a class. They will still be called, but not executed. For example, the following JUnit+JMockit test does that:
static class CodeUnderTest
{
private final SomeDependency someDep = new SomeDependency(123, "abc");
int doSomething(String s)
{
someDep.doSomethingElse(s);
return someDep.getValue();
}
}
static final class SomeDependency
{
SomeDependency(int i, String s) { throw new RuntimeException("won't run"); }
int getValue() { return -1; }
}
#Test
public void mockEntireClassIncludingItsConstructors()
{
new NonStrictExpectations() {
#Mocked SomeDependency mockDep;
{ mockDep.getValue(); result = 123; }
};
int result = new CodeUnderTest().doSomething("testing");
assertEquals(123, result);
}

Object without a value

I was asking this question about controlling a thread that was reading from a blocking queue. Although it wasn't the solution I chose to go with, several people suggested that a special "poison pill" or "sentinel" value be added to the queue to shut it down like so:
public class MyThread extends Thread{
private static final Foo STOP = new Foo();
private BlockingQueue<Foo> blockingQueue = new LinkedBlockingQueue<Foo>();
public void run(){
try{
Foo f = blockingQueue.take();
while(f != STOP){
doSomethingWith(f);
f = blockingQueue.take();
}
}
catch(InterruptedException e){
}
}
public void addToQueue(Foo f) throws InterruptedException{
blockingQueue.put(f);
}
public void stop() throws InterruptedException{
blockingQueue.put(STOP);
}
}
While I like this approach, I decided not to use it because I wasn't sure what value to use for the STOP field. In some situations it's obvious - for instance, if you know you're inserting positive integers, negative numbers could be used as control values - but Foo is a fairly complex class. It's immutable and hence has a constructor that takes several arguments. To add a no-argument constructor would mean leaving several fields uninitialised or null, which would cause methods to break if they were used elsewhere - Foo is not just used with MyThread. Similarly, putting dummy values into the main constructor would just pass this problem on as several of the fields and constructor parameters are themselves significant objects.
Am I simply programming over-defensively? Should I worry about adding no-argument constructors to a class, even if there are no setters to make the object usable (just assume other programmers will be sensible enough to not use that constructor)? Is the design of Foo broken if it can't have a no-argument constructor or at least a non-value - would it be better to put if(someField == null){throw new RuntimeException();} checks in all methods?
I don't really see what the advantage of this design is versus a simple boolean variable to indicate the loop should stop.
But if you really want to go with this design, I would suggest making a private no-arg constructor, and making a static STOP Foo. Like this.
public class Foo {
public static final Foo STOP = new Foo();
... fields
private Foo(){}
public Foo(...){
...
}
...
}
public class MyThread extends Thread{
private static final Foo STOP = new Foo();
private BlockingQueue<Foo> blockingQueue = new LinkedBlockingQueue<Foo>();
public void run(){
try{
Foo f = blockingQueue.take();
while(f != STOP){
doSomethingWith(f);
f = blockingQueue.take();
}
}
catch(InterruptedException e){
}
}
public void addToQueue(Foo f) throws InterruptedException{
blockingQueue.put(f);
}
public void stop() throws InterruptedException{
blockingQueue.put(Foo.STOP);
}
}
This has the advantage that you're still not exposing an invalid constructor.
The disadvantage is that the Foo class knows that in some cases it's used as a 'poison pill', which might not be what it's for. Another disadvantage is that The STOP object might be inconsistent. You could make an anonymous subclass from it do disable the methods with UnsupportedOperationException or something.
I think you're right about not using empty constructors. If Foo is such an complex class, it doesn't seem logical to use a complete object for that.
If adding a null is possible. That seems a nice way to go.
Another way could also be to implement an interface. IBlockableQueueObject? This could be implemented by the foo object and by the STOP sign. Only thing is that you have to cast the interface back to the Foo if it is not a STOP.
another option would be to wrap Foo in a generic wrapper such as this:
public class Wrapped<T> {
private final T value;
public Wrapped(T value) {
this.value = value;
}
public T get() { return value; }
}
which you can then use to pass a null value as a poison pill to a BlockingQueue<Wrapped<Foo>>.
You should worry about having no-argument constructors that don't result in usable instances.
The design of Foo sounds fine - I would generally assume that I'm not allowed to pass in null into a constructor unless the documentation specifically allows me to. Especially with an immutable class.

Categories

Resources