Tuesday, November 12, 2013

WSDL 2 Java

WSDL 2 Java
So you decided to do wsdl 2 java design. This is currently the more “proper” way to go about it. For more information about this debate see: http://docs.spring.io/spring-ws/site/reference/html/tutorial.html. You have the wsdl but how do you generate the code?

Maven Plugin

If all you need is to convert one wsdl, you can do a quite simple solution with maven using the ant plugin:

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-antrun-plugin</artifactId>
       <executions>
              <execution>
                     <phase>process-classes</phase>
                     <configuration>
                           <target>
                                         <java classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
                                         <arg value="-impl" />
                                         <arg value="-b" />
                                         <arg value="bindings.xjb" />
                                         <arg value="-server" />
                                         <arg value="-d" />
                                         <arg value="gen" />
                                         <arg value="-wsdlLocation" />
                                         <arg value="/WEB-INF/wsdls/my.wsdl" />
                                         <arg value="my.wsdl" />
                                         <classpath>
                                                <path refid="maven.compile.classpath" />
                                         </classpath>
                                  </java>
                           </target>
                     </configuration>
                     <goals>
                           <goal>run</goal>
                     </goals>
              </execution>
       </executions>
</plugin>

This plugin will generate using the cxf engine a java file with all the schema files needed for the code.
This is a good solution if you just need one file or want to just look things over.
If you have multiple wsdl’s and you want to intervene during the generating process you need to do it by code. Also in the case that you do not know in advance what the wsdls are but only know the directory of the wsdls, then you need to generate them via code.

Java Code

To run the cxf engine via the java code you will need to run the same command line as above just via java code.
So why do we want to use java code and not just a simple maven plugin. First reason is, if you want to add a binding file. For more about binding please see: http://www.oracle.com/technetwork/articles/entarch/jax-ws-jaxb-customization-082750.html, https://blogs.oracle.com/sdimilla/entry/implementing_handlers_using_jaxws_2.
Binding files allows you to change the way the java code is generated. You can add annotations, or define the package name and many more things.
Binding files, recommend that you add the wsdl location in the binding file, like:
<jaxws:bindings     
  wsdlLocation="xxx.wsdl"
The disadvantage of this, is that you need to create a template binding file so that you can change the name for each wsdl file. The other option is to just omit this section in the binding file.

The main options are:  where to generate the code, whether or not to compile it, and the wsdl location. For all options see http://cxf.apache.org/docs/wsdl-to-java.html.
Another issue that needs to be handled is the location of the command path relevant to the bind file. You can put the bind file where ever you want, but when passing the location to the api, the relative path must be relative to the working directory of the command execution.  For an easy way of calculating relative paths between directories please see:

Code generation intervene

One of the features that are greatly missing is the ability to intervene in the code generation of the wsdl service file. If you want to intervene in the generation of the xsd files, you can do this with jaxb plugins.

For a nice example that adds support for XmlElementWrapper see (https://github.com/dmak/jaxb-xew-plugin). For more information on plugins and jaxb extensions see http://www.jroller.com/gmazza/entry/enhancing_jaxb_artifacts.
The problem is that for the wsdl generation cxf did not use the jaxb plugins scheme and there is no official way to intervene in the code generation.
I “hack” can be done. Cxf uses a velocity template to generate the file. The velocity template name is iml.vm. So if you write your own template (and place it in the same package as cxf template), and add it to a jar that is in the classpath before the cxf jar, your template will be used by cxf and not the internal one.

Other issues for code generation

If you are generating all the web service stubs, you will most probably also want your code to add to your cxf xml file all the proper endpoints as well.

Generation of Code

Since we will be generating the service classes from the wsdl’s you need to think if this process is a onetime process or an ongoing one. If it is part of your build system, then you cannot edit the generated files (by default cxf generates the files with a TEMP suffix). There are a few options to solve this issue. First you need to make sure that all generated files are not in the source area but in the generated (/target/ generated-sources).

You now have a few options of how to add your specific code, while still continue to regenerate the service classes. The simple one is to just copy the service class into you source code. This sort of defeats the idea of having new services added dynamically. Second solution is if you edited the  template generation you can have all services delegate the call to a central spring bean, and then use the proxy pattern to handle all calls. Third option is to add an AOP layer to catch all calls to the service and write a generic code for all of them without having to do any wiring or changing of cxf templates.

Wednesday, October 23, 2013

Java Decompiling and Eclipse


Java Decompiling and Eclipse


One of the more frustrating issues are when you debug code in eclipse and want to debug a third party jar but do not have the source.


If the jar is open source and you are using maven you can try to use
mvn install –DdownloadSources=true.
This does not always work, since not all jar’s supply the source files.
In addition there are third part jar’s or sun jar’s that do not have source files. For this we have decompile utilities. The most famous one is jad (http://en.wikipedia.org/wiki/JAD_(JAva_Decompiler)).
So just go to your eclipse market and write jad. Once you have installed the plugin, next time you need to look at the code you will see:





Monday, October 14, 2013

Android – Israel Timezone


Android – Israel Timezone

For all those Israelis that have an android but have the wrong time/time zone since Israel keeps on changing the date of day light savings, this procedure is for you.

Download updated tzdata 


Android adb

Make sure you have the android adb (http://developer.android.com/sdk/index.html)

Connection to your device

To test your connection type in the dos prompt: adb devices.
You should get a list like

Copy the tzdata file to the same folder as the adb.

Run the following commands

adb root
adb remount
adb push tzdata /system/usr/share/zoneinfo/
adb shell chmod 644 /system/usr/share/zoneinfo/tzdata
adb reboot

You should now have the correct time and time zone.



Monday, October 7, 2013

Create a Java CLI application with Maven

Create a Java CLI application with Maven

Creating a CLI application is part of our daily routine. In java it is strait forward; all you need to do is to add a class with the main function:
public static void main(String[] args) {
}
This is nice for debugging from eclipse, but if you need to release this jar with the cli working, you will face the following issues:
1.       You need to add the main class to you manifest file and compile it in the jar.
2.       You need to create a folder with all the jar’s dependencies needed to run this cli.

Main Class

maven-jar-plugin

The first issue can be solved by using the maven-jar-plugin:
<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-jar-plugin</artifactId>
       <configuration>
              <archive>
                     <manifest>
                           <addClasspath>true</addClasspath>
                           <mainClass>com.package.Main</mainClass>
                     </manifest>
              </archive>
              <finalName>jarname-cli</finalName>
       </configuration>
</plugin>

This plugin will create a jar file by the name of jarname-cli.jar, will a manifest file with the following entry:
Main-Class: com.package.Main
This will allow us to run from the command line:
java -jar jarname-cli %1 %2.

Jar Dependencies

Though if your jar has dependencies to other jars you will receive the following error when running the command line:
Exception in thread "main" java.lang.NoClassDefFoundError:
This is because we still need to package all the dependency jars into the same folder.
To solve this you need two more plugins.

maven-dependency-plugin (http://maven.apache.org/plugins/maven-dependency-plugin/)

The first plugin will calculate all the dependencies and copy them to a directory (cli):
<plugin>
       <artifactId>maven-dependency-plugin</artifactId>
       <executions>
              <execution>
                     <phase>install</phase>
                     <goals>
                           <goal>copy-dependencies</goal>
                     </goals>
                     <configuration>
       <outputDirectory>${project.build.directory}/../cli/</outputDirectory>
                     </configuration>
              </execution>
       </executions>
</plugin>

This plugin will copy all dependencies even though you don’t need all of them (it will include testing and jars not necessarily in use). You can start to manage you dependencies with the exclude, but this way you will constantly need to check that new jars are not added. The other option is to tell the plugin only the jars you want added:
                     <configuration>
                           <includeScope>runtime</includeScope>
                           <includeArtifactIds>commons-cli,spring-core,commons-logging,freemarker</includeArtifactIds>
                           <outputDirectory>${project.build.directory}/../cli/</outputDirectory>
                     </configuration>

This way any new dependencies will not be copied to the directory.
Of course if there are dependencies that you need for the execution of your cli, you will need to add them. You can use either the includeArtifactIds, or includeGroupIds whichever is easier.
This plugin is nice since it will get all the dependencies, but what it does not do is copy current jar to your cli directory. For this you need the ant plugin to copy the current jar

maven-antrun-plugin (http://maven.apache.org/plugins/maven-antrun-plugin/)

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-antrun-plugin</artifactId>
       <executions>
              <execution>
                     <id>Copy Main Jar To Cli Directory</id>
                     <phase>install</phase>
                     <configuration>
                           <tasks>
                                  <copy todir="${project.build.directory}/../cli/">
                                         <fileset dir="${project.build.directory}/" includes="*.jar"
                                                excludes="*sources*.jar,*javadoc*.jar" />
                                  </copy>
                           </tasks>
                     </configuration>
                     <goals>
                           <goal>run</goal>
                     </goals>
              </execution>
       </executions>
</plugin>

The action is very simple, it is a copy action from ant, that will copy the jar from the target directory.

maven-clean-plugin (http://maven.apache.org/plugins/maven-clean-plugin/)

Since your maven project will create the dir and all the jars needed, you need to add the clean plugin to remove the dir when running clean in maven.
<plugin>
       <artifactId>maven-clean-plugin</artifactId>
       <configuration>
              <filesets>
                     <fileset>
                           <directory>${project.build.directory}/../cli</directory>
                     </fileset>
              </filesets>
       </configuration>
</plugin>

This solution is good for most cases. But sometimes you need more flexibility. Occasionally you might want not to have a directory with all jar’s but you might want to pack them all in one jar (thought licensing must be considered). Also sometimes you might want to add more files or resources to the jar, or maybe create a zip file instead of the jar file. For this you have the assembly plugin. The dependency plugin is actually a subset of the assembly plugin, so you can do all the above and more.

maven-assembly-plugin (http://maven.apache.org/plugins/maven-assembly-plugin/)

We will not go into the whole plugin since you can do a lot with it (for a full set of options see http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html).
                     <plugin>
                           <artifactId>maven-assembly-plugin</artifactId>
                           <configuration>
                                  <finalName>wsf_${version}</finalName>
                                  <appendAssemblyId>false</appendAssemblyId>
                                  <descriptors>
                                         <descriptor>src/main/resources/assembly.xml</descriptor>
                                  </descriptors>
                                  <outputDirectory>${project.build.directory}/../assembly/</outputDirectory>
                           </configuration>
                           <executions>
                                  <execution>
                                         <id>make-assembly</id>
                                         <!-- this is used for inheritance merges -->
                                         <phase>package</phase>
                                         <!-- bind to the packaging phase -->
                                         <goals>
                                                <goal>single</goal>
                                         </goals>
                                  </execution>
                           </executions>
                     </plugin>

As you can see we can do both creating a manifest file with the mainclass, and adding other files. You can enable enhanced features by assigning an assembly.xml and do for example:

<assembly>
        <id>bundle</id>
        <formats>
               <format>jar</format>
        </formats>
        <includeBaseDirectory>false</includeBaseDirectory>
        <dependencySets>
               <dependencySet>
                       <outputDirectory>/</outputDirectory>
                       <useProjectArtifact>true</useProjectArtifact>
                       <unpack>true</unpack>
                       <scope>runtime</scope>
                       <includes>
                               <include>*:commons-cli:*</include>
                               <include>*:spring-core:*</include>
                               <include>*:commons-logging:*</include>
                               <include>*:freemarker:*</include>
                       </includes>
               </dependencySet>
        </dependencySets>
</assembly>


Here you can notice that we used the option <unpack>true</unpack>. This will unpack all jar’s and then repack them all in one jar. This way you can bundle you cli into one jar only.

Sunday, August 18, 2013

Multithreading queries with hibernate & spring

There are times that we have a process that needs to run multiple requests from the db, and then with the result of all of them, to combine the results in a specific way. Of course you can run each query sequentially, but to boost performance you want to run them in parallel.
At first this seems simple since you just need to run each query in a separate thread using a callable, and then wait on the future results to get them (for a good article on thread and concurrency see: http://www.vogella.com/articles/JavaConcurrency/article.html).  
As we will see this approach has a lot of problems, and does not work simply with hibernate.

Session and Threads

The problem is what information do you pass to the thread, and what is the result from the thread. The first naïve thought was to create the query object in the main thread (so the thread can be generic and not deal with the query and parameters), and then pass to each new thread the query. Then all the thread needs to do is call query.uniqueResult() or query.list() and return the result.
The problem with this approach is that hibernate session is not thread safe (http://www.javalobby.org/java/forums/t104442.html, http://pveentjer.wordpress.com/2007/02/19/sharing-hibernate-entities-between-threads/), so you cannot share the session between threads. Hibernate to simplify the implementation assumes that all queries run on a thread are using the same session. This means that you are not allowed to pass the session between threads.
So the next option is to pass the dao to the thread and then call a specific function on the dao. This makes more sense from a design point of view since this is the default design of a service layer application. In a web app, each request has it’s own thread, and then the calls to the dao are all stateless and will have their own session per thread that is created by hibernate.
The downside to this solution is that we do not have a generic way to run queries asynchronous. A possible solution is to pass a reference to the dao, and an object that describes the function and parameters, and the within the thread to use reflection to find the function and to call it with the parameters sent.

Transactions

The next part that you need to think about is transactions. By default each thread will have its own transaction (needs to be defined by annotations or xml). It is not simple to have transactions cross threads and is not considered to be a good design practice. But if for whatever reason you must have it, global JTA is the way to go.

Results

The next part that needs to be taken into consideration is the result from the thread. The problem is that if we return the entity as is, and it has lazy objects, accessing these objects on the main thread will cause a Hibernate Lazy Load Exception. Since hibernate tries to load the data from the database when there is a lazy proxy, and the call to the object is from a different thread, hibernate cannot load the information and a lazy exception is thrown (for more information see http://blog.xebia.com/2009/02/07/hibernate-and-multi-threading/).
There are multiple ways to solve this issue. One is to use dto’s and convert the entity to a pojo and then it will not be associated with hibernate session. Another solution is to use an open source lib by tikal (http://tikalk.com/chop-hibernate-lazy-associations) that will chop any entities and replace the proxies by a null according to an aop pointcut.

Summary:

What seemed like a simple idea in the beginning to run multiple queries in multiple threads, although a need sometimes, the implementation must be carefully done to take into account all the issues raised above.