miercuri, 29 iulie 2009

JAX-WS Webservices: Part 2

This post continues previous one for offering new information about jax-ws webservices. One issue which is often met is related to return types of the web service. For instance: We implement an EJB component which models a person. How can I return this? I might try to specify for one of the webservice methods the EJB as a return type. This is so wrong. The EJB might have a collection resulting from a OneToMany relation. When the client will try to access an element of this collections an exception will be raised complaining about "session closed". To avoid this, we implement a new class(wrapper) which will be serializable. We make sure we don't use Java Collection types like Set, List, Hash, ..... We'll use arrays instead([]). In the web service method we populate all attributes of the wrapper class. The following example demonstrates this:

@Entity
public class Persoana {
@Id
private long cnp;

@OneToMany(mappedBy="parinte")
private List rude;


//metode getter/setter
}


public class PersoanaWrapper implements Serializable {
private long cnp;

private PersoanaWrapper[] rude;

//metode getter/setter
}


Metoda din webservice care doreste sa returneze o persoana ar putea fi implementat de maniera urmatoare:

public PersoanaWrapper getPersoana(long cnp) {
//cod prin care incarc ejb-ul persoanei dorite. => Persoana persEJB;
PersoanaWrapper pers = new PersoanaWrapper();
int nrRude = persEJB.getRude().size();

pers.setCNP(persEJB.getCNP());
pers.setRude(new PersoanaWrapper[nrRude]);

for(int i = 0; i < nrRude; i++) {
PersoanaWrapper tmp = new PersoanaWrapper();
tmp.setCNP(persEJB.getRude().get(i).getCNP());
pers.getRude()[i] = tmp;
}

return pers;
}

One enhancement of the example is to add a new method/constructor which accepts an argument with the EJB type. Using wrapper classes you cand return whatever custom data type you want.
I mentioned in a previous post that when deploying a java web service in a container it will be exposed as a web service and as a Session bean. I strongly encourage you to invoke it as a web service or as a Session bean(not both). If you intend to make your application interoperable then use just web services.

How can we inject resources in a web service?

It is common to use resources in a web service. For instance, we might need to use a DataSource from the container. We might want to inject an EntityManager in the webservice. Both situation are easily solved in Java EE:

@PersistenContext(unitName="myPersistence")
private EntityManager em;

@Resource(mappedName="java:jdbc/MyDS")
private DataSource ds;

We can use @Resource annotation to inject various resources like:
  • Mail session
  • Custom data sources
  • Other resources

luni, 27 iulie 2009

JAX-WS Webservices

In one of the recent projects I worked on I was supposed to implement a SOA arhitectue. The business logic was exposed through web services. This solution was developed because one of its components was written in C# and the rest of components were written in Java. The chosen container for the business layer was JBoss 5(web services, ejb) and Tomcat 6 for front-end(web application). The first major issue was raised by the JBoss 5 version downloaded from the jboss.org site.

Obs: !!!!!!!!!If you use jre/jdk 6 download the jboss version compiled with jdk 6. Otherwise you will get weird errors when you try to access the webservice.

I assume that you downloaded the correct version of jboss on your computer. Java EE/jax-ws makes webservices creation a formality.

@WebService
@SOAPBinding(style=Style.RPC)
@Stateless
public interface ServiciuTest {
@WebMethod
public String sayHello(@WebParameter(name="message")String msg);
}

@Stateless
@WebService(endpointInterface="ServiciuTest")
public class ServiciuTestBean {
public String sayHello(String msg) {
return msg;
}
}

This is all you have to do for creating a functional web service. In this moment the webservice can be deployed on a container that supports jax-ws. In Java EE, the above mentioned class will be exposed as a web service and as a session bean. The interface described is an endpoint(spec) for the web service. The annotation used in the method declaration alter the way the wsdl file is generated. You must keep in mind that you won't be able to return classes which aren't serializable.

In the following paragraphs I present how a complex web service can be implemented. This web service downloads a file from server.

@WebService
@SOAPBinding(style=Style.RPC)
@Stateless
public interface ServiciuFilesTest {
@WebMethod
public byte[] getFile(@WebParam(name="file_name")String fName);
}

@Stateless
@WebService(endpointInterface="ServiciuFilesTest")
public class ServiciuFilesTestBean {
public byte[] getFile(String fName) {
   byte[] deRet = new byte[(int)(new File(fName)).length()];
try {
FileInputStream file = new FileInputStream(fName);
file.read(deRet);
file.close();
}
catch(IOException ioe) {
ioe.printStackTrace();
return null;
}
return deRet;
}
}

This is all you have to do. In this manner you can send files to a client through the web service. Usually, it is recommended that you encode the content sent using Base64.

vineri, 12 iunie 2009

java.util.logging and a wrapper log class

In this post, I show how can we easily implement a logger class which has three types of messages:
  • info
  • warning
  • error
This messages are saved in a file in the following format: err-"currentdate". This logger stile is inspired by classic unix/linux log style. The following class uses java.util.logging and it should be enough for most applications. The class has singleton pattern assigned to it because I need to instantiate it only once.

package ro.example;

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.logging.*;

public class LoggerSingleton {
private static Logger logger;
private static LoggerSingleton selfInst = null;
private String msgFile = "err%s.log";

private LoggerSingleton() throws Exception {
logger = Logger.getLogger("MyApplication");

this.switchStdErr(this.msgFile);
}

private void switchStdErr(String fName) throws Exception {
Calendar cal = GregorianCalendar.getInstance();
String file = String.format(fName, cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.DAY_OF_MONTH));

PrintStream err = new PrintStream(new FileOutputStream(file, true));

System.setErr(err);
}

public static LoggerSingleton getInstance() throws Exception {
if(selfInst == null)
selfInst = new LoggerSingleton();

return selfInst;
}

public void writeInfo(String msg) {
try {
logger.log(Level.INFO, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}


public void writeWarning(String msg) {
try {
logger.log(Level.WARNING, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}

public void writeWarning(Exception excp) {
try {
logger.log(Level.WARNING, excp.getMessage(), excp);
}
catch(Exception ex) {
ex.printStackTrace();
}
}


public void writeError(String msg) {
try {
logger.log(Level.SEVERE, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}

public void writeError(Exception excp) {
try {
logger.log(Level.SEVERE, excp.getMessage(), excp);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}

Comment: The log method from Logger class writes all messages to System.err stream. Because of this. the first thing I do is to redirect System.err to a specified file.

In the following section I show a possible test file which uses all available methods.

package ro.example;

public class TestLoggerSingleton {
public static void main(String[] args) throws Exception {
LoggerSingleton log = LoggerSingleton.getInstance();

log.writeInfo("Just for fun");
log.writeWarning("Only a warning");
log.writeError("Only an error message");

try {
throw new Exception("Nice error.");
}
catch(Exception ex) {
log.writeWarning(ex);
log.writeError(ex);
}
}
}


The obtained file is presented below.

Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeInfo
INFO: Just for fun
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeWarning
WARNING: Only a warning
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeError
SEVERE: Only an error message
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeWarning
WARNING: O eroare draguta
java.lang.Exception: Nice error.
at ro.example.TestLoggerSingleton.main(TestLoggerSingleton.java:16)
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeError
SEVERE: Nice error.
java.lang.Exception: Nice error.
at ro.example.TestLoggerSingleton.main(TestLoggerSingleton.java:16)

Every day in which we use the logger class a new file is generated with yyyy-mm-dd.log name. In this way we can see how application evolved in an extremely simple manner. In a future post I'll show how can we generate an xml log file instead of a plain text file.

miercuri, 3 iunie 2009

Hibernate session in web applications

In this article, I show a method in which we can avoid using EAGER fetch type in hibernate entities. For opening a hibernate session in web application we can use a filter that is mapped for /* url pattern. This filter will open a hibernate session and make it available for the current request. In this way, every Collection attribute from an entity can be easily accessed during the request. Some common problems met when not using this method is related to session being closed when trying to access an element from a collection. The session will be put as an request attribute and we call it OPENED_CONNECTION. The following code should give an idea of how we open and use a hibernate session in this way.

public class ManageConnection implements Filter {

private FilterConfig filterConfig;

public void destroy() {}

public void init(FilterConfig fConfig) {

this.filterConfig = fConfig;

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {

Object obj = request.getAttribute("OPENED_CONNECTION");

Session ses = null;

if(obj != null) {

ses = (Session)obj;

try {

ses.close();

}

catch(HibernateException ex) {

ex.printStackTrace(); //just print the stack trace into log files

}

}

ses = HibernateSingleton.getInstance().openSession();

request.setAttribute("OPENED_CONNECTION", ses);

chain.doFilter(request, response);

}

}


I use a helper class called HibernateSingleton. The code for this class is presented bellow:


public class HibernateSingleton {

private static SessionFactory sessionFactory;

static

{

sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();

}

public static SessionFactory getInstance()

{

return sessionFactory;

}

public static Session getRequestSession() {

return (Session)Contexts.getRequest().getAttribute("OPENED_CONNECTION");

}

}


Basically, the class build a Hibernate session factory and provides two static methods. One of them help as to get a Hibernate session instance. The other method returns the opened_connection attribute from the request. In my case Contexts.getRequest() method is just a wrapper method which has the code: return (HttpRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
Of course this is an example from a JSF application.
Now, everytime you need a hibernate session in your application you just use HibernateSingleton.getRequestSession() method. If you have used other methods for managing hibernate sessions you will definitely "love" this one. It also improves performance.

miercuri, 20 mai 2009

Python mocking __new__

In acest tutorial voi prezenta o facilitate python extrem de interesanta: inlocuirea metodei speciale __new__. Acest lucru mi-a fost util in momentul in care am scris o suita de teste pentru o clasa. Problema era ca aceasta clasa era Singleton si in concluzie era dificil sa ma asigur ca resursele injectate sunt corecte de la un test la altul. Solutia de compromis a fost sa elimin comportamentul Singleton al clasei doar pentru teste.

In this tutorial I will show you an unsual feature of python: replacing special method __new__. This seemed extremely useful to me in the moment I wrote some unit tests for a class. Adding the fact the class was a Singleton makes the problem even more interesting. It was difficult for me, to make sure every test was injecting the correct resources. The solution I came up with was to eliminate the "singleton" behavior just for tests.

class TestedClass(float):
def mockedNew(cls, *args, **kwds):
print("Mocked new")
self = float.__new__(*args, **kwds)
return self

def deleteNew(cls):
cls.__new__ = cls.mockedNew

def __new__(cls, arg=0.0):
print("Normal new")
return float.__new__(cls, arg*0.0254)

def __init__(self, arg=0.0):
print("Not working")

deleteNew = classmethod(deleteNew)
mockedNew = classmethod(mockedNew)

if __name__ == "__main__":
TestedClass.deleteNew()
print(TestedClass(12))

In mod normal, in exemplul de mai sus, daca nu as apela deleteNew rezultatul ar fi:
Usually, if I don't invoke deleteNew the result would be:
  • Normal new
  • Not working
  • 0.3048
Calling deleteNew changes the result to:
  • Mocked new
  • Not working
  • 12
In this manner I managed to change __new__ method behavior dynamically.

Python and Mocker

In this tutorial I'll show you how you can test your algorithms by eliminating dependencies(filesystem, database, ldap, and so on). Doing like this, you can easily follow the business logic and assert for the expected results. In the following example, I'll show you how to eliminate filesystem dependency.

def complex_algorithm(objOpen=open):
#here comes the business logic

#here comes the filesystem dependency
f = objOpen("test_file.txt", "w")
f.write("simple test")
f.close()

We can easily see that I provided an argument(objOpen) with default value of open builtin. In this manner, I can inject a mocked function for testing and in a production environment, open builtin will be used. In the following paragraph, I present the "mocking" part:

def test_ComplexAlgorithm():
controller = Mocker()
objOpen = controller.mock()
fMocked = controller.mock()

objOpen.open("test_file.txt", "w")
controller.result(fMocked)

fMocked.write("simple test")

fMocked.close()

controller.replay()

complex_algorithm(objOpen.open)

This is all you need. If the function had returned a result you could have easily asserted it. For more informations about mocking visit the site http://labix.org/mocker.

Python and static methods

At my new working place I had to learn Python so I discovered some features that are hard to understand for someone with Java background. One of these features is definition of static methods.

In Java, you can write something like:

public static void helloWorld() { System.out.println("Hello world"); }

In python lucrurile sunt mai complicate si depinde si de versiune folosita. De exemplu, daca folosim o versiune de python anterioara 2.4 atunci vom defini o metoda statica in felul urmator:

In Python, it's more difficult to define class/static methods. If we use a version earlier than 2.4 we will define a static method like this:

def helloWorld(cls):
print("Salutari")

helloWorld = classmethod(helloWorld)

If we use a version newer than 2.4, the implementation of static methods is simpler because we use a decorator:
@staticmethod
def helloWorld(cls):
print("Hello world")

In both cases, defining a static method in Python is harder than in Java.