Wednesday, February 6, 2013

RMI Server and Client implementation

1. Interface
  • interface extends Remote class
  • every method throws RemoteException
package com.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Date;

public interface RmiInterface extends Remote {

 Date getDate() throws RemoteException;
}
2. RMI server implementation
  • class extends UnicastRemoteObject
  • class implements custom RmiInterface
  • class creates RMI registry and binds it to localhost and specified port
package com.rmi.server;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Date;

import com.rmi.RmiInterface;

public class RMIServer extends UnicastRemoteObject implements RmiInterface {

 protected RMIServer() throws RemoteException, AlreadyBoundException,
   UnknownHostException {
     
  String registryHost = InetAddress.getLocalHost().toString();
  String registryName = "serverRMI";
  int registryPort = 1234;
  
  System.out.println("Starting RMI server on host: " + registryHost
    + ", port: " + registryPort + " with name: " + registryName);
  
  Registry registry = LocateRegistry.createRegistry(registryPort);
  registry.bind(registryName, this);
 }

 @Override
 public Date getDate() {
  return new Date();
 }

 public static void main(String[] args) throws RemoteException,
   UnknownHostException, AlreadyBoundException {
  RMIServer server = new RMIServer();
 }
}
3. RMI client implementation
  • class gets RMI registry
  • class invokes RMI server method
package com.rmi.client;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Date;

import com.rmi.RmiInterface;

public class RMIClient {

 public static void main(String[] args) throws RemoteException,
   NotBoundException {
   
  String registryHost = "127.0.0.1";
  String registryName = "serverRMI";
  int registryPort = 1234;
  
  Registry registry = LocateRegistry.getRegistry(registryHost,
    registryPort);
  RmiInterface rmiServer = (RmiInterface) registry.lookup(registryName);
  Date date = rmiServer.getDate();
  
  System.out.println("Date from RMI server: " + date);
 }
}

Wednesday, January 23, 2013

Deploying Axis2 web service as ROOT application on Tomcat

By default Axis2 services are available on http://host:8080/axis2/services/*. If you want to remove axis2/services part from the service endpoint and access your service by http://host:8080/serviceName/*

1. Overide default Axis2 servlet mapping services in web.xml file.

 AxisServlet
 /serviceName/*

2. Remove an application name value by deploying axis2 implementation (from war distribution axis2-1.X.X-war.zip) as ROOT application.

Info: War distribution contains application with above structure:
axis2-web
META-INF
org
WEB-INF
    classes
    conf
    lib
    modules
    services
        put here *.aar files to deploy WS
    web.xml (manually created)

web.xml file







    Apache-Axis2
    
        AxisServlet
        Apache-Axis Servlet
        org.apache.axis2.transport.http.AxisServlet
        
        
        
        
        
        
        
        
        
        
        1
    
    
        AxisAdminServlet
        Apache-Axis AxisAdmin Servlet (Web Admin)
        
            org.apache.axis2.webapp.AxisAdminServlet
    
    
    
    
    
        AxisServlet
        /servlet/AxisServlet
    

    
        AxisServlet
        *.jws
    

    
        AxisServlet
        /serviceName/*
     
 
    
        AxisAdminServlet
        /axis2-admin/*
    

    
    
    
        inc
        text/plain
    

   
      index.jsp
      index.html
      /axis2-web/index.jsp
    

    
      404
      /axis2-web/Error/error404.jsp
    

    
        500
        /axis2-web/Error/error500.jsp
    

Tuesday, January 22, 2013

JBoss: change 8080 port

If you want to change default 8080 port just go to a file:

./jboss/server/default/deploy/jbossweb.sar/server.xml

find below fragment and change port attribute:


Saturday, November 24, 2012

JAXB marshall and unmarshall

  1. write xsd schema file(s)
  2. use xjc tool to compile xsd schema file(s) into java classes
  3. create a java object
  4. marshall the object into a file
  5. unmarshall the object from a file

1. drink.xsd schema file



   <xs:element name="drink">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="name" type="xs:string" />
            <xs:element name="alcohol" type="AlcoholEnum" minOccurs="0" maxOccurs="10" />
            <xs:element name="ice" type="xs:boolean" />
         </xs:sequence>
      </xs:complexType>
   </xs:element>

   <xs:simpleType name="AlcoholEnum">
      <xs:restriction base="xs:string">
         <xs:enumeration value="vodka" />
         <xs:enumeration value="rum" />
         <xs:enumeration value="whiskey" />
         <xs:enumeration value="Unknown" />
      </xs:restriction>
   </xs:simpleType>

2. compile xsd file into java classes
xjc drink.xsd

3 - 6 marshall and unmarshall using JAXB
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import programmerutilities.blogspot.com.AlcoholEnum;
import programmerutilities.blogspot.com.Drink;

public class MarshallDrink {

   public static void main(String[] args) {

      Drink drink = new Drink();
      drink.setName("Whiskey on te Rock");
      drink.setIce(true);
      List<alcoholenum> alcoholList = drink.getAlcohol();
      alcoholList.add(AlcoholEnum.WHISKEY);

      // marshall and unmarshall the drink object using a file
      try {
         File file = new File("drink.xml");

         JAXBContext context = JAXBContext.newInstance(Drink.class);

         Marshaller marshaller = context.createMarshaller();
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
         marshaller.marshal(drink, file);

         Unmarshaller unmarshaller = context.createUnmarshaller();

         Drink unmarshalledDrink = (Drink) unmarshaller.unmarshal(file);

      } catch (JAXBException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
}

Friday, November 23, 2012

Java read file (entire or line by line)

Four ways to read a file in java. I have tested an execution time of them using 1,37 MB text file with 108825 lines. Result of tests is in a first comment of each method and is specified in milliseconds.

1 Read entire file at once

1.1 FileInputStream with read()
// execution time: 7 - 8 ms
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
File file = new File("C:\\test.txt");
InputStream is = new FileInputStream(file);
byte[] temp = new byte[1024];
int read;
while ((read = is.read(temp)) >= 0) {
 buffer.write(temp, 0, read);
}
byte[] data = buffer.toByteArray();
System.out.println(new String(data));
PS: remember that read(byte[] b) doesn't do what you think it does -> link

1.2 FileInputStream with readFully()
// execution time: 11 - 12 ms
File file = new File("C:\\test.txt");
DataInput input = new DataInputStream(new FileInputStream(file));
byte[] bufferArray = new byte[(int) file.length()];
input.readFully(bufferArray);
String value = new String(bufferArray);

2 Read file line by line

2.1 BufferedReader with readLine()
// execution time: 19 - 20 ms
FileInputStream fStream = new FileInputStream("C:\\test.txt");
DataInputStream in = new DataInputStream(fStream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
 System.out.println(line);
}
2.2 Scanner with nextLine(
// execution time: 196 - 216 ms
File file = new File("c://test.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
scanner.nextLine();
 System.out.println(line);
}
scanner.close();