Java Web Services Deployment Model

Apr 13, 2010 by

The product I am developing is going to come out in early access package pretty soon. My QA and Support team are still not quite get it why the web services in our product needs additional steps to add some descriptor files when it going to be deployed on Sun Java System Web Server. I also found this confusion quite commonplace among beginners who start learning JAX-WS. I would like to explain it here so the next time somebody asks me again then I can just direct him to this post.

Java EE deployment model
The final package of JAX-WS web services is an ordinary war file just like any other Servlet/JSP web application’s war file. If you look at the basic JAX-WS tutorial you will notice that the implementation can be as minimal as a simple Java class with a couple of web service annotations.

@WebService()
public class NewsService {
    public String[] getAlert(){
        //implementation
    }
}

You can just pack this class to a war file without the need of any descriptor file even web.xml and then deploy it to Java EE application server to get a nice and simple web services.

You are able to do this kind of deployment because your application server has implemented all the necessary specifications for developing/deploying web services on Java EE platform. The main specification defining potable programming model for Java EE platform is JSR-109 (Implementing Enterprise Web Services). If you search internet and mailing list, you may found many developers call web services with this kind of deployment model as “JSR-109 web services”. Actually, JSR-109 always works together with other specification like JSR-224 (JAX-WS) and JSR-181 (web services annotation) so I will choose to call this deployment model “Java EE deployment model”.

If you choose to make your web services compliant with JSR-109 specification then your war file can be deployed on any Java EE application servers that support the specification. I have developed my unit testing on Glassfish and give the same package to QA team to run system test on WebSphere.

Now, let’s look at it in the real action.
Here we are creating a web services stating from creating a web application project. To demonstrate JSR109 web services, I will choose target server to be Glassfish which is a full Java EE application server.

ChoosingContainer

Once you have created a web service (using web services wizard or manually create java class with web services annotation), you will see that there is nothing in your web.xnl that related to web services information. You can ignore the sun-web.xml, this file is specific to Glassfish and it is not descriptor in our main topic. You may want to delete all descriptor in WEB-INF and deploy your web application to see that your web services application is still able to work properly.

JSR109_IDE

Here is the default web.xml file content.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Now you may want to look at the final war file that you can distribute to your client.
You will see that there is no web services library packed in your war file at all. Since this is JSR109 web services so it expect Java EE server to provide all necessary libraries.

D:\Program\netbeans-projects\JSR109\dist>jar -tf JSR109.war
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/ws/
WEB-INF/classes/ws/news/
WEB-INF/classes/ws/news/NewsService.class
index.jsp

Servlet Based deployment model
If you want to deploy the NewsService example above on non full Java EE server (Sun Java System Web Server, Tomcat) then you may have some concerns to think about.

The most important concern is that this kind of deployment is not portable. From the eyes of the non Java EE container, your web services war file is no different from the normal Servlt/JSP web application’s war file. If you want to do web services then you have to choose an implementation of JAX-WS and pack all the necessary libraries into your war. Now you will get a web application that happens to have some libraries that know how to do web services.

Another thing is that your web services implementation classes are not going to be automatically discovered by your container. You will have to edit some file descriptors to tell your JAX-WS implementation library to know how you want your web services to be deployed. These descriptors are specific to the library you are using. The web services in my product need sun-jaxws.xml file when it is going to be deployed on SJSWS because we are using SUN JAX-WS reference implementation for this kind of deployment.

In NetBeans, if you choose target server to be Apache Tomcat then you will get the war file structure as shown below.

ServletBased_IDE

You will see that sun-jaxws.xml file will be added to your WEB-INF directory once you create a web services. Both sun-jaxws.xml and web.xml will contain descriptive information about your web services.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>NewsService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>NewsService</servlet-name>
        <url-pattern>/NewsService</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

sun-jaxws.xml

<endpoints version="2.0" xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">
  <endpoint implementation="ws.news.NewsService" name="NewsService" url-pattern="/NewsService"/>
</endpoints>

And here is the layout of the final package.
D:\Program\netbeans-projects\ServletBasedWS\dist>jar -tf ServletBasedWS.war
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/ws/
WEB-INF/classes/ws/news/
WEB-INF/lib/
META-INF/context.xml
WEB-INF/classes/ws/news/NewsService.class
WEB-INF/lib/activation.jar
WEB-INF/lib/webservices-api.jar
WEB-INF/lib/webservices-extra-api.jar
WEB-INF/lib/webservices-extra.jar
WEB-INF/lib/webservices-rt.jar
WEB-INF/lib/webservices-tools.jar
WEB-INF/sun-jaxws.xml
WEB-INF/web.xml
index.jsp

You will see that jar files of METRO (JAX-WS RI ) have been packed along with our final war file.

read more

Related Posts

Share This

Bug of Glassfish 2.1 in clearing ServletContext’s attributes

Apr 12, 2010 by

I had spent the whole morning finding out what caused an error in a so simple class of a module. It turned out to be a defect of Glassfish Server. I would like to describe the defect here as my own reference.

Since I can’t show you the real production code so I will use this example to describe the defect

public class AppContextListener implements ServletContextListener{
    public static final String AUTHEN_ENABLED = &quot;AUTHEN_ENABLED&quot;;

    private volatile AuthenProcessor authenProsessor;

    public void contextInitialized(ServletContextEvent sce) {
        authenProsessor = createAuthenProcessor();

        if( readConfigBoolean(AUTHEN_ENABLED) ){
            sce.getServletContext().setAttribute(AUTHEN_ENABLED, new Boolean(true) );
            authenProsessor.startup();
        }
    }

public void contextDestroyed(ServletContextEvent sce) {
        Boolean authenEnabled = (Boolean)sce.getServletContext().getAttribute(AUTHEN_ENABLED);

        if( authenEnabled.booleanValue() ){
            authenProsessor.shutdown();
        }
    }
}

I think I don’t need to explain what the class does because it’s easy enough to read. The default value for AUTHEN_ENABLED configuration is true. Once you get the web application running and then tries to undeploy it you will get NullPointerException at the line authenEnabled.booleanValue().

We don’t have any Servlet or JSP yet so it’s impossible that there will be any module that removes AUTHEN_ENABLED attribute from the ServletContext. I have googled it out and found that this is a defect of Glassfish 2.1 that all attributes of ServletContext will be cleared before the contextDestroyed() method gets to be called.

You may find the detail at defect log Issue6594. Actually, the Issue of the defect is 6442 but I found the summary in Issue6594 contains more information.

This defect has been fixed in Glassfish V3. I have deploy the web application on V3 and problem has gone.

read more

Related Posts

Share This

Simple little things

Dec 10, 2009 by

A couple weeks ago, I had a chance to talk to one of my old friends who had been running his startup firm for about 2 years. He came to Bangkok for his business and stayed at my place. We talked about a lot of things especially about how his business was going. He had shared with me his story regarding how hard it was to find and hire a decent developer.  We both agreed that there were not many developers here in Thailand (compare to the number of all university graduates) that had passion in developing software.  My friend told me that when he took a look at the code written by his staff, there were many times that he felt like he could make it a lot better by just adding some simple little changes here and there.

Well, this kind of talk isn’t new. The question has been asking for long time. What is the most important virtue for a man to be successful in his professional life?  Is it the level of intelligence or the passion or the hard working? In forum, soon-to-be-graduates keep asking what are the abilities or skill that the potential employers have been looking for. Novice developers take two or three training courses to acquire knowledge about the coolest technology. There is nothing wrong about doing that. In fact, it’s quite a reasonable preparation for jobs applying.  But sometime I think that it’s not so much about having the most advance skill. In the entry level, it’s more like having great attitude and strong passion.

If you love what you are doing (I know it’s hard), there is great chance that you will spend more time or investing more effort in your work. You are doing that not because you are hoping to get promotion to the next level as soon as possible but because you care about your work itself. A module of your code may already wok just fine. But if you keep learning, one day you may find out that with just some little changes you can make a lot improvement for the module. Those changes are not so complicate that you may need higher education to figure them out. It may be just a pattern or best practice that you learned from a blog entry you has read this morning.

For example, I have seen many place that Log4J logger has been used as;

public ItemResponse processItem(ItemRequest req) throws ItemException {
String rev;
try {
rev = itemArchive.getRevision(req.getItemID() );
} catch (ItemArchiveException ex) {
logger.error(ex);
//recovery code goes here
}
//some code here
}

If you have spent even little time playing with Log4J you may already know that the above logging will not print the stack trace of  the ItemArchiveException. This can cause a headache in trouble shooting problem in real production. Let’s look at the API doc.

The second line is the version that should be used for logging exception. All the stack trace will be logged.

  • public void error(java.lang.Object message)
  • public void error(java.lang.Object message, java.lang.Throwable t)

With a little change to use logger.error(“Failed to get item revision”, ex) can result in a big benefit here.

Speaking of logging stack trace, in my experience, chained exception is very useful when it comes to investigating log file. You should always includes the cause exception in the exception you are about to throw unless you can make the about-to-be-threw exception so meaningful in itself (which I will say it’s pretty hard to do so).

Let’s look at the above list again. What if I want to throw ItemException if I couldn’t get revision value for the item?

try{
// some code here
} catch (ItemArchiveException ex) {
throw new ItemException("Couldn’t get revision for " +  req.getItemID());
}

It will be quite impossible to know what exactly went wrong by just knowing the ID of the item in trouble. Again, a little change can be really helpful

throw new ItemException(“Couldn’t get revision for ” + req.getItemID(), ex);

I have to tell you that I am not trying to exaggerate the problem of these two cases above. I have experienced both cases in real production code and it cause quite a headache for me.

Now back to my main idea of this post.
Well, I just realized that I don’t have a main idea for this post at all. It’s my rambling about how hard it is to spot developers who really enjoy writing software.

read more

Related Posts

Share This

Spurious Wakeup

Sep 14, 2008 by

I have finished reading Effective Java long time ago. It is such a great book. The more I passed through each page the more I realized how little I know about java programming. The distance between “coder” and “developer” is really far

I read most of the item listed in the book. One of the items I have skipped was Item 50: Never invoke wait outside a loop. The code below show the concept of this item

synchronized (obj) {
    while (<condition does not hold>)
        obj.wait();

     ... // Perform action appropriate to condition
 }

Looking at the name of the practice, I thought I knew all the reasons behind it so I just skipped it. Today I found an interesting post asking What is spurious wakeup. I read it and found that “threads can wake up on wait() for no reason at all”!!!!! There are quite many good references for this fact and one of them is, guess what, the item 50 of Effective Java. I would have known it for long time ago if I just read it. One of the reasons behind it stated in the item is that

The waiting thread could wake up in the absence of a notify. This is known as a spurious wakeup. Although The Java Language Specification [JLS] does not mention this possibility, many JVM implementations use threading facilities in which spurious wakeups are known to occur, albeit rarely [Posix, 11.4.3.6.1]

I thought sometimes it was OK to call wait() without condition-checking loop if the object to wait on represented just one condition, the object was shared only between waiting and notifying threads and the code’s execution order guaranteed that wait leaks would not occur. Now giving that JVM implementation can send spurious wakeup signal, the condition checking loop is A MUST

Apparently, the spurious wakeup is an issue (I doubt that it is a well known issue) that intermediate to expert developers know it can happen but it just has been clarified in JLS third edition which has been revised as part of JDK 5 development. The javadoc of wait method in JDK 5 has also been updated

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops

You may wonder (like me) why JLS designer decided to allow this kind of thing to happen. It’s not that I don’t want to use condition checking loop. The checking is the best practice that developers should always do no matter of them knowing anything about the spurious wakeup or not. But I just don’t see the benefit of allowing the wakeup for no reason. It turns out that this is something about performance as stated in Multithread Programming with Java

Due to some arcania in the hardware design of modern SMP machines, it proves to be highly convenient to define them like this. The hardware runs a little faster, and the programmer needs to reevaluate the condition anyway

read more

Related Posts

Share This

I just commit a copyright violation

Sep 14, 2008 by

The story is that I have read an interesting blog entry of Russell Ball and decided to translate the whole blog entry and put it on my extra blog in which I intend to store my translated articles. A few days later Russell wrote a blog entry which, at first, made me think he didn’t approve my act (sorry for my bad interpretation). He clarified me later that I have misunderstood his meaning. He even allowed me to translate any of his blog entry. Thanks very much Russell.

To make sure about the translation issue, I have gathered more information about copyright law and realized that just making it clear that I am not trying to steal other people’s content by placing the original author’s name in the translated article and providing a link to the original content doesn’t make me able to get away from copyright violation.

I found an article talking about the case of translation and online copyright. The author have simulated the situation that.

1. Person A writes an article in Japanese.
2. Person B sees the article, translates it into English, and posts the translated article on his own website

Is Person B infringing Person A’s copyright?

There are 3 person B’s used cases.

1. Person B posts the translated article on his own website without giving any credit to Person A, or providing a link back to Person A’s website

2. Person B posts the translated article on his own website, and credits Person A as the original author. Better yet, Person B even posts a link Person A’s article.

3. Person B posts the translated article on his own website after obtaining permission from Person A.

My case with Russell’s content falls in number 2 the one which seems OK but it’s not.

The translator may have put real effort in translation and once the original work has been translated, the output can be considered as a “derivative work” of the original source. He even makes his intention clear by giving credit to the author and providing a like to the original content. But as long as the translation is not in “fair use”, he is still subject to copyright infringement.

I have translated the whole blog entry, not a part of it. All parts of the output work derived from the original work so I can’t say that I am showing an excerpt of a blog or I just want to show an example message or I am just trying to make a parody. The output work is not a fair use of the original work.

The article about Japanese translation explains that:

Using our example above, it’s the same as Person B creating his own Gundam series where the Gundam are made out of wood. Although Person B’s wood Gundam are different from Person A’s metal Gundam, Person B is still infringing on Person A’s copyrights.

Things will be different if the original work’s owner is willingly to put his/her work in a license that is friendly for distribution and making derivative work like “Creative Common License”. The best and safest way for this kind of scenario is to ask for the author permission in performing any thing on his/her work.

Now let me tell you a bit about my motivation behind my purpose of translating other people’s articles before I end this blog entry.

I am a software developer and I , like all other developers around the word, trying my best to keep myself up to date with all the technology trends and knowledge. With the extremely fast flow of IT information these days, waiting for a government’s department to translate modern technical books or initiate a project to translate articles about the newest technology to thai is just like an impossible hope.

So I have been training myself to read english so I can learn directly from the original sources. The thing that starts my motivation is that I often recommend some good resource or articles on internet to my colleagues and got back the reply like “Do you have those articles in thai”, “I am not that good at reading English, I will see if I can get it somewhere else in thai”. Useless for me to tell them that being in IT field, reading and writing in english are not something we can avoid. I am not very good at reading/writing in English too but at least I am willing to keep practicing.

Not very long ago I found www.thaidev.org which provides forum/resources for thai developers and encourage people to submit translated article under Creative Common License. I thought, “this is great” I might have something to contribute. My hope is that thai developers may feel more comfortable to read those translated article and , at the same time, develop their interest to seek more of this informative resources from the original sources and gradually become familiar with reading in english.

I hope I will also benefit form the translation process. I should gain more understanding in the article I am working on because I will have to do some crosscheck with other resources and performing some research to make sure I truly understand what I am doing otherwise I will just embarrass myself in front of public place if I have put a false information in the translated work.

read more

Related Posts

Tags

Share This

Inversion of Control and Dependency Injection are not the same

Sep 14, 2008 by

The term IOC (Inversion of Control) and DI (Dependency Injection) have often been used interchangeably. Both concepts have been around in software design for a long time and just have became in spotlight recently due to, I guess, the concept of decoupling software components to increase maintainability , make cleaner code and encourage unit-testing has became more and more popular.

There are many frameworks to help developers to implement the concepts but the most adopted one is Spring framework. The fact that Spring call its dependency injection framework “IOC container” so, with its incredible popularity, people start using IOC as the synonym of DI. Technically, IOC is a software design principle which has a more generic meaning than DI. DI is just a specific form of IOC.

I am not going to pretend to be an expert in software design. If you want to hear from the real expert then I recommend you to read Martin Fowler’s article on the concept of IOC and how it related to DI and just forget about the rest of my blog. The core concept I am going to tell you I derived it from those two articles.

What is Inversion of Control?

IOC is about how software components or areas of code give up its “control” to other components or other areas of code. The “control” may be execution flow, object life-cycle managing, the way subcomponent has been created or any program activity.

Let’s look at an example

ServerSocket echoServer = new ServerSocket(8888);
while(true){
    Socket clientSocket = echoServer.accept();
    ClientHandlerThread handler = new ClientHandlerThread(clientSocket);
    handler.start();
}

The above area of code use standard java API to create a server program. It start by binding socket to port 8888 , put it self in forever loop waiting for client connection. Once it got a connection, it decides to create a thread to handle the connection then get back to while-loop to wait for next request. You can think of the above code as a user program which use java network API as a library. The program controls its own execution flow and manages its own life-cycle (in this case the server stop when administrators manually kill its process). The library can be look as a passive component with the user program actively drives the whole program.

Now, let’s say we want a HTTP server. There are so many details to handle when you deal with HTTP protocol. It’s complicate enough for java as a platform to create a framework for you so you don’t need to get your hand dirty in dealing with low level details.

With Servlet API, you only have to concern about your business logic by specify what you want to do with clients requests in doGet/doPost methods. The API and web container will intercept socket connection can call the method you have implemented.
In this case, the control invert from your code to the framework. The framework will drive the whole program. It will call init() to let you have a chance to initialize your component before accepting request and will call destroy() when it decide your servlet shouldn’t be active anymore. This is way IOC is also known as the Hollywood Principle – “Don’t call us, we’ll call you”.

What is Dependency Injection?

DI is a specific form of IOC. In this case, the “control” that is inverted is the way your component manage its dependency.

class MyComponent{
	private ConfigParser parser;

	public MyComponent(String configFile){
		parser = new ConfigParser(configFile);
	}

	public void init(){
		String debugStr = parser.getConfig("debug");
	}
}

MyComponent internally create ConfigParser in it constructor. This will make MyComponent tightly depend on ConfigParser. What if, in the future, you create another version of ConfigParser which read parameters from a configuration repository server? MyComponent has to come up with a way to choose which implementation to use. Not just MyComponent, all code that explicitly create ConfigParser have to be changed to accommodate a new type of parser.

Another thing is the above code is very hard to do unit testing. The ConfigParser implementation always read parameters form file. Imagine you are writing JUnit test case for MyComponent class with 20 test scenario and you have to create a configuration file for each scenario.

interface ConfigParser{
  public String getConfig(String configKey);
}

class FileConfigParser implements ConfigParser{
  public FileConfigParser(String configFile) {   //init   }

public String getConfig(String string) { //Read Parameter from file. }

}

class RemoteConfigParser implements ConfigParser{
  public RemoteConfigParser(String host, int port) { //init  }

  public String getConfig(String string) { //Read Parameter from remote server. }
}

class MyComponent{
  private ConfigParser parser;

  public MyComponent(ConfigParser configParser){
    this.parser = configParser;
  }

  public void init(){
    String debugStr = parser.getConfig("debug");
  }
}

Now, our MyComponent doesn’t explicitly create an implementation of ConfigParser. The control of how to create ConfigParser has been inverted to be a responsibility of someone else or put it another way, someone will create a concrete implementation of ConfigParser (dependency) and inject it to MyComponent. This dependency injection pattern help promote loosely couple system. MyComponent class doesn’t entirely depend on a specific type of ConfigParser, any parser implementation can be injected to MyComponent becase all implementations fulfill the same contracts specified in ConfigParser interface. In JUnit test case you can create a mock parser which read parameters from a StringReader containing just those parameters for a specific test scenario.

RemoteConfigParser is likely to have its own dependency, let’s say it’s a component encapsulate connection transport. You do the same as you did with ConfigParser- externalize the dependency into Transport interface to make someone else be able to inject concrete transport into RemoteConfigParser. Now what if a transport implementation has a few dependencies?

You can get the picture that now our system comprises of many components with its dependency hierarchy. Before you are able to use a component, you have to resolve its whole dependency hierarchy. In the large system which contains hundred or thousand components, who is going to do that for you.

Now it might not be very hard to guess what Spring IOC container is for. I will refactor our program to make RemoteConfigParser has two Transport dependency. Here is the Spring IOC configuration file which I will used to tell spring how to resolve MyComponent dependency hierarchy.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="primary-transport" class="example.ioc.TCPTransport">
    <constructor-arg value="172.20.12.16" />
    <constructor-arg value="8888" />
</bean>

<bean id="backup-transport" class="example.ioc.TCPTransport">
    <constructor-arg value="172.20.12.17" />
    <constructor-arg value="8888" />
</bean>

<bean id="configParser" class="example.ioc.RemoteConfigParser">
    <constructor-arg ref="primary-transport" />
    <constructor-arg ref="backup-transport" />
</bean>

<bean id="myComponent" class="example.ioc.MyComponent">
    <constructor-arg ref="configParser" />
</bean>
</beans>

Somewhere it my program initialization I will ask Spring to create MyComponent for me.

String configFile = "mycomponent-config.xml";
ApplicationContext appContext = new ClassPathXmlApplicationContext(configFile);  

MyComponent myComponent = (MyComponent)appContext.getBean("myComponent");

I don’t know it is correct or not to call a DI framework a “IOC container” but IOC and DI is not 100% equivalent as you may think.

read more

Related Posts

Share This