2017. augusztus 29., kedd

Setting up a convenient Eclipse working environment


Here I would like to list all task, I need to do when setting up my Eclipse environment


Plug-ins to be installed
  • More Unit - the best tool for generating and maintaining unit test created for Eclipse 
  • JRebel - in case of server side programming, you can save a huge amount of time with it. It is commerctal, but a community version also can be used. This version is full featured, only sends messages sometimes to your Facebook wall. 
  • Lombok - enhances the Java language with annotation based elements, bringing it closer to the features of Scala, and other modern, Java-like languages. I suse it to avoid coding boilerplate code. You can generate getter/setter, toString, etc. 
  • Findbugs - static code analysis tool
  • PMD - static code analysis tool
  • Ucdetector - detects unnecesary code in your application. Also can be used to lower the accessibility of your classes or elements.
  • JIRA connector 
  • Eclipse class decompiler
  • InstaSearch - makes searching way faster with Lucence based search engine. 
  • QuickRex - evaluating Regular expressions directly in Eclipse
Settings to be made
  • add source to java packages
  • set toString generation
  • set formatter
  • set comparison to ignore white spaces by default
  • set multi monitor environment. Do not forget to stop Eclipse always with File/Exit, instead of closing any of the windows.
  • import your collection of short-keys 

Export your environment

Using prototype in Spring singleton service



I wanted to use a Spring bean, with private fields in order to build an object. Previously the builder class was really as an example of the builder pattern implemented. It was able to build the required object based on the parameters, defined for the builder.

Later on, after the requirement changed, the builder had to use other services in order to get detailed information for the build process. In this case you have the following possibilities:
  • define all services as parameter of the build process, and use them when needed.
    I did not choose this option, as it would not have resulted a clear interface for the builder. The dependent services are mandatory for the build process, but the builder can not force to define them in its interface. So the client has to set up the builder correctly before using it. It would have resulted such a restriction, what I did not want to build into my system.
  • Implement the builder as a Spring singleton bean. In this case the singleton must not have a state, so it is not possible to define the build parameters as field of the bean. It would make the implementation less readable, while the parameters must have been passed to the private methods several times.
So I chose to concert my builder class into a Spring prototype bean. The necessary parameters must be set by the client, but the necessary services are injected with CDI by the container.

The result looked like this:


@Service(value = "logicBuilderService")
@Scope("prototype")
public final class LogicBuilderService {

 @Autowired
 private DeviceDAO deviceDao;

 @Autowired
 private SupportedDeviceDao supportedDeviceDao;

 // contains eagerly initialized device and channel collection
 @Setter
 private Gateway gateway;

 @Setter
 private LogicRequest request;

 public Logic build() {
  Logic logic = createNewLogic();
  addTrigger(logic);
  addActions(logic);

  return logic;
 }
....


At the client side, you need to use an Objectfactory, in order to get a new instance of the service. Whenever you need a new, clean instance of the builder, you get it from the Spring framework, without the properties set.


 @Autowired
 private ObjectFactory<LogicBuilderService> prototypeFactory;

 private LogicBuilderService getNewLogicBuilderServiceInstance(Gateway gateway, LogicRequest request) {
  LogicBuilderService logicBuilder = prototypeFactory.getObject();
  logicBuilder.setGateway(gateway);
  logicBuilder.setRequest(request);

  return logicBuilder;
 }

In order to use the LogicBuilderService in a unit test, you need to mock the ObjectFactory, so it returns a new instance of the builder for all calls.


@Mock
 private ObjectFactory<LogicBuilderService> prototypeFactory;

 @InjectMocks
 private LogicRestService logicRestService;

 @Before
 public void setup() {
  when(prototypeFactory.getObject()).thenReturn(new LogicBuilderService());
 }