• Feb
    • 25
    • 2012

Going Remote – JavaFX and Spring Remoting

Posted by In Uncategorized 6 comments
This entry is part 11 of 15 in the series Building JEE applications in JavaFX 2.0

Because JavaFX is so new to the scene, most of the focus of my previous blogs has been on getting our JavaFX client working cleanly. That’s only a very small part of the JEE puzzle however, and in this post we’re going to start expanding our horizons. We’re going to turn our little FirstContact application into a client-server one, using HTTP as the communication channel.

This post is probably going to be a little more complex than some of my last ones (unless you are already pretty familiar with web services development with Spring and Maven). I’m going to just push through it so as not to get bogged down in the detail. If you get lost on the way, feel free to ask questions via comments.

The full source code for this post can be found here.

Part 1: Split the project into a multi-module Maven project

Where before we had one single desktop application, now we’re going to have two: a client and a server. We also have a bit of code that is shared between these two (i.e. the service interface and data transfer objects sent between client and server), which we need to bundle into both the client and the server.

In Maven this means we need three ‘projects’, one for the client, one for the server and one for the common module shared between them. We could create these three separate projects as stand-alone instances, but it would be nice if we could bundle them all together into one so we can build them as one entity and work with them as one project in our IDE.

Maven’s answer to this is the ‘multi-module project’. If you’re not familiar with these, have a quick google on them. In fact this article here quite nicely explains what we’re about to do to our code so I’ll leave the explanation up to that and just get stuck into it.

First we need to restructure all our old single module code into the following directory structure:

c:\dev\first-contact-client-server

- pom.xml

+ first-contact-client
  - pom.xml
  + src
    + main
      + java
        + com
          + zenjava
            + firstcontact
              + gui
                + detail
                  - ContactDetailPresenter.java
                + main
                  - MainPresenter.java
                + search
                  - ContactSearchPresenter.java
                - FirstContactApp.java
                - FirstContactAppFactory.java
      + resources
        + fxml
          - ContactDetail.fxml
          - ContactSearch.fxml
          - Main.fxml
        - styles.css

+ first-contact-common
  - pom.xml
  + src
    + main
      + java
        + com
          + zenjava
            + firstcontact
              + service
                - Contact.java
                - ContactService.java

+ first-contact-server
  - pom.xml
  + src
    + main
      + java
        + com
          + zenjava
            + firstcontact
              + service
                - SimpleContactService.java

You can see our three modules are nicely contained within a single parent module called first-contact-client-server (you can use whatever name you like for). Additionally we’ve split the code and resources into the appropriate modules, so all the GUI code and FXML files are in the ‘client’ module, whereas the service interface and Contact bean (which are effectively the API onto our server implementation) are in the ‘common’ module, and our simple service implementation is in the ‘server’ module (for now we’re going to keep this simple, but in future posts we’ll look at making this use a database).

All the code and FXML is, at this stage, just a direct copy from our project in the last post, the only change is that we now have four pom.xml files instead of the single file we had before. There’s one pom.xml file for each of the three modules and a parent pom.xml to bundle it all together. Since each of these modules is doing something different, the POMs need to reflect this, so we need to modify each slightly.

First our parent POM. In this we need to let Maven know that we’re using a multi-module project and what modules are contained within. The below will do this (note the use of pom as the packaging type).

c:\dev\first-contact-client-server\pom.xml


<?xml version="1.0"?>
<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.zenjava</groupId>
    <artifactId>first-contact-client-server</artifactId>
    <name>JFX Contact Management System</name>

    <packaging>pom</packaging>
    <version>1.0</version>

    <modules>
        <module>first-contact-common</module>
        <module>first-contact-client</module>
        <module>first-contact-server</module>
    </modules>

</project>

Next our client POM. This is very similar to our original POM as we are using all the same client side features. The only two significant changes are firstly the reference back to the parent POM (which we just created above), and secondly a dependency onto the first-contact-common module (which we’ll create below) so that our client can use the shared code from there.

c:\dev\first-contact-client-server\first-contact-client\pom.xml

<?xml version="1.0"?>
<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>

    <parent>
        <groupId>com.zenjava</groupId>
        <artifactId>first-contact-client-server</artifactId>
        <version>1.0</version>
    </parent>

    <groupId>com.zenjava</groupId>
    <artifactId>first-contact-client</artifactId>
    <name>JFX Contact Client</name>

    <packaging>jar</packaging>
    <version>1.0</version>

    <dependencies>

        <!-- First Contact Common -->

        <dependency>
            <groupId>com.zenjava</groupId>
            <artifactId>first-contact-common</artifactId>
            <version>1.0</version>
        </dependency>

        <!-- JavaFX -->

        <dependency>
            <groupId>com.sun.javafx</groupId>
            <artifactId>javafx</artifactId>
            <version>2.0.beta</version>
            <scope>system</scope>
            <systemPath>C:/apps/javafx/javafx-2.0.2_32bit/rt/lib/jfxrt.jar</systemPath>
        </dependency>

        <!-- Spring and supporting toolkits -->

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2</version>
        </dependency>

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

    </dependencies>

</project>

Our common POM is similar to our client one, however since this contains only basic code with an interface and a data transfer object, we have no need for all the dependencies onto JavaFX, Spring, etc. In fact we don’t want these dependencies because this code will be shared with the server, so there should be no reference to JavaFX or client side libraries in it.

c:\dev\first-contact-client-server\first-contact-common\pom.xml

<?xml version="1.0"?>
<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>

    <parent>
        <groupId>com.zenjava</groupId>
        <artifactId>first-contact-client-server</artifactId>
        <version>1.0</version>
    </parent>

    <groupId>com.zenjava</groupId>
    <artifactId>first-contact-common</artifactId>
    <name>JFX Contact Common</name>

    <packaging>jar</packaging>
    <version>1.0</version>

</project>

Finally, our server POM. At this stage we’ve just got our very simple service implementation in this project so there’s no need for a lot of dependencies. We just need one reference back to our common module so our server can make use of the classes defined in there.

c:\dev\first-contact-client-server\first-contact-server\pom.xml

<?xml version="1.0"?>
<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>

    <parent>
        <groupId>com.zenjava</groupId>
        <artifactId>first-contact-client-server</artifactId>
        <version>1.0</version>
    </parent>

    <groupId>com.zenjava</groupId>
    <artifactId>first-contact-server</artifactId>
    <name>JFX Contact Server</name>

    <packaging>jar</packaging>
    <version>1.0</version>

    <dependencies>

        <!-- First Contact Common -->

        <dependency>
            <groupId>com.zenjava</groupId>
            <artifactId>first-contact-common</artifactId>
            <version>1.0</version>
        </dependency>

    </dependencies>

</project>

That’s it, you should be able to open this project in your favourite IDE. In IntelliJ you simply choose File -> Open Project and then select the top-level pom.xml file. IntelliJ is smart enough to handle the multi-module setup and will create a corresponding multi-module IntelliJ project with all our sub-modules configured as you would expect.

Eclipse can definitely also handle this structure although I believe you have to use one of the plugins (m2Eclipse from memory) rather than the default project file generation. NetBeans also looks to have multi-module support (according to this document anyway), but I’ve not used it so can’t comment.

Alternatively you can use the command line to build your project via Maven. If you open a Command Prompt and change directory to where the top-level pom.xml file lives (so in my case that’s c:\dev\first-contact-client-server) then type the following command:

mvn clean install

This will attempt to build all three of our modules and package them into JAR files, one after the other. If the build is successful, the resulting JAR files will be found in the ‘target’ directories under each module (e.g. the client JAR will be at c:\dev\first-contact-client-server/first-contact-client/target/first-contact-client-1.0.jar).

If you run this build right now however, with our project in its current state, you will get a compile error! Our client is still trying to ‘new’ an instance of our SimpleContactService, which now lives on the server so the client doesn’t have access to it (since there is no dependency from the client POM to the server POM). We’re going to sort this all out in the next few steps.

Part 2: Create a web app for the server

Currently our modules are all setup to produce JAR files when built. For the client and common modules this works fine, but our server module is going to be deployed to a web server (i.e. Tomcat) so it needs to be bundled into a WAR file instead.

With Maven this is incredibly easy, all we do is change the ‘packaging’ type in our server POM from ‘jar’ to ‘war’:

<packaging>war</packaging>

Since this is a web application, we also need to supply a web.xml file to be included in the WAR file. We do this simply by adding one to the directory maven expects it to be, which is first-contact-server/src/main/webapp/WEB-INF.

For now we can just use an empty web.xml file, but we’ll add to this shortly:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

</web-app>

Job done! Next time you run a build (such as mvn clean install from the command line) Maven will assemble a WAR file for us into the ‘target’ directory of the server module, which can be deployed on any servlet engine (such as Tomcat). Of course our webapp doesn’t actually do anything yet, but we’ll sort that out next.

Part 3: Expose our services using Spring’s HTTP Invoker

We have a server, but it’s not really serving anything up yet. We need to expose some ‘web services’ that our client can access and make use of. There are a number of flavours of web services we can choose between here: SOAP is the old timer, a big, heavy, verbose XML-based solution; RESTful is a lighter XML-style approach, whereas Hessian and Spring’s HTTPInvoker are binary based solutions. There’s a whole stack of other options out there too.

The choice of web service toolkit is largely down to your specific project requirements. Each of the frameworks has it’s advantages and disadvantages. The binary protocols, for example, typically have less overhead and can be more performant, whereas the XML-based ones allow for human readability. Some toolkits will work only with Java clients (such as Spring’s HTTPInvoker), some work better for limited-memory mobile devices (such as Hessian or RESTful) and others have additional features (and overheads) for solving complex business-to-business scenarios (such as SOAP).

In our application we have a JavaFX client and a Java server so for my money our best choice is Spring’s HTTPInvoker. It is incredibly simple to setup and use and since it uses Java Object serialization (i.e. our Java beans are just serialized across the HTTP connection) it is very fast and handles all our data types naturally. If we were also looking at supporting non-Java clients (such as an iPhone app) then I’d probably tend towards Hessian.

Luckily there is a toolkit out there that helps us wire in our choice of web service technology and allow us to easily change our mind later: Spring Remoting. This is another optional Spring toolkit, separate to the HTTPInvoker (i.e. you can use one without the other) which allows us to magically switch between many of the popular remoting toolkits just through some configuration changes. This gives us the flexibility to start developing using one toolkit (such as Spring’s HTTPInvoker) and if we find the need, easily switch to another (such as Hessian). The official Spring documentation on this is very good and well worth a read.

Enough pre-amble, let’s get to it. First thing we need to do is get the Spring Remoting jars into our server project. Maven makes this easy once again, we just add the following dependency into our server POM:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>3.0.6.RELEASE</version>
</dependency>

Now we need to expose a Servlet that can handle incoming requests and route them to our service implementation. Spring provides the DispatcherServlet for exactly this purpose, so we can add this to our web.xml file like so:

<servlet>
    <servlet-name>first-contact</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>first-contact</servlet-name>
    <url-pattern>*.service</url-pattern>
</servlet-mapping>

I’ve mapped the above Servlet so that any incoming request ending in .service will be passed on to the DispatcherServlet. You can use any URL pattern you like (such as *.htm or *.do).

Next we need to tell Spring which services to expose. Up until now we’ve managed to get away with using Spring’s @Configuration annotation to avoid writing Spring XML files. This is web-land however, and web-land seems to love XML, so unfortunately we have to slot in at least a little XML to get things happening.

By default Spring will look for an XML file with the same name as the <servlet-name> in our web.xml and with “-servlet.xml” appended to it. So for our above web.xml in order to configure our first-contact servlet, we need to create a file called first-contact-servlet.xml and put this in our WEB-INF directory.

In this XML file we need to tell Spring to instantiate our SimpleContactController class and expose it at a certain endpoint (i.e. web URL). Since we’ve decided to use Spring’s HTTPInvoker, it’s a very simple case of including a HttpInvokerServiceExporter reference in our XML file. Our config looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<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.xsd">

    <bean name="simpleContactService" class="com.zenjava.firstcontact.service.SimpleContactService"/>

    <bean name="/contact.service" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="simpleContactService"/>
        <property name="serviceInterface" value="com.zenjava.firstcontact.service.ContactService"/>
    </bean>

</beans>

The first <bean> declaration just adds our SimpleContactService to the application context with the name ‘simpleContactService’ so it can be referenced elsewhere in the file. On it’s own, this does nothing as far as our web service is concerned. The bean is loaded into memory, but it’s not accessible on the web yet.

It’s the second <bean> declaration where the magic happens. Here we define a HttpInvokerServiceExporter to expose our service over the web. Spring knows to use the ‘name’ attribute as the end point, so in this case, our service will be accessible via the URL http://your-domain.com/contact.service. If you want to change the end point, all you do is change the name in this config file (just make sure the URL mapping in your web.xml matches the pattern you use).

When the server is running you can actually hit this URL with a standard web browser to call the service – of course it will throw an error because the browser doesn’t know how to handle Java serialized objects but it’s still a useful little test to see if things are wired up correctly.

As well as the ‘name’, we also give the Exporter a reference to the ‘simpleContactService’ that we defined in the first <bean>. This tells Spring to use the simpleContactService to provide all the implementation of the service calls. The HttpInvoker will do all the socket handling and serializing and deserializing for us, and then just delegate the calls onto our nice, Java implementation. Like magic!

There’s one more thing we have to tell the exporter. We have to explicitly specify that we want this service to be accessible via the ContactService interface. This might seem a bit redundant but it’s actually a pretty important security decision. If Spring just exposed every method on the SimpleContactService implementation bean we might accidentally allow web access to private methods that should only be used on the server side. Using a single interface allows us to tightly control what we expose to the big, scary world that is the world wide web, where hackers lurk waiting to take down our every server.

We’re done. Well almost. Because we’re using Spring’s HTTPInvoker, and it uses Java serialization to serialize our data between client and server, we need to make sure our beans are actually serializable. This is a simple case of making our Contact bean implement the standard java Serializable interface like so:


import java.io.Serializable;

public class Contact implements Serializable
{

Exposing our ContactService as a web service was that easy! All you need to do now is either run your web application in your IDE, or use ‘mvn clean install’ from the command line to generate a WAR file that you can then take and deploy to any servlet-based web server. I use Tomcat religiously because it simple and reliable, but there are literally dozens to choose from.

Part 4: Add a little magic

In our previous step, we had to manually declare our SimpleContactService bean in the XML file. In a large project there could be large numbers of these service beans (as well as dozens of supporting beans such as DAOs, etc). Declaring each one by hand can get a bit annoying.

There’s a little bit of Spring magic, called component scanning, that can save us some work in this area. Basically we can set some properties in our Spring XML file to tell Spring to scan our project’s classpath and find any class annotated with @Service (or a few alternatives that we won’t worry about yet) and Spring will then just magically add those to the application context.

Unfortunately there’s no way (that I’m aware of) to avoid defining the HttpInvokerServiceExporter in our XML file so we still have to do this step by hand. I don’t know whether this is a deliberate decision by the Spring guys for security reasons (i.e. they don’t want people accidentally exposing service beans when they didn’t mean to) or whether it was just not thought of. Either way, we’re left with the job of exposing these one-by-one in XML config.

Here’s the Spring config for using component scanning for our beans:

first-contact-servlet.xml

<?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"
       xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:annotation-config/>

    <context:component-scan base-package="com.zenjava.firstcontact.service"/>

    <bean name="/contact.service" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="simpleContactService"/>
        <property name="serviceInterface" value="com.zenjava.firstcontact.service.ContactService"/>
    </bean>

</beans>

Then all we have to do is annotate out SimpleContactService class like so:

import org.springframework.stereotype.Service;

@Service
public class SimpleContactService implements ContactService
{

For just our single bean the above component scanning is definitely overkill but as our application grows with more features and more services, this component scanning approach will save us a little bit of XML configuration file mucking around. We’ll see this pay off soon, I promise.

Part 5: Access our services from our client

Our server’s now sitting there eager to accept requests and serve up data, but our client is not talking to it yet. If you look at our old FirstContact code, you’ll remember that the SimpleContactService was created in our FirstContactAppFactory class and then injected into our various Presenters. The Presenters only ever made reference to the ContactService interface and never had any dependency on the underlying implementation being used. This was a deliberate tactic which is about to pay dividends.

Instead of creating a new instance of the SimpleContactService in our client, we can now use Spring Remoting to get a reference to the remote SimpleContactService that’s running on our server. Spring will give us a ‘stub’ implementation of our ContactService interface that uses HTTPInvoker to communicate back to the server, but from our perspective this is virtually invisible – everything is coded to use the ContactService interface so it doesn’t matter whether we’re accessing the local SimpleContactService or using a stub, the rest of our code won’t change at all!

First things first: we have to get the Spring Remoting library into our client module. Additionally we also need the HttpClient library from Apache commons. Spring’s HttpInvoker uses this under the covers to make the connection to the server. Here’s the dependencies to add to our client module’s POM:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>3.0.6.RELEASE</version>
</dependency>

<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
</dependency>

Next we replace the factory method in FirstContactAppFactory (which currently creates our new SimpleContactFactory), to instead create a ‘stub’ onto our server. The code for this is a tad messy because it has been written more for XML-based configuration than Java based config, meaning we have to manually do some factory stuff that XML Spring normally hides. Still it is only a few lines of extra code and it is all nicely hidden away inside our AppFactory doing no harm to anyone.

Our new factory method looks like this:

@Bean
public ContactService contactService()
{
    String serverUrl = "http://localhost:8080/contact.service";

    HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean();
    factory.setServiceUrl(serverUrl);
    factory.setServiceInterface(ContactService.class);
    factory.setHttpInvokerRequestExecutor(new CommonsHttpInvokerRequestExecutor());
    factory.afterPropertiesSet();
    return (ContactService) factory.getObject();
}

Note that I’ve just hard coded the server URL into this class and I’m using localhost on port 8080. This is the default when you are running a local tomcat instance but obviously in a proper distribution you would need to provide a proper URL (e.g. http://yourdomain.com/yourapp/contact.service). It would be trivial to load the URL from a properties file, or there are a number of other techniques that could be used. For now I’ll leave that as something for you to play with.

Part 6: Marvel at our success

We’re done! We’ve just written a working distributed JavaFX application with a web based back-end. You can either run the server inside your IDE (check your IDE’s help for details on how to do this, or post questions below) or you can use mvn clean install to build a WAR file that you can then copy into a Tomcat webapps directory. Your client at this stage is best run through your IDE by launching the FirstContactApp class (down the road we’ll have a look at different ways to build a deployable client bundle).

Since this is a distributed application you can actually run as many instances of the client as you want and they will all talk to the same server instance. You can even run the client from different machines but in this case you will need to change the server URL in the FirstContactAppFactory class to point to the IP address or domain name of the computer running the server.

We’ve made a pretty big step with this work towards a proper JEE application, but you’ll notice that when we start and stop the server, all our data is reset because it is only stored in memory on the server. In the next post we’ll have a look at using a database to store changes long term as you’d expect from a proper JEE system.

The full source code for this post can be found here.

Series Navigation<< Porting “First Contact” to SpringJavaFX and persistence: adding database support >>

6 Comments

  • Reply
    Alan
    March 17, 2012

    This is very nice.
    I had a brief overview in the material you’ve put up in this post, but definitely will try it out later this week and follow the steps you took to learn some new things. I’m new to Java EE and JavaFX so this has been prescious stuff for me.
    Thanks a lot. Keep sharing your knowledge and experience.

  • Reply
    March 17, 2012

    Hi Dan,

    Nice blog! Is there an email address I can contact you in private?

  • Reply
    Karthik
    July 5, 2012

    Hi Dan,
    I have recently started to learn JavaFX and your blog has been immensely helpful! Thanks for all the good stuff.

  • Reply
    Diego
    January 11, 2013

    Hello Zen
    when I try to run the generated JNLP file I get
    com.sun.deploy.net.JARSigningException: unsigned jar file: file:/D:/workspace/first-contact-client-server/first-contact-client/target/webstart/lib/javax.inject-1.jar
    at com.sun.javaws.security.SigningInfo.getCommonCodeSignersForJar(Unknown Source)
    at com.sun.javaws.security.SigningInfo.check(Unknown Source)
    at com.sun.javaws.security.JNLPSignedResourcesHelper.checkSignedResourcesHelper(Unknown Source)
    at com.sun.javaws.security.JNLPSignedResourcesHelper.checkSignedResources(Unknown Source)
    at com.sun.javaws.Launcher.prepareResources(Unknown Source)
    at com.sun.javaws.Launcher.prepareAllResources(Unknown Source)
    at com.sun.javaws.Launcher.prepareToLaunch(Unknown Source)
    at com.sun.javaws.Launcher.prepareToLaunch(Unknown Source)
    at com.sun.javaws.Launcher.launch(Unknown Source)
    at com.sun.javaws.Main.launchApp(Unknown Source)
    at com.sun.javaws.Main.continueInSecureThread(Unknown Source)
    at com.sun.javaws.Main.access$000(Unknown Source)
    at com.sun.javaws.Main$1.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

    But.. whe I try to sign the jar file using jarsigner, I get
    jarsigner: unable to open jar file: javax.inject-1.jar
    Do you have any clue?
    Thank you

  • Reply
    May 9, 2013

    Good day I am so glad I found your blog, I really found
    you by mistake, while I was browsing on Digg for something else, Nonetheless I am
    here now and would just like to say thank you for a remarkable post and a all round entertaining blog (I
    also love the theme/design), I don’t have time to go through it all at the moment but I have bookmarked
    it and also added in your RSS feeds, so when I have time I will
    be back to read a lot more, Please do keep up the fantastic b.

Leave a Comment