Asdfasf

Sunday, October 14, 2012

Simple Producer Consumer With LinkedBlockingQueue

Here is a simple Producer/Consumer sample using java.util.concurrent.LinkedBlockingQueue. Simply, Cachiers process tasks waiting in dropbox produced by Producer.

Task class which is processed by Cachier:

 public class Task {  
      private int taskNumber;  
      public Task(int taskNumber) {  
           this.setTaskNumber(taskNumber);  
      }  
      public void setTaskNumber(int taskNumber) {  
           this.taskNumber = taskNumber;  
      }  
      public int getTaskNumber() {  
           return taskNumber;  
      }  
 }  

Dropbox class is the box that tasks are dropped in. This class has LinkedBlockingQueue containing task objects to be processed with max size 20


 import java.util.concurrent.LinkedBlockingQueue;  
 public class Dropbox {  
      LinkedBlockingQueue<Task> blockingQueue = new LinkedBlockingQueue<Task>(20);  
      public Task take() throws InterruptedException {  
           return blockingQueue.take();  
      }  
      public void put(Task t) throws InterruptedException {  
           blockingQueue.put(t);  
      }  
 }  

Producer is responsible from producing tasks and putting them to DropBox. If dropbox reaches its limit, producer thread will be blocked till queue has empty slot


 public class Producer implements Runnable {  
      private Dropbox d;  
      public Producer(Dropbox d) {  
           this.d = d;  
      }  
      @Override  
      public void run() {  
           int i = 0;  
           while (true) {  
                Task t = new Task(i++);                 
                try {  
                     d.put(t);  
                     System.out.println(t.getTaskNumber() + " is added");  
                } catch (InterruptedException e) {  
                     e.printStackTrace();  
                }  
           }  
      }  
 }  

Cachier is consumer and responsible from processing tasks, it waits till dropbox has a task to be processed

 public class Cashier implements Runnable {  
      private Dropbox d;  
      private String name;  
      public Cashier(Dropbox d, String name) {  
           this.d = d;  
           this.name = name;  
      }  
      @Override  
      public void run() {  
           while (true) {  
                try {  
                     Task t = d.take();  
                     System.out.println("Processing " + t.getTaskNumber() + " by "  
                               + name);  
                     Thread.sleep(1000);  
                } catch (InterruptedException e1) {  
                     // TODO Auto-generated catch block  
                     e1.printStackTrace();  
                }  
           }  
      }  
 }  

Here is the main class starting application with 1 producer and 3 consumer

 public class Main {  
      public static void main(String[] args) {  
           Dropbox d = new Dropbox();  
           Producer p = new Producer(d);  
           Cashier c1 = new Cashier(d, "Ahmet");  
           Cashier c2 = new Cashier(d, "Mehmet");  
           Cashier c3 = new Cashier(d, "Fatih");  
           new Thread(c1).start();  
           new Thread(c2).start();  
           new Thread(c3).start();  
           new Thread(p).start();  
      }  
 }  

Friday, October 12, 2012

Scenes From Software Development Life :)




Uploading File with Apache Commons File Upload

To upload file into server and reading uploaded file, we need following apache packages;

http://hc.apache.org/httpcomponents-client-ga/

http://commons.apache.org/fileupload/

Client code is as below, it is just posting a file and string parameter into a servlet:


 import java.io.File;  
 import java.io.IOException;  
 import org.apache.http.HttpResponse;  
 import org.apache.http.client.ClientProtocolException;  
 import org.apache.http.client.HttpClient;  
 import org.apache.http.client.methods.HttpPost;  
 import org.apache.http.entity.mime.MultipartEntity;  
 import org.apache.http.entity.mime.content.FileBody;  
 import org.apache.http.entity.mime.content.StringBody;  
 import org.apache.http.impl.client.DefaultHttpClient;  
 public class UploadFile {  
   public static void main(String[] args) throws ClientProtocolException, IOException {  
     HttpClient client = new DefaultHttpClient();  
     String url = "http://127.0.0.1:8080/servlet";  
     HttpPost post = new HttpPost(url);  
     File file = new File("c:\\sil\\SID.jpg");  
     MultipartEntity entity = new MultipartEntity();  
     entity.addPart("file", new FileBody(file));  
     entity.addPart("parameter", new StringBody("value"));      
     post.setEntity(entity);  
     HttpResponse response = client.execute(post);  
     System.out.println(response);  
   }  
 }  

How uploaded file and http parameter can be processed in servlet side?

  public SmsForm processRequest(HttpServletRequest request) throws IOException, ServletException {  
     String contentType = request.getContentType();      
     SmsForm smsForm = new SmsForm();          
     if ((contentType != null) && (contentType.startsWith("multipart/form-data"))) {  
       DiskFileUpload fu = new DiskFileUpload();  
       fu.setSizeMax(100000);  
       fu.setSizeThreshold(4096);  
       fu.setRepositoryPath(System.getProperty("java.io.tmpdir"));  
       try {  
         List fileItems = fu.parseRequest(request);  
         Iterator iter = fileItems.iterator();  
         while (iter.hasNext()) {  
           FileItem item = (FileItem) iter.next();  
           String fileName = item.getName();  
           if (item.getName() == null) {  
             String fieldName = item.getFieldName();              
             smsForm.setField(fieldName, item.getString());              
           } else {  
             smsForm.setFile(item);  
           }  
         }  
       } catch (Exception e) {  
         e.printStackTrace();  
       }        
     }   
   }  

Placing Build Details into MANIFEST.MF via ANT / Maven

If it is needed to place build details into MANIFEST.MF file under META-INF directory of jar file, that can be accomplished via ANT in build.xml as below

      <tstamp>  
           <format property="TODAY" pattern="yyyy-MM-dd HH:mm:ss" />  
      </tstamp>  
      <target name="build" depends="compile">  
           <war warfile="${dist.home}\${dist.war}" basedir="${deploy.home}" webxml="${deploy.home}\WEB-INF\web.xml" excludes="javadoc">  
             <manifest>               
              <attribute name="Built-By" value="${user.name}"/>            
                 <attribute name="Built-Date" value="${TODAY}" />       
              <attribute name="Implementation-Vendor" value="XXXX"/>  
              <attribute name="Implementation-Title" value="${app.name}"/>  
              <attribute name="Implementation-Version" value="${release.number}"/>               
             </manifest>  
           </war>  
      </target>  

Just put required attributes between manifest tag of war or jar task. Output of MANIFEST.MF file would be as below:

 Manifest-Version: 1.0  
 Ant-Version: Apache Ant 1.7.1  
 Created-By: 14.2-b01 (Sun Microsystems Inc.)  
 Built-By: fkul  
 Built-Date: 2012-10-12 17:18:20  
 Implementation-Vendor: XXXX  
 Implementation-Title: product  
 Implementation-Version: 01_01_00_Build01  



Additionally, how those attributes in MANIFEST.MF can be read? As below:

   public static String getBuildDetails() throws MalformedURLException, IOException {  
     Class clazz = ThisClass.class;  
     String className = clazz.getSimpleName() + ".class";  
     String classPath = clazz.getResource(className).toString();  
     if (!classPath.startsWith("jar")) {  
       // Class not from JAR  
       return null;  
     }  
     System.out.println("ClassPath=" + classPath);  
     String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF";  
     System.out.println("ManifestPath=" + manifestPath);  
     Manifest manifest = new Manifest(new URL(manifestPath).openStream());  
     Attributes attr = manifest.getMainAttributes();  
     return attr.getValue("Implementation-Title") + " : " + attr.getValue("Implementation-Version");  
   }  

By shipping build details in MANIFEST.MF and reading them on runtime is a good idea to inform user of product on runtime as which version of product is currently running.

In Maven

If you are using maven, that can be accomplished in pom as below:

<properties>
     <maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
</properties>

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 <version>2.3</version>
 <configuration>
   <archive>
  <manifest>
    <addClasspath>true</addClasspath>
  </manifest>
  <manifestEntries>            
   <Built-Date>${maven.build.timestamp}</Built-Date>            
   <Implementation-Vendor>${vendor}</Implementation-Vendor>
   <Implementation-Title>${name}</Implementation-Title>
   <Implementation-Version>${version}</Implementation-Version>
  </manifestEntries>
   </archive>
 </configuration>
</plugin>

Monday, October 08, 2012

Oracle SID vs SERVICE_NAME

If you connect to ORACLE with SERVICE_NAME, you should define it as below


MADDB=
  (DESCRIPTION=
    (ADDRESS=
      (PROTOCOL=TCP)
      (HOST=172.28.106.152)
      (PORT=1552)
    )
    (CONNECT_DATA=
      (SERVICE_NAME=MADDB)
    )
  )

If you work with SID, you can define it at TOAD by clicking on checkbox while defining TNS name


which will be as below


MADDB=
  (DESCRIPTION=
    (ADDRESS=
      (PROTOCOL=TCP)
      (HOST=172.28.106.152)
      (PORT=1552)
    )
    (CONNECT_DATA=
      (SID=MADDB)
    )
  )


What about connection URL?

To connect with SERVICE_NAME:

jdbc:oracle:thin:@172.28.106.152:1552/MADDB

To connect with SID:

jdbc:oracle:thin:@172.28.106.152:1552:MADDB

For details : http://www.rojotek.com/blog/2008/01/04/oracle-sid-service_name/

Wednesday, October 03, 2012

Shipping WSDL with Jar for JAX-WS Client

If you work with JAX-WS for webservice client, jax-ws needs wsdl file on runtime. For this purpose, it is better to ship wsdl file with your client code in jar file. Just put wsdl file at top level directory in jar file as below:
-JAR
----META-INF/
----wsdl/service.wsdl

Then, you can instantiate client port as below


 URL wsdlLocation = MyClass.class.getResource("/wsdl/service.wsdl");  
 MyService service = new MyService(wsdlLocation);  
 MyPort proxy = service.getBasicHttpBindingPort();  
 ((BindingProvider) proxy).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, serviceEndPointUrl);  

.