Wednesday, October 15, 2014

Ant: adding additional JARs to classpath

I was working in a custom ATG module in which I required to extend a core ATG class. When I ran the build ant command I got compile errors because of "cannot find symbol", in other words, my dear reference class was not being recognized. It was missing! In my Eclipse project I got no errors because I had the right library included in the project's classpath.

I started looking on how to add additional JAR files to the classpath, but after digging a little bit more in the compile target referenced in the build.xml:

<target name="build" depends="echo-build-message,clean,compile,jar-classes,jar-configs,copy-to-install" />

I saw how could I add additional classpath entries using the reference id "classpath.additions". In the included common.xml file we had this:


 
<target name="compile">
     <mkdir dir="${java.output.dir}"/>
        <mkdir dir="${java.src.dir}"/>
        <copy todir="${java.output.dir}">
            <fileset dir="${java.src.dir}">
                <include name="**/*.properties" />
                <include name="**/*.xml" />
            </fileset>
        </copy>
     <if>
      <isreference refid="classpath.additions" />
      <then>
       <path id="fullClasspath">
        <path refid="classpath" />
        <path refid="classpath.additions" />
       </path>
      </then>
      <else>
       <path id="fullClasspath">
        <path refid="classpath" />
       </path>
       </else>
     </if>
        
     <echo message="java.src.dir: ${java.src.dir}, java.output.dir: ${java.output.dir}" />
     <javac srcdir="${java.src.dir}" destdir="${java.output.dir}" classpathref="fullClasspath" debug="on" includeAntRuntime="false" />
</target>

So I just added this in the build.xml:
<path id="classpath.additions"> 
  <fileset dir="${dynamo.home}/../REST/lib"><include name="**/*.jar" /></fileset>  
</path> 
This seems like an elegant generic way for configuring classpaths in a multi module environment like ATG.

Tuesday, October 14, 2014

ATG: Nucleus tips

Get current request URI

import atg.servlet.ServletUtil;
//...
ServletUtil.getCurrentRequest().getRequestURI();

Define a collection of components

Java:
    
protected Component [] componentes;

public void setComponents(Component [] components) {
   this.components = components;
}
    
public Component [] getComponents() {
   return components;
}

Properties:
components=\
 /path/to/some/Component,\
        /path/to/another/Component


Tuesday, July 22, 2014

Spring: Integration testing under Spring Boot application context but mocking services


Use @MockBean annotation

DEPRACATED:

So I wanted to create some integration tests for an API application that uses Spring Boot. The thing is that I needed to load the same application context as the real applicationm, because Spring Boot performs a bunch of configurations for you, and these were not being loaded in a StandAlone mode.

But also I didn't want to use real services which depend upon real data. Depending on databases for your tests creates fragile tests.

After researching on the web I found this way:


This is the typical Spring-Boot entry point class.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@EnableAutoConfiguration
@ComponentScan
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

A base class having the logic to init the application context.

import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = MyApplication.class)
public abstract class BaseIntegrationTest {

    protected MockMvc mockMvc;
    
    @Autowired
    protected WebApplicationContext wac;

    @Before
    public void setup() {
       
        MockitoAnnotations.initMocks(this);
        this.mockMvc = webAppContextSetup(wac).build();
    }
}

An implementation class mocking a required service class.
public class FooIntegrationTest extends BaseIntegrationTest {

    @Configuration
    public static class TestConfiguration {
        @Bean
        @Primary
        public FooService fooService() {
            return mock(FooService.class);
        }
    }


    @Autowired
    FooService mockFooService;
}

Monday, June 2, 2014

HalBuilder: First steps

My team and I are working on trying to find best Java client to consume Hal REST services. I was trying HalBuilder and took me a time to figure a few tweaks to make the simple example describe in the website to work. Perhaps, I was doing something wrong, but just in case someone is also stuck on that, here's the code:

Maven Dependencies:

<dependency>
 <groupId>com.theoryinpractise</groupId>
 <artifactId>halbuilder-api</artifactId>
 <version>2.2.1</version>
</dependency>
<dependency>
 <groupId>com.theoryinpractise</groupId>
 <artifactId>halbuilder-core</artifactId>
 <version>3.1.3</version>
</dependency>
<dependency>
 <groupId>com.theoryinpractise</groupId>
 <artifactId>halbuilder-json</artifactId>
 <version>3.1.3</version>
</dependency>
<dependency>
 <groupId>com.theoryinpractise</groupId>
 <artifactId>halbuilder-standard</artifactId>
 <version>3.0.1</version>
</dependency>

<dependency>
  <groupId>com.ning</groupId>
  <artifactId>async-http-client</artifactId>
  <version>1.8.9</version>
</dependency>

Java code:

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutionException;

import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.Response;
import com.theoryinpractise.halbuilder.api.ReadableRepresentation;
import com.theoryinpractise.halbuilder.api.RepresentationFactory;
import com.theoryinpractise.halbuilder.json.JsonRepresentationFactory;

//http://gotohal.net/
public class TestHalBuilderAPI {
 
 public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
  RepresentationFactory representationFactory = new JsonRepresentationFactory();
  representationFactory.withFlag(RepresentationFactory.PRETTY_PRINT);  
  
  AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
  Response response = asyncHttpClient.prepareGet("http://gotohal.net/restbucks/api").execute().get();
  
  InputStreamReader inputStreamReader = new InputStreamReader(response.getResponseBodyAsStream());
 
  ReadableRepresentation representation = representationFactory.readRepresentation(inputStreamReader);
  String ordersLinkUrl = representation.getLinkByRel("orders").getHref();  
  System.out.println(ordersLinkUrl);  
  asyncHttpClient.close();
 }
}

Friday, May 30, 2014

VirtualBox: Copy/Paste (Guest additions) not working on my Ubuntu VM


I have a Ubuntu VM where I do all my development. Since I installed VirtualBox and created my VM, I never was able to make copy/paste or have better graphics. It all comes with the installation of Guest Additions in the guest machine, but for some reason the installation wasn't working.

I lived with that for some time until I got time to do some more research. First I tried to run the command to enable to copy/paste:

VBoxClient --clipboard -d

But got an error indicating that Guest Additions was not correctly installed or setup (quite not remember well).

So then I run the setup command:

sudo /etc/init.d/vboxadd setup

And got an error:

Removing existing VirtualBox non-DKMS kernel modules ...done.
Building the VirtualBox Guest Additions kernel modules
The gcc utility was not found. If the following module compilation fails then
this could be the reason and you should try installing it.

The headers for the current running kernel were not found. If the following
module compilation fails then this could be the reason.

Building the main Guest Additions module ...fail!
(Look at /var/log/vboxadd-install.log to find out what went wrong)
Doing non-kernel setup of the Guest Additions ...done.

Stupid GCC utility was not installed! :D. Installed it:

sudo apt-get install gcc

Run again the setup and it got installed correctly. Restarted the VM and got finally my copy/paste between host and guest machines. Also my graphics acceleration.