Java

Active MQ – java.io.IOException: tmpFile.renameTo(classFile) failed

Posted on

I downloaded the latest version of Apache ActiveMQ. Post download followed the simple steps for installation and then followed the starting ActiveMQ. It started and I tried accessing the admin console @ http://localhost:8161/admin/.

It opened by showed an error message:

Error!

Exception occurred while processing this request, check the log for more information!

What do you want to do next?

ActiveMQ Console

And my command prompt had this stacktrace:

jvm 1    | java.io.IOException: tmpFile.renameTo(classFile) failed
jvm 1    |      at org.apache.jasper.compiler.SmapUtil$SDEInstaller.install(SmapUtil.java:235)
jvm 1    |      at org.apache.jasper.compiler.SmapUtil.installSmap(SmapUtil.java:158)
jvm 1    |      at org.apache.jasper.compiler.Compiler.generateClass(Compiler.java:390)
jvm 1    |      at org.apache.jasper.compiler.Compiler.compile(Compiler.java:437)
jvm 1    |      at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:608)
jvm 1    |      at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:360)
jvm 1    |      at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:486)
jvm 1    |      at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:380)
jvm 1    |      at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:652)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:445)
jvm 1    |      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
jvm 1    |      at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:574)
jvm 1    |      at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)
jvm 1    |      at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1044)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:372)
jvm 1    |      at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:189)
jvm 1    |      at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:978)
jvm 1    |      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
jvm 1    |      at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:293)
jvm 1    |      at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:120)
jvm 1    |      at org.eclipse.jetty.servlet.DefaultServlet.doGet(DefaultServlet.java:566)
jvm 1    |      at javax.servlet.http.HttpServlet.service(HttpServlet.java:693)
jvm 1    |      at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:652)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1320)
jvm 1    |      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
jvm 1    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1291)
jvm 1    |      at org.apache.activemq.web.filter.ApplicationContextFilter.doFilter(ApplicationContextFilter.java:102)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1291)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:443)
jvm 1    |      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
jvm 1    |      at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:521)
jvm 1    |      at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)
jvm 1    |      at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1044)
jvm 1    |      at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:372)
jvm 1    |      at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:189)
jvm 1    |      at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:978)
jvm 1    |      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
jvm 1    |      at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
jvm 1    |      at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:521)
jvm 1    |      at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
jvm 1    |      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
jvm 1    |      at org.eclipse.jetty.server.Server.handle(Server.java:367)
jvm 1    |      at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:486)
jvm 1    |      at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:926)
jvm 1    |      at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:988)
jvm 1    |      at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:640)
jvm 1    |      at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
jvm 1    |      at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
jvm 1    |      at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)
jvm 1    |      at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
jvm 1    |      at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
jvm 1    |      at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
jvm 1    |      at java.lang.Thread.run(Thread.java:744)

Fix is very simple, if you are on Windows 7 then while launching ActiveMQ:

  1. Stop ActiveMQ if it is running
  2. Start command prompt as Administrator (Start Menu -> Type cmd -> Right click on cmd -> choose Run as Administrator
  3. Or go to the /bin/(win32 or win64 based on your system and right click on activemq.bat and choose Run as Administrator

Now again access the admin console. BINGO problem solved!!!

Happy coding….

JAX-WS Custom Exception with FaultBean in TomEE and WebSphere Application Server

Posted on

In our last post we were able to deploy a simple JAX-WS service on both TomEE and WebSphere Application Server.

JAX-WS Specification suggests that three thing should be followed for us to implement Custom Exception as SOAP Fault.

WrapperException(String message, FaultBean faultInfo) A constructor where WrapperException
is replaced with the name of the generated wrapper exception and FaultBean is replaced by the
name of the generated fault bean.
WrapperException(String message, FaultBean faultInfo, Throwable cause) A constructor
whereWrapperException is replaced with the name of the generated wrapper exception and FaultBean
is replaced by the name of the generated fault bean. The last argument, cause, may be used to convey
protocol specific fault information, see section 6.4.1.
FaultBean getFaultInfo() Getter to obtain the fault information, where FaultBean is replaced by the
name of the generated fault bean.

But as it turns out to be this is not very restrictive and not honored across Application Server. Let’s take the IMyService.java and MyServiceImpl.java from previous post and then we will modify the exception part.

Our updated Exception class will have a faultBean which will accept errorCode and errorMessage.

First the exception class MyException.java, in below code we have introduced a new class MyExceptionBean which holds our errorCode and errorMessage. We initialize this class with values which are passed to the constructor of our MyException.

package com.test.mumz.soap.soapexp;

import javax.xml.ws.WebFault;

/**
 * The Class MyException.
 * 
 * @author prabhat.jha
 */
@WebFault(name = "MyException")
public class MyException extends Exception {

	/** The Constant serialVersionUID. */
	private static final long	serialVersionUID	= -861826770198517502L;

	/** The my exception bean. */
	private MyExceptionBean		faultBean			= null;

	/**
	 * Instantiates a new my exception.
	 * 
	 * @param errorCode
	 *            the error code
	 * @param message
	 *            the message
	 */
	public MyException(String errorCode, String message) {
		prepareFaultBean(errorCode, message);
	}

	/**
	 * Instantiates a new my exception.
	 * 
	 * @param errorCode
	 *            the error code
	 * @param message
	 *            the message
	 * @param cause
	 *            the cause
	 */
	public MyException(String errorCode, String message, Throwable cause) {
		super(message, cause);
		prepareFaultBean(errorCode, message);
	}


	/**
	 * Adds the exception details.
	 *
	 * @param errorCode            the error code
	 * @param errorMessage            the error message
	 * @return the my exception
	 */
	private void prepareFaultBean(String errorCode, String errorMessage) {
		this.faultBean = new MyExceptionBean(errorCode, errorMessage);
	}
	
	/**
	 * Gets the fault bean.
	 *
	 * @return the fault bean
	 */
	public MyExceptionBean getFaultBean() {
		return faultBean;
	}
}

Next is our MyExceptionBean.java which is POJO and holds errorCode and errorMessage.

package com.test.mumz.soap.soapexp;

/**
 * The Class MyExceptionBean.
 * 
 * @author prabhat.jha
 */
public class MyExceptionBean {

	/** The error code. */
	private String	errorCode		= null;

	/** The error message. */
	private String	errorMessage	= null;

	/**
	 * Instantiates a new my exception bean.
	 * 
	 * @param errorCode
	 *            the error code
	 * @param errorMessage
	 *            the error message
	 */
	public MyExceptionBean(String errorCode, String errorMessage) {
		this.errorCode = errorCode;
		this.errorMessage = errorMessage;
	}

	/**
	 * @return the errorCode
	 */
	public String getErrorCode() {
		return errorCode;
	}

	/**
	 * @param errorCode
	 *            the errorCode to set
	 */
	public void setErrorCode(String errorCode) {
		this.errorCode = errorCode;
	}

	/**
	 * @return the errorMessage
	 */
	public String getErrorMessage() {
		return errorMessage;
	}

	/**
	 * @param errorMessage
	 *            the errorMessage to set
	 */
	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}
}

Next deploy it in TomEE and use SoapUI to test. Sample Input and Output are given below
Input

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mpr="http://mprabhat.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <mpr:sayHello>
         <arg0></arg0>
      </mpr:sayHello>
   </soapenv:Body>
</soapenv:Envelope>

Output

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Server</faultcode>
         <faultstring>Fault occurred while processing.</faultstring>
         <detail>
            <ns1:MyException xmlns:ns1="http://mprabhat.com/">
               <faultBean xsi:type="ns2:myExceptionBean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://mprabhat.com/">
                  <errorCode>Code</errorCode>
                  <errorMessage>Message</errorMessage>
               </faultBean>
            </ns1:MyException>
         </detail>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

Brilliant everything works perfectly???? Wait let’s deploy it in WebSphere now. Please follow the same steps as described in previous post and then run with above input.

This is not to show demerit or loop hole in the spec or by the implementation provider, this is just another way of doing it but I would say follow the spec the chances of this not working is higher then the spec.

  • If you provide both getFaultInfo and getFaultBean in above MyException, you will find that control will always come to getFaultInfo. So the spec is honored 🙂
  • If in MyExceptionBean you remove getter and setters you will not see any Soap Fault but if you make your fields public it will again work ;), I know it’s simple Java bean specification.

JAX-WS Exception Handling with TomEE and WebSphere Application Server 8.5

Posted on Updated on

Let’s write a simple JAX-WS example which will throw an Exception. We will then deploy it in TomEE and then to WebSphere 8.5 and see the difference.

  1. Download TomEE ( I have downloaded the plus version which at the time of writing was 1.7.1)
  2. Download and install WebSphere Application Server (Developer version is free)
  3. Download and install SoapUI

Once servers are downloaded and installed, open your eclipse and create a new “Dynamic Web Project”. Our project will have three Source Files namely:

  1. EndPoint interface IMyService
  2. Implementation class MyServiceImpl
  3. Exception class MyException

I will not get into what these annotations are, rather you can visit any of the many available tutorials for a quick/detailed walk through.

First our interface IMyService.java

package com.test.mumz.soap.soapexp;

import javax.jws.WebService;

/**
 * The Interface IMyService.
 *
 * @author prabhat.jha
 */
@WebService(targetNamespace = "http://mprabhat.com/")
public interface IMyService {

	/**
	 * Say hello.
	 *
	 * @param userName the user name
	 * @return the string
	 * @throws MyException the my exception if <code>username</code> is null or blank
	 */
	public String sayHello(String userName) throws MyException;
}

Our interface is simple enough just has one method sayHello which accepts a String and if the parameter is null or empty will throw an instance of MyException

Next our Web Service implementation class.

package com.test.mumz.soap.soapexp;

import java.util.Date;

import javax.ejb.Stateless;
import javax.jws.WebService;

/**
 * The Class MyServiceImpl.
 * @author prabhat.jha
 */
@Stateless
@WebService(portName = "myport", serviceName = "MyService", targetNamespace = "http://mprabhat.com/", endpointInterface = "com.test.mumz.soap.soapexp.IMyService")
public class MyServiceImpl implements IMyService {

	/**
	 * Instantiates a new my service impl.
	 */
	public MyServiceImpl() {
	}

	/* (non-Javadoc)
	 * @see com.test.mumz.soap.soapexp.IMyService#sayHello(java.lang.String)
	 */
	@Override
	public String sayHello(String userName) throws MyException {
		if (userName == null || userName.trim().length() == 0 || "".equals(userName)) {
			throw new MyException("Username cannot be null");
		}
		return "Hello : " + userName + " ,server time is : " + new Date();
	}
}

This again is self-explanatory, just returns hello message with server time. If parameter is null with throw MyException.

Finally our exception class MyException.java

package com.test.mumz.soap.soapexp;

import javax.xml.ws.WebFault;

/**
 * The Class MyException.
 * 
 * @author prabhat.jha
 */
@WebFault(name="MyException")
public class MyException extends Exception {

	/** The Constant serialVersionUID. */
	private static final long	serialVersionUID	= -861826770198517502L;
	
	/**
	 * Instantiates a new my exception.
	 * 
	 * @param message
	 *            the message
	 */
	public MyException(String message) {
		super(message);
	}

	/**
	 * Instantiates a new my exception.
	 * 
	 * @param cause
	 *            the cause
	 */
	public MyException(Throwable cause) {
		super(cause);
	}

	/**
	 * Instantiates a new my exception.
	 * 
	 * @param message
	 *            the message
	 * @param cause
	 *            the cause
	 */
	public MyException(String message, Throwable cause) {
		super(message, cause);
	}

	/**
	 * Instantiates a new my exception.
	 * 
	 * @param message
	 *            the message
	 * @param cause
	 *            the cause
	 * @param enableSuppression
	 *            the enable suppression
	 * @param writableStackTrace
	 *            the writable stack trace
	 */
	public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}
}

Now export your project as war and deploy it in TomEE first (Simple way: Right Click on project -> Export -> War and then place this war inside /webapps). Or you can even deploy it through Eclipse. After deployment start TomEE and on console you should see the wsdl location. It should look like this:

INFO: Webservice(wsdl=http://localhost:8080/SoapException/webservices/MyServiceImpl, qname={http://mprabhat.com/}MyService) --> Ejb(id=MyServiceImpl)

To test:

  1. Launch SoapUI
  2. File -> New Soap Project
  3. Give Project Name like MyServiceSoapUIPrj and wsdl. Just append “?wsdl” to what is printed on the console. It should be like:
    http://localhost:8080/SoapException/webservices/MyServiceImpl?wsdl

  4. Now send a request with some parameter:
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mpr="http://mprabhat.com/">
       <soapenv:Header/>
       <soapenv:Body>
          <mpr:sayHello>
             <arg0>User</arg0>
          </mpr:sayHello>
       </soapenv:Body>
    </soapenv:Envelope>
    

    You should get the response back like below:

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
       <soap:Body>
          <ns2:sayHelloResponse xmlns:ns2="http://mprabhat.com/">
             <return>Hello : User ,server time is : Sun Nov 02 23:40:06 IST 2014</return>
          </ns2:sayHelloResponse>
       </soap:Body>
    </soap:Envelope>
    

    Input with null parameter:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mpr="http://mprabhat.com/">
       <soapenv:Header/>
       <soapenv:Body>
          <mpr:sayHello>
             <arg0></arg0>
          </mpr:sayHello>
       </soapenv:Body>
    </soapenv:Envelope>
    

    Here is your SOAP fault

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
       <soapenv:Body>
          <soapenv:Fault>
             <faultcode>soapenv:Server</faultcode>
             <faultstring>Username cannot be null</faultstring>
             <detail>
                <a:MyException xmlns:a="http://mprabhat.com/">
                   <message>Username cannot be null</message>
                </a:MyException>
             </detail>
          </soapenv:Fault>
       </soapenv:Body>
    </soapenv:Envelope>
    

    So all in all, everything works expected and we have our JAX-WS working. Wait only in TomEE!!!
    Now let’s deploy the same in our WebSphere Application Server. Steps to deploy:

    1. Make sure your WebSphere Application Server is installed and you have already created profile
    2. Start your server
    3. Go to administrator Console -> Applications -> WebSphere Enterprise Application and click on Install
    4. Click on Choose File, browse and select your war file
    5. Click Next and then choose “Fast Path – Prompt only when additional information is required.”
    6. Click Next, in the following screen make sure “Deploy Web Services” is selected/checked and click Next
    7. Click Next and again Click Next
    8. Provide some context root like /soapexptest and click Next and again Next and then Finish
    9. After some time it should ask you to save or Review the deployment, click on Save.
    10. From list of available applications, select your Application and click on Start. You should see something like below

      Application SoapException_war on server server1 and node DRLTRN0002Node01 started successfully. The collection may need to be refreshed to show the current status.

    11. Now go to SoapUI and create a new project, your WSDL should look like this:
      http://localhost:9080/soapexptest/MyService/MyService.wsdl
      
    12. Sample input and output remains the same

    That’s it everything worked perfectly, now in the next post we will see how things get complicated when we use a custom bean for providing SOAP Fault.

Java EE 6 Servlet – TomEE – Caused by: java.lang.IllegalArgumentException: Invalid in servlet mapping

Posted on Updated on

How bad a plain vanilla servlet can go with annotations??? Let’s see what happens if we miss a simple “/”.

So I configured a simple Servlet in eclipse, see the code below

package com.mumz.test.javaee.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class MySecondServlet.
 */
@WebServlet(urlPatterns={"/second","/secondServlet"})
public class MySecondServlet extends HttpServlet {
	
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;
       
    /**
     * The Constructor.
     *
     * @see HttpServlet#HttpServlet()
     */
    public MySecondServlet() {
        super();
    }

	/**
	 * Do post.
	 *
	 * @param request the request
	 * @param response the response
	 * @throws ServletException the servlet exception
	 * @throws IOException the IO exception
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().println("Welcome to second servlet");
	}
}

I am using Apache TomEE, so I wrote this servlet and started my TomEE.

My console was filled up with below stacktrace:

SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/MyServlet]]
	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:188)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1123)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:799)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:744)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/MyServlet]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	... 6 more
Caused by: java.lang.IllegalArgumentException: Invalid <url-pattern> secondServlet in servlet mapping
	at org.apache.catalina.core.StandardContext.addServletMapping(StandardContext.java:3279)
	at org.apache.catalina.core.StandardContext.addServletMapping(StandardContext.java:3254)
	at org.apache.catalina.deploy.WebXml.configureContext(WebXml.java:1430)
	at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1341)
	at org.apache.tomee.catalina.OpenEJBContextConfig.webConfig(OpenEJBContextConfig.java:363)
	at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:873)
	at org.apache.tomee.catalina.OpenEJBContextConfig.configureStart(OpenEJBContextConfig.java:113)
	at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:371)
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5355)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 6 more

And what is the reason???

In my URL pattern I had forgotten a slash “/”

@WebServlet(urlPatterns={"/second","secondServlet"})
public class MySecondServlet extends HttpServlet

And the correction is:

@WebServlet(urlPatterns={"/second","/secondServlet"})
public class MySecondServlet extends HttpServlet {

Android ListFragment conflicts with a type defined in the same file – Heights of Ignorance

Posted on Updated on

Yesterday I stumbled upon below error while developing my Android application which also has a ListFragment

The import android.support.v4.app.ListFragment conflicts with a type defined in the same file

I had android-support-v4.jar in my libs folder and I was finding it
very difficult to understand what could go wrong in such a simple class.

And after taking a closer look it was heights of ignorance :),
see my class definition below:

import android.support.v4.app.ListFragment;

public class ListFragment extends ListFragment {

}

I had given my class name as ListFragment,
and compiler was correctly telling me what went wrong.

Android unable to execute dex : multiple dex files define Landroid

Posted on Updated on

Just today I started getting this exception:

unable to execute dex : multiple dex files define Landroid

Cause: This exception will come if you have multiple version of support library.

Where to check:

  1. Right Click on Project and select Build Path
  2. Check in Libraries if you have support library added (This happens when we do Android Tools -> Fix Project Properties)
  3. If you don’t find any such instance then check if you have copied support library manually into the lib folder of your project
  4. If you don’t find any such duplicates then check how many Android libraries (custom applications like FacebookSDK) 

Remove the duplicate libraries and do a clean -> rebuild

Hope this helps.

Spring Data JPA

Posted on Updated on

Spring Data JPA provides a more cleaner approach of using JPA for DAO layer. It removes boilerplate code and developers can concentrate on actual logic.

Our DataModel

07 September 2013 PM 06-14-30
First create a maven project and add below dependencies:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mumz.test.springdata.jpa</groupId>
	<artifactId>SpringDataJPA</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<properties>
		<spring.version>3.2.4.RELEASE</spring.version>
		<spring.data.version>1.3.4.RELEASE</spring.data.version>
		<hibernate.version>4.2.5.FINAL</hibernate.version>
		<jpa.version>1.0.1.FINAL</jpa.version>
		<querydsl.version>3.2.3</querydsl.version>
		<junit.version>4.8.2</junit.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>${spring.data.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate.javax.persistence</groupId>
			<artifactId>hibernate-jpa-2.0-api</artifactId>
			<version>${jpa.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>com.mysema.querydsl</groupId>
			<artifactId>querydsl-jpa</artifactId>
			<version>${querydsl.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.3</version>
		</dependency>
		<dependency>
			<groupId>commons-pool</groupId>
			<artifactId>commons-pool</artifactId>
			<version>1.6</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<executions>
					<execution>
						<id>default-testCompile</id>
						<phase>test-compile</phase>
						<goals>
							<goal>testCompile</goal>
						</goals>
						<configuration>
							<source>1.6</source>
							<target>1.6</target>
						</configuration>
					</execution>
					<execution>
						<id>default-compile</id>
						<phase>compile</phase>
						<goals>
							<goal>compile</goal>
						</goals>
						<configuration>
							<source>1.6</source>
							<target>1.6</target>
						</configuration>
					</execution>
				</executions>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Given our datamodel and maven dependcies ready, below is the Book Entity class. Book is a simple POJO with JPA annotations.

package com.mumz.test.springdata.jpa.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * The Class Book.
 * 
 * @author prabhat.jha
 */
@Entity(name = "BOOK")
public class Book implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -5163349208616552005L;

	/** The id. */
	private Long id = null;

	/** The name. */
	private String name = null;

	/** The author. */
	private String author = null;

	/**
	 * Gets the id.
	 * 
	 * @return the id
	 */
	@Id
	@Column(name = "ID")
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}

	/**
	 * Sets the id.
	 * 
	 * @param id
	 *            the new id
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * Gets the name.
	 * 
	 * @return the name
	 */
	@Column(name = "NAME")
	public String getName() {
		return name;
	}

	/**
	 * Sets the name.
	 * 
	 * @param name
	 *            the new name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Gets the author.
	 * 
	 * @return the author
	 */
	@Column(name = "AUTHOR")
	public String getAuthor() {
		return author;
	}

	/**
	 * Sets the author.
	 * 
	 * @param author
	 *            the new author
	 */
	public void setAuthor(String author) {
		this.author = author;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((author == null) ? 0 : author.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Book)) {
			return false;
		}
		Book other = (Book) obj;
		if (author == null) {
			if (other.author != null) {
				return false;
			}
		} else if (!author.equals(other.author)) {
			return false;
		}
		if (id == null) {
			if (other.id != null) {
				return false;
			}
		} else if (!id.equals(other.id)) {
			return false;
		}
		if (name == null) {
			if (other.name != null) {
				return false;
			}
		} else if (!name.equals(other.name)) {
			return false;
		}
		return true;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Book [id=" + id + ", name=" + name + ", author=" + author + "]";
	}
}

The major difference from plain old JPA and "Spring Data JPA" is usage of repositories. A Repository provides you with the generic framework for dealing with persistence layer boilerplate code like below:

public void save(MyEntity myEntity){
    if(myEntity.getId() != null) {
        entityManager.merge(myEntity);
    } else {
        entityManager.persist(myEntity);
    }
}

Spring Data JPARepository provides you with enough generic services to take care of most of the scenarios. Given this let's write our Repository called as IBookRepository which is an interface and extends JpaRepository. JpaRepository is parameterized interface so we need to provide the Entity class and class of the identifier(Primary Key). In this case our Entity class is Book and identifier is Long.

package com.mumz.test.springdata.jpa.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.mumz.test.springdata.jpa.entity.Book;

/**
 * The Interface IBookRepository.
 * 
 * @author prabhat.jha
 */
public interface IBookRepository extends JpaRepository<Book, Long> {
	/**
	 * Find book by id.
	 * 
	 * @param bookId
	 *            the book id
	 * @return the book
	 */
	public Book findBookById(Long bookId);

	/**
	 * Find all books.
	 * 
	 * @return the list
	 */
	public List<Book> findAll();
}

Next we will write our Service interface IBookService and it's implementation class BookServiceImpl. IBookService is a plain interface and self-explanatory.

package com.mumz.test.springdata.jpa.service;

import java.util.List;

import com.mumz.test.springdata.jpa.entity.Book;

/**
 * The Interface IBookService.
 * @author prabhat.jha
 */
public interface IBookService {
	
	/**
	 * Save.
	 *
	 * @param book the book
	 * @return the book
	 */
	public Book save(Book book);
	
	/**
	 * Find book by id.
	 *
	 * @param bookId the book id
	 * @return the book
	 */
	public Book findBookById(Long bookId);
	
	/**
	 * Find all books.
	 *
	 * @return the list
	 */
	public List<Book> findAllBooks();
}

Next is our service implementation class BookServiceImpl. If you take a closer look you will see we don't have any EntityManager instead we have our IBookRepository. Same IBookRepository would be used to save and retrieve records.

package com.mumz.test.springdata.jpa.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mumz.test.springdata.jpa.entity.Book;
import com.mumz.test.springdata.jpa.repository.IBookRepository;

/**
 * The Class BookServiceImpl.
 * 
 * @author prabhat.jha
 */
@Service(value = "bookService")
@Transactional
public class BookServiceImpl implements IBookService {

	/** The book repository. */
	@Autowired
	private IBookRepository bookRepository = null;

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.mumz.test.springdata.jpa.service.IBookService#save(com.mumz.test.springdata.jpa.entity.Book)
	 */
	@Override
	public Book save(Book book) {
		return bookRepository.save(book);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.mumz.test.springdata.jpa.service.IBookService#findBookById(java.lang.Long)
	 */
	@Override
	public Book findBookById(Long bookId) {
		return bookRepository.findBookById(bookId);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.mumz.test.springdata.jpa.service.IBookService#findAllBooks()
	 */
	@Override
	public List<Book> findAllBooks() {
		return bookRepository.findAll();
	}

	/**
	 * Gets the book repository.
	 * 
	 * @return the book repository
	 */
	public IBookRepository getBookRepository() {
		return bookRepository;
	}

	/**
	 * Sets the book repository.
	 * 
	 * @param bookRepository
	 *            the new book repository
	 */
	public void setBookRepository(IBookRepository bookRepository) {
		this.bookRepository = bookRepository;
	}
}

And finally our applicationContext.xml. Since we are using annotation driven configuration it is important to tell Spring where to search for our repositories and so that it can search and keep it ready for DI.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	
	http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.2.xsd
	http://www.springframework.org/schema/data/jpa 
	http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

	<tx:annotation-driven />
	<jpa:repositories base-package="com.mumz.test.springdata.jpa" />
	<context:component-scan base-package="com.mumz.test.springdata.jpa" />
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>oracle.jdbc.driver.OracleDriver</value>
		</property>
		<property name="url">
			<value>jdbc:oracle:thin:@localhost:1521:MYDB</value>
		</property>
		<property name="username">
			<value>MYUSER</value>
		</property>
		<property name="password">
			<value>MYPASSWORD</value>
		</property>
	</bean>

	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="database">
					<value>ORACLE</value>
				</property>
				<property name="showSql" value="true" />
				 <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
			</bean>
		</property>
	</bean>

	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
</beans>

We also need persistence.xml since we are dealing with JPA.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
	xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="springdata" >
	</persistence-unit>
</persistence>

Finally our test class BookServiceTest

/**
 * 
 */
package com.mumz.test.springdata.jpa;

import static org.junit.Assert.assertNotNull;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

import com.mumz.test.springdata.jpa.entity.Book;
import com.mumz.test.springdata.jpa.repository.IBookRepository;
import com.mumz.test.springdata.jpa.service.IBookService;

/**
 * The Class BookServiceTest.
 *
 * @author prabhat.jha
 */
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ TransactionalTestExecutionListener.class,
		DependencyInjectionTestExecutionListener.class })
@ContextConfiguration(locations = { "/META-INF/applicationContext.xml" })
@Transactional
@TransactionConfiguration(defaultRollback = false)
public class BookServiceTest {

	/** The last created book id. */
	private Long lastCreatedBookId = null;
	
	/** The book service. */
	@Autowired
	@Qualifier(value = "bookService")
	private IBookService bookService;

	/** The book repository. */
	@Autowired
	private IBookRepository bookRepository;

	/**
	 * Sets the up.
	 *
	 * @throws Exception the exception
	 */
	@Before
	public void setUp() throws Exception {
	}

	/**
	 * Tear down.
	 *
	 * @throws Exception the exception
	 */
	@After
	public void tearDown() throws Exception {
	}

	/**
	 * Test create book.
	 */
	@Test
	public void testCreateBook() {
		Book book = new Book();
		book.setName("Spring Data JPA - Reference Documentation");
		book.setAuthor("Oliver Gierke");
		book = this.getBookRepository().save(book);
		assertNotNull("Test failed create book returned null id",book.getId());
		lastCreatedBookId = book.getId();
	}

	/**
	 * Test find book by id.
	 */
	@Test
	public void testFindBookById() {
		Book book = this.getBookRepository().findBookById(lastCreatedBookId);
		assertNotNull(book);
	}

	/**
	 * Test find all books.
	 */
	@Test
	public void testFindAllBooks() {
		List<Book> books = this.getBookRepository().findAll();
		assertNotNull("Test failed findAllBooks returned null", books);
		if (books != null) {
			for (Book book : books) {
				System.out.println(book);
			}
		}
	}

	/**
	 * Gets the book service.
	 *
	 * @return the book service
	 */
	public IBookService getBookService() {
		return bookService;
	}

	/**
	 * Sets the book service.
	 *
	 * @param bookService the new book service
	 */
	public void setBookService(IBookService bookService) {
		this.bookService = bookService;
	}

	/**
	 * Gets the book repository.
	 *
	 * @return the book repository
	 */
	public IBookRepository getBookRepository() {
		return bookRepository;
	}

	/**
	 * Sets the book repository.
	 *
	 * @param bookRepository the new book repository
	 */
	public void setBookRepository(IBookRepository bookRepository) {
		this.bookRepository = bookRepository;
	}
}

Hope this helps!
N.B: You can download the code from Spring Data JPA