Leaking this in constructor - java

The Controller class is a singleton, which seems to be a special case allowing for safely passing this to Controller.
Netbeans gives
Configure "passing suspicious parameters in the constructor" hint
for controller.addObserver(this); which makes me ask what the better technique would be, although I gather it's not a good approach.
package net.bounceme.dur.usenet.swing;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Logger;
import javax.mail.Folder;
import javax.swing.ListModel;
import net.bounceme.dur.usenet.controller.Controller;
import net.bounceme.dur.usenet.controller.MessageBean;
import net.bounceme.dur.usenet.controller.MessagesDefaultListModel;
public class MessageSelect extends javax.swing.JPanel implements Observer {
private static final Logger LOG = Logger.getLogger(MessageSelect.class.getName());
private Controller controller = Controller.getInstance();
private ListModel messages = new MessagesDefaultListModel();
private MessageBean messageBean = new MessageBean();
#SuppressWarnings("unchecked")
public MessageSelect() {
controller.addObserver(this);
initComponents();
messagesJList.setPrototypeCellValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}

You are passing this to an external class (Controller) when the object hasn't been fully constructed. Controller could then reference your object while its construction hasn't finished.
Most people work around this by using a factory method which creates the object first, then passes this externally.
// private to force clients to use the static factory method
private MessageSelect() {
initComponents();
messagesJList.setPrototypeCellValue("xxx");
}
public static MessageSelect createInstance() {
MessageSelect instance = new MessageSelect();
instance.controller.addObserver(instance);
return instance;
}
Take a look at this excellent Brian Goetz article on safe object construction.

Using this as parameter can be dangerous in the contructor because the object is not fully initialized
As from http://wiki.netbeans.org/Java_Hints
I guess the point is, the super class may try and access apart of the class which has not yet been intialised (or you later change during your own construction)

Related

PowerMock won't mock static method to throw an Exception in a Spring-Boot application

I realize there are many many very similar questions. I've been through all of them and I still cannot make my code work.
I have a service defined in my Spring-Boot application, just like this:
#Service
public class FileStorageService {
private final Path fileStorageLocation;
#Autowired
public FileStorageService(final FileStorageProperties fileStorageProperties) {
//FileStorageProperties is a very simple class that right now just holds one String value
this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
.toAbsolutePath()
.normalize();
try {
Files.createDirectories(fileStorageLocation);
} catch (IOException e) {
// FileStorageException is my custom, runtime exception
throw new FileStorageException("Failed to create directory for stored files", e);
}
}
}
And I want to test scenario, when directory creation fails and thus I need to mock method Files.createDirectories(). My test class looks like this:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.io.IOException;
import java.nio.file.Files;
#RunWith(PowerMockRunner.class)
#PrepareForTest({Files.class})
public class FileStorageServiceTest {
private static final String UPLOAD_DIR = "uploadDir";
#Test(expected = FileStorageException.class)
public void some_test() throws IOException {
PowerMockito.mockStatic(Files.class);
PowerMockito.when(Files.createDirectories(Mockito.any())).thenThrow(new IOException());
new FileStorageService(createFileStorageProperties());
}
private FileStorageProperties createFileStorageProperties() {
final FileStorageProperties fileStorageProperties = new FileStorageProperties();
fileStorageProperties.setUploadDir(UPLOAD_DIR);
return fileStorageProperties;
}
}
I believe I followed every step from tutorials and questions I've read.
I use:
#RunWith(PowerMockRunner.class),
#PrepareForTest({Files.class}),
PowerMockito.mockStatic(Files.class),
and PowerMockito.when(Files.createDirectories(Mockito.any())).thenThrow(new IOException());.
Still, no exception is thrown during test and it fails. WIll be super thankful for the help, cause I feel I miss something really simple and just cannot see it.
From: https://github.com/powermock/powermock/wiki/Mock-System
Normally you would prepare the class that contains the static methods (let's call it X) you like to mock but because it's impossible for PowerMock to prepare a system class for testing so another approach has to be taken. So instead of preparing X you prepare the class that calls the static methods in X!
Basically, we mock the class's use of the System class, rather than unmockable System class itself.
#PrepareForTest({Files.class})
An alternative, non-Powermock way to do this without mocking any system class would be to create a helper method, #Spy the original class, and mock that helper method specifically to throw the exception.
when(spy.doSomethingWithSystemClasses()).thenThrow(new Exception("Foo");

Method intercepted twice even though it was called once

In the following code snippet I'm calling the method doStuff once on an instance of Subclass. However it is intercepted twice.
Note that doStuff was defined in the parent class SuperClass. If doStuff was defined in SubClass the interception logic would work as expected: only one interception.
Am I using Byte Buddy incorrectly?
package com.test;
import static net.bytebuddy.matcher.ElementMatchers.any;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import java.util.concurrent.Callable;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType.Builder;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import org.junit.Test;
public class ReproBugTest {
#Test
public void reproBug() {
new AgentBuilder.Default().type(nameStartsWith("com.test"))
.transform(new AgentBuilder.Transformer() {
#Override
public Builder<?> transform(
Builder<?> builder,
TypeDescription td) {
return builder.method(any())
.intercept(
MethodDelegation.to(MethodInterceptor.class));
}
})
.installOn(
ByteBuddyAgent.installOnOpenJDK());
SubClass subClass = new SubClass();
subClass.doStuff();
}
}
class SuperClass {
public void doStuff() {
System.out.println("Doing stuff...");
}
}
class SubClass extends SuperClass {
}
class MethodInterceptor {
#RuntimeType
public static Object intercept(#SuperCall Callable<?> zuper)
throws Exception {
// Intercepted twice, bug?
System.out.println("Intercepted");
Object returnValue = zuper.call();
return returnValue;
}
}
You are intercepting the method call for every type, i.e. for both Subclass and SuperClass. You need to further specify your interceptor for what methods to intercept. In you case, you only want to intercept methods if they are declared by a given type.
This is easy to implement. Instead of builder.method(any()), you should intercept builder.method(isDeclaredBy(td)). This way, a method is only intercepted if it is declared by the intercepted type.
Finally, I can see from, your source code that you are using an older version of Byte Buddy. Version 0.7-rc6 runs stable, has additional features and fixes several bugs. (However, some APIs still need to be changed.)

How to test java code that uses Basho's riak-java-client?

I'm creating a small java service that returns a list of restaurants depending on the selected place.
Data is retrieved from Riak using com.basho.riak:riak-client:2.0.0 and the read operation is wrapped in a TenacityCommand.
Important classes are described below and I would be happy if you could assist me in creating a solid and simple unit test.
Commands are created using a factory:
package service.command.factory;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.Namespace;
import domain.Place;
import service.command.FetchRestaurantsCommand;
public class FetchRestaurantsCommandFactory {
private final RiakClient riakClient;
private final Namespace namespace;
public FetchRestaurantsCommandFactory(final RiakClient riakClient, final Namespace namespace) {
this.riakClient = riakClient;
this.namespace = namespace;
}
public FetchRestaurantsCommand create(final Place place) {
Location location = new Location(namespace, place.getName());
FetchValue riakCommand = new FetchValue.Builder(location).build();
return new FetchRestaurantsCommand(riakClient, riakCommand);
}
}
And the command looks like this:
package service.command;
import java.util.Optional;
import service.command.keys.WhereToEatDependencyKeys;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.api.commands.kv.FetchValue.Response;
import com.yammer.tenacity.core.TenacityCommand;
import domain.Restaurant;
import domain.RestaurantList;
public class FetchRestaurantsCommand extends TenacityCommand<Optional<RestaurantList>>{
private final RiakClient riakClient;
private final FetchValue fetchValue;
public FetchRestaurantsCommand(RiakClient riakClient, FetchValue fetchValue) {
super(WhereToEatDependencyKeys.RIAK_GET_RESTAURANTS);
this.fetchValue = fetchValue;
this.riakClient = riakClient;
}
#Override
protected Optional<RestaurantList> run() throws Exception {
Response response = riakClient.execute(fetchValue);
return Optional.ofNullable(response.getValue(RestaurantList.class));
}
#Override
protected Optional<RestaurantList> getFallback() {
return Optional.of(RestaurantList.createFallback(new Restaurant("My failure suggestion")));
}
}
The above classes are used like:
Place place = // Created from url parameter
RiakClient riakClient = // created on start using the app's conf
Namespace namespace = // created on start using the app's conf
FetchRestaurantsCommandFactory factory = new FetchRestaurantsCommandFactory(riakClient, namespace);
FetchRestaurantsCommand command = factory.create(place);
return command.execute();
Apart from the features provided by TenacityCommand, how should I assert that my system fetches data as expeceted?
My initial idea was to mock a RiakClient to return a predefined FetchValue.Response and then make assertions on the resulting RestaurantList.
Unfortunately its not possible to instantiate or Mockito.mock a FetchValue.Response due to its design.
The accepted answer in How to mock riak java client? describes why Mockito won't work.
As far a I understood you want to write unit test. So you want to test that assuming some Response whether Optional<RestaurantList> instance is constructed correctly or not.
What I can think of is to wrap riakClient.execute(fetchValue); in a protected (or package private) helper function like:
Response fetch() {
return riakClient.execute(fetchValue);
}
Then in your test you can inherit from FetchRestaurantsCommand and override fetch function by returning any Response
Now, you can write any test to see whether the conversion of given Response to Optional<RestaurantList> behaves as expected or not.
If you need entire code and my explanation is not clear enough let me know to provide it.
I ended up using PowerMock as suggested by #gontard. See my unit test on GitHub: FetchRestaurantsCommandTest.java
I considered to create a fake/mock RiakClient in the com.basho.riak.client package. Such class could hopefully instantiate the Response object in the same way as the real client does. It would probably work for fetchValue but it would grow too big when involving more advanced Riak concepts s.a. siblings.

Does setDefaultHighRepJobPolicyUnappliedJobPercentage(100) really work?

According to https://cloud.google.com/appengine/docs/java/tools/localunittesting#Writing_HRD_Datastore_Tests, "If your app uses the High Replication Datastore (HRD), you may want to write tests that verify your application's behavior in the face of eventual consistency. LocalDatastoreServiceTestConfig exposes options that make this easy." You're supposed to set setDefaultHighRepJobPolicyUnappliedJobPercentage(100) and then, "By setting the unapplied job percentage to 100, we are instructing the local datastore to operate with the maximum amount of eventual consistency. Maximum eventual consistency means writes will commit but always fail to apply, so global (non-ancestor) queries will consistently fail to see changes."
However, I don't think setDefaultHighRepJobPolicyUnappliedJobPercentage(100) works.
If it did, then my test case below, testEventualConsistency() should pass but it it fails on the second assertion. On the first assertion, I read back an object I've saved using an Objectify ancestor() query. It works as documented because the object is retrieved. However, the second assertion fails. In that assertion I've also read back the object I've saved but I haven't used an Objectify ancestor() query so it shouldn't retrieve anything because I've specified that no jobs should complete (i.e. the setDefaultHighRepJobPolicyUnappliedJobPercentage(100) setting).
EventualConsistencyTest Test Case
import static com.googlecode.objectify.ObjectifyService.begin;
import static com.googlecode.objectify.ObjectifyService.ofy;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.util.List;
import org.junit.Test;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Ref;
import com.googlecode.objectify.util.Closeable;
import com.netbase.followerdownloader.model.DownloadTask;
import com.netbase.followerdownloader.model.User;
public class EventualConsistencyTest {
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()
.setDefaultHighRepJobPolicyUnappliedJobPercentage(100));
#Test
public void testEventualConsistency() {
helper.setUp();
ObjectifyRegistrar.registerDataModel();
User user = new User();
user.id = 1L;
Closeable closeable1 = begin();
ofy().save().entity(user);
closeable1.close();
Closeable closeable2 = begin();
DownloadTask downloadTask = new DownloadTask();
downloadTask.owner = Ref.create(user);
ofy().save().entity(downloadTask);
closeable2.close();
Closeable closeable3 = ObjectifyService.begin();
List<DownloadTask> downloadTasks1 = ofy().load().type(DownloadTask.class).ancestor(user).list();
assertThat(downloadTasks1.size(), equalTo(1));
closeable3.close();
Closeable closeable4 = ObjectifyService.begin();
List<DownloadTask> downloadTasks2 = ofy().load().type(DownloadTask.class).list();
assertThat(downloadTasks2.size(), equalTo(0)); // THIS SHOULD PASS IF setDefaultHighRepJobPolicyUnappliedJobPercentage(100) WORKED
closeable4.close();
helper.tearDown();
}
}
User Definition
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
#Entity
public class User {
#Id public Long id;
public User () {
}
}
DownloadTask Definition
import com.googlecode.objectify.Ref;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Parent;
#Entity
public class DownloadTask {
#Id public Long id;
#Parent public Ref<User> owner;
public DownloadTask() {
}
}
Environment:
appengine-api-1.0-sdk-1.9.17.jar
appengine-testing-1.9.17.jar
appengine-api-stubs-1.9.17.jar
junit-4.11.jar
objectify-5.1.3.jar
In case I missed anything else important, here is a more exhaustive list:
My questions are:
Is setDefaultHighRepJobPolicyUnappliedJobPercentage(100) broken?
Does setDefaultHighRepJobPolicyUnappliedJobPercentage(100) not really work as documented? Does it in fact apply the job even though the documentation says it's not supposed to?
Is the value passed to setDefaultHighRepJobPolicyUnappliedJobPercentage() really supposed to be 100 and not maybe let's say, 1.0f?
Do Objectify ancestor queries not really work as documented?
The problem is explained by an observation at https://cloud.google.com/appengine/docs/java/tools/localunittesting#Java_Writing_High_Replication_Datastore_tests :
"In the local environment, performing a get() of an Entity that belongs to an entity group with an unapplied write will always make the results of the unapplied write visible to subsequent global queries."
In this contect, this means the ancestor-query:
List<DownloadTask> downloadTasks1 = ofy().load().type(DownloadTask.class).ancestor(user).list();
which internally "performs a get() of an Entity that belongs to an entity group with an unapplied write" influences the behavior of the immediately-following global query:
List<DownloadTask> downloadTasks2 = ofy().load().type(DownloadTask.class).list();
To avoid your tests influencing each other, and in particular, interfering w/each other in this way, it's best to use a separate method per operation under test (each with all the needed setup and teardown parts), rather than having successive operations-under-test within a single test method.

Java newbie problem: package with private access

Pack.java imports pack.TestPack; but it cannot access it. I cannot understand why it cannot access the class despite the import.
Error
Pack.java:7: TestPack() is not public in pack.TestPack; cannot be accessed from outside package
System.out.println(new TestPack().getHello());
^
1 error
Pack.java
import pack.TestPack;
import java.io.*;
public class Pack
{
public static void main(String[] args){
System.out.println(new TestPack().getHello());
}
}
TestPack.java
package pack;
import java.util.*;
import java.io.*;
public class TestPack
{
private String hello="if you see me, you ar inside class TestPack";
public String getHello(){return hello;}
TestPack(){}
}
You should make TestPack's constructor public.
public class TestPack
{
private String hello="if you see me, you ar inside class TestPack";
public String getHello(){return hello;}
public TestPack(){}
}
The thing is, even though TestPack visibility is public, its parameterless constructor visibility is package (which is the visibility when you don't specify one explicitly).
package visibility means that classes in the same package will be able to see it. Since TestPack and Pack are not in the same package, Pack can't call TestPack's constructor.
In the way you are using getHello function, you may start thinking using static methods
public class TestPack
{
private static String hello="if you see me, you ar inside class TestPack";
public static String getHello(){return hello;}
private TestPack(){}
}
then you just will do:
public class Pack
{
public static void main(String[] args){
System.out.println(TestPack.getHello());
}
}
I suggest that you don't make the class public but make the constructor public and have folks use a public interface that your class implements. It is a good idea to start the API to your package to be public interfaces (and perhaps some public abstract classes) and hide your implementation classes by not marking them as public so that you can change these over time. You can then provide a public factory methods in your package which instantiate your package private class and return them as the interface types. Here is an interface which is public:
package stackoverflow;
public interface Widget {
public void doWidgetWork(String work);
}
Here is the implementation which is "package private". The compiler wont let code outside of the same package import nor use this class at all:
package stackoverflow;
/*package*/ class WidgetHidden implements Widget {
public WidgetHidden(String configOptionA, String configOptionB){
// ...
}
public WidgetHidden(){
// ...
}
public void doWidgetWork(String work)[
// ...
}
}
notice there that the second occurrence of the word /package/ is a comment (it is not legal in java to use that word there) but many programmers use such a comment in that position to show people that it was not an accident that the class is not public; it signifies that the developer really intended that the class is deliberately "package private". To let people instantiate the class from outside of your package you provide a static factory class (else an instance factory class):
package stackoverflow;
public class WidgetFactory {
public static Widget newInstance( String configOptionA, String configOptionB) {
return new Widget( String configOptionA, String configOptionB);
}
}
The whole point of the factory class is that it hides your internal classes (the ones you hide as package private). Over time you can change your factory classes to return new classes or rename or delete the WidgetHidden class.
Many frameworks indicate which classes other developers should not use by putting them into a package with the name "internal" in it. The public interfaces would be in the main package (e.g. "com.stackoverflow.widget") and the hidden classes into your internal package which only exposes public factory classes (e.g. "com.stackoverflow.widget.internal").
A variation on the theme is to not use a static method on the factory class; make it a regular method. The alternatives are called "static factories" or "instance factories" depending on whether the method is static or not. Not making the method static seems like more work for people using your package as they first have to instantiate your factory object before using it to create Widget. Where is helpful is when people might want to set some defaults for all widgets on the constructor of the factory then use the none static newInstance methods to specify anything beyond the defaults:
public class WidgetInstanceFactory {
private String defaultOptionA = null;
public WidgetInstanceFactory( String defaultOptionA ) {
this.defaultOptionA = defaultOptionA;
}
public Widget newInstance( String optionB ) {
return new WidgetHidden( this.defaultOptionA, optionB );
}
}
It is possible to get around package private protection using reflection to find and invoke the constructor. A really nice feature of the Spring framework it that it will instantiate classes that are not public even when there is no factory class (although it is more polite to provide factory classes which Spring is happy to use also). The following code will work:
package stackoverflow.other;
class TestInstantiate {
private Widget myWidget = null;
public TestInstantiate(){
this.myWidget = instantiatePackagePrivateClass("stackoverflow.WidgetHidden");
}
private Widget instantiatePackagePrivateClass(String className)
throws ClassNotFoundException, NoSuchMethodException,
InstantiationException, IllegalAccessException,
InvocationTargetException {
#SuppressWarnings("unchecked")
Class<FileUploadSequence> clazz = (Class<Widget>) Class.forName(className);
Constructor<Widget> constructor = clazz.getConstructor(new Class[]{});
constructor.setAccessible(true);
Widget widget = (Widget) constructor.newInstance((Object[])null);
return widget;
}
}
In that example I used the no arguments constructor but clearly you can find and invoke the two string constructor using the same approach. Clearly such code gets around the intention of the programmer who wrote WidgetHidden; they wanted to hide it as they are likely to change it. Anyone who uses such a back door to manipulate the package private object should be aware that the class WidgetHidden is not part of the public API of the framework they are using so it likely to be deleted or changed without prior notice by the developer who wrote the package you are using. Renaming it to be WidgetInternal and putting it into an "internal" package make it every more the case you are telling people "do not uses". The JVM has optional security setting which prevent people from doing such tricks; but the person running the JVM has to configure it externally to dis-allow such tricks which is only useful when you want to run someone else code you don't trust and prevent it from pulling such tricks.
The book Effective Java by Josha Block 2nd Edition has a lot of discussion and examples and details of the pitfalls when trying to write a good API. It has a lot of detail to explain why you should always look to hide as many classes as you can with lots of other good "tricks of the trade".

Categories

Resources