Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

03 January 2014

Java WebSocket Sample

I have not been updating this blog for some time but I was unsatisfied with my search on Java Websockets topic on the client implementation in Java and configuration so I decided to post one.

There is valuable info on several blogs and presentation slides on Java WebSockets, but generally the samples are about the implementation of server side and websocket client is implemented on html/JavaScript, I wanted a client implementation in Java.

I decided to provide a complete  sample, with  both a Java websocket server and java client together with the html/javascript one.

The sample application is a virtual USD Exchange rate publishing server and the websocket client consumes the new USD rate as it becomes available.

How to Configure:

1. For the server implementation: WebSockets standard is included in JEE7 so you app.server must be supporting JEE7.
WebSphere Liberty 8.5.5 did not run this so I went with GlasssFish 4.0 (build 89)

Just deploy the application as a war or ear file. Since annotation based approach is used no need to configure a web.xml/deployment descriptor.

2. For the Java client implementation: JSE7 does not include WebSockets so you should add necesessary jar files yourself. I used Tyrus as the websocket api implementation.

Use javax.websocket-api.jar and tyrus-standalone-client-1.3.3.jar from https://tyrus.java.net/

3. Java client should have a file named javax.websocket.ContainerProvider in MEFA-INF/services folder with the content org.glassfish.tyrus.client.ClientManager to introduce Tyrus to JSE7 environment as WebSocketContainer provider . (see ServiceLoader API for details)

4. For the html/javascript implementation: IE9 does not support websockets,IE version must be at least 10.
For Firefox and Chrome...they have been supporting websockets for a very long time so it won't be a problem.
see caniuse.com for more info on browser support.

Here is the server application


package websocket.server;

import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.*;
import javax.websocket.*;
import javax.websocket.server.*;

@ServerEndpoint("/ratesrv")
public class CustomEndPoint {
private static Queue<Session> queue = new ConcurrentLinkedQueue<Session>();
private static Thread rateThread ;

static
{//rate publisher thread, generates a new value for USD rate every 2 seconds.
rateThread=new Thread(){
public void run() {
DecimalFormat df = new DecimalFormat("#.####");
while(true)
{
double d=2+Math.random();
if(queue!=null)
sendAll("USD Rate: "+df.format(d));
try {
sleep(2000);
} catch (InterruptedException e) {
}
}
};
} ;
rateThread.start();
}

@OnMessage
public void onMessage(Session session, String msg) {
try {
System.out.println("received msg "+msg+" from "+session.getId());
} catch (Exception e) {
e.printStackTrace();
}
}

@OnOpen
public void open(Session session) {
queue.add(session);
System.out.println("New session opened: "+session.getId());
}

@OnError
public void error(Session session, Throwable t) {
queue.remove(session);
System.err.println("Error on session "+session.getId());
}

@OnClose
public void closedConnection(Session session) {
queue.remove(session);
System.out.println("session closed: "+session.getId());
}

private static void sendAll(String msg) {
try {
/* Send updates to all open WebSocket sessions */
ArrayList<Session > closedSessions= new ArrayList<>();
for (Session session : queue) {
if(!session.isOpen())
{
System.err.println("Closed session: "+session.getId());
closedSessions.add(session);
}
else
{
session.getBasicRemote().sendText(msg);
}
}
queue.removeAll(closedSessions);
System.out.println("Sending "+msg+" to "+queue.size()+" clients");
} catch (Throwable e) {
e.printStackTrace();
}
}
}

and here is the Java WebSocket Client:

@ClientEndpoint
public class WSClient  {

  private static Object waitLock = new Object();

    @OnMessage
    public void onMessage(String message) {
       System.out.println("Received msg: "+message);        
    }

  @OnOpen
    public void onOpen(Session p) {
        try {
            p.getBasicRemote().sendText("Session established");           
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

private static void  wait4TerminateSignal()
{
synchronized(waitLock)
{
try {
waitLock.wait();
} catch (InterruptedException e) {
}
}
}

    public static void main(String[] args) {
    WebSocketContainer container=null;
    Session session=null;
try{
container = ContainerProvider.getWebSocketContainer();
//WS1 is the context-root of my web.app 
//ratesrv is the path given in the ServerEndPoint annotation on server implementation
session=container.connectToServer(WSClient.class, URI.create("ws://localhost:8080/WS1/ratesrv"));
wait4TerminateSignal();
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(session!=null){
try {
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

The html/javascript client is:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket Client</title>
 <script type="text/javascript">

      var wsocket;
      
      function connect() {        
          wsocket = new WebSocket("ws://localhost:8080/WS1/ratesrv");        
          wsocket.onmessage = onMessage;          
      }
           
      function onMessage(evt) {             
         document.getElementById("rate").innerHTML=evt.data;          
      }
      
      window.addEventListener("load", connect, false);
  </script>
</head>
<body>

<table>
<tr>
<td> <label id="rateLbl">Current Rate:</label></td>
<td> <label id="rate">0</label></td>
</tr>
</table>
</body>
</html>

I hope this helps

10 April 2009

Generics and AutoBoxing

Image
Another nice feature of Java is Generics and Auto Boxing introduced with version 5.

see how it simplifies things below:

assume we have a Hashtable that has String objects as keys and a Integer objects as the values.

With generic this is defined as

Hashtable errorList = new Hashtable();
errorList.put("error3",3); --autoboxing
Enumeration fileNames=errorList.keys();
while(fileNames.hasMoreElements()){
String name=fileNames.nextElement(); --no cast thx to generics
int info = errorList.get(name); --autoboxing
}


in the previous versions we would have to write

Hashtable err = new Hashtable();
err.put("error3", new Integer(3));
Enumeration enum4=err.keys();
while(enum4.hasMoreElements())
{
String name=(String)enum4.nextElement();
int info =((Integer)err.get(name)).intValue();
System.out.println(info);
}


Conclusion: I liked them both :)


31 March 2009

Reasonable file deletion error reporting at last

Image

The stupid File.delete() API returns true or false depending on the result of the operation but if it is false you do not get any feedback.

At last! in Java 7 we now have FileRef.delete() which throws an exception reporting the cause of the problem.

30 March 2009

Java7 Directory Listener

Image

I guess everyone had a need to monitor a directory for file creation/update sometime. Previously we used to accomplish this task by continiously polling files in the target directory such as

while(true){
File [] allFiles = dir.listFiles();
processList(allFiles);
waitForSomeTime();
}


Now we have a new way of doing the same task in an event driven manner.
see java.nio.file package for handy FileSystem,FileRef,Watchable,WatchEvent and WatchService.

Here is a sample for how to do the above task with new Java7 APIs.

WatchService service = FileSystems.getDefault().newWatchService();
WatchKey key = directory.getPath().register(service,new Kind[]{StandardWatchEventKind.ENTRY_CREATE});
while(true){
key=service.take();
List eventList = key.pollEvents();
...
key.reset();

}

08 January 2007

Websphere hanging problem during start

I am using IBM WSAD/RAD 6.0 but I had some problems with the integrated WAS 6 server within.
After an sometime the WAS server hangs at Starting... state.
Sometimes the server starts neither in debug mode nor start mode. It just says Starting...
In one case the server starts in debug mode but when you try to start in normal mode it hangs.

The solution: Just remove all the files in the preload folder typically located in the %installation_root%/runtimes/base_v6/profiles/default/logs/preload folder.

22 November 2006

Java based implementation of Apriori Data Mining Algorithm

This is my favor to CS grad students studying datamining:). Possibly this will be an assignment for you.Below is a brief description of Apriori with Java source codes.

Apriori is a well known algorithm for association rule mining, mainly used for market basket like data analysis.For example you are given a list of transactions, you are to find the rules such as
"90% of customers buying coffee and sugar also buy cream".

For the market basket data analysis, one needs two steps:
first determine the frequent item sets then form the association rules from these sets.

While forming the frequent item sets the Apriori principle is simple: Any subset of a frequent itemset must be frequent. Before starting to give the algorithm steps, let me give 2 definitions, support and confidence.

Support of an itemset X isfraction of transactions in D that contain X

Confidence c of an association rule X ⇒ Y in D is Fraction of transactions which contain the itemset Y from the subset of transactions from D which contain the itemset X.

First determine the frequency of each single item.
Then generate candidate sets, for each k-item
frequent set,join with itself to generate the candidates.
Next, prune candidates that don't match the apriori principle stated above.
Calculate the frequencies of the pruned candidates and now you have the item sets of size k+1.

After you have formed the frequent item sets not you need to generate association rules.

For each frequent itemset X
For each subset A of X, form a rule A (X – A)
Delete those rules that do not have minimum confidence


Computation of the confidence of a rule A ==> (X – A)

Confidence(A==>(X-A))=support(X)/support(A)


Thats all!,for the source code

Apriori.java -- the appriori implementation
Kume.java -- helper class, implementation of Set which supports subsets(k) and minus() operations

27 February 2006

How to obtain caller method (jdk 1.4+)

Sometimes you want to know which class/method called your function. Starting with Java 1.4, java.lang.StackTraceElement provides an easy way to accomplish this. Here is how

StackTraceElement[] telements = new Exception().getStackTrace();
String callerClass = telements[1].getClassName();
String callerMethod = telements[1].getMethodName();

The array's 0th item is your method and 1st item is the method that called your method.

GetJava Download Button

26 February 2006

How to Build A DLL and Call It From Another C Program, using MS VC++ 6.0

My professional software development experience is mainly on server side Java/J2EE development. Recently, I had to build a DLL for –let me say – integration with a third party product. Although I was very proficient in the C programming language in collage days, it’s been years ago and it’s been based on vi&gcc&xxgdb development on Unix (mainly Sun Solaris and Digital Alpha workstations) and Linux.

I had trouble in finding a complete and explainatory document for all steps so I decided to write one. I decided to build this short tutorial to guide people who needs to build a DLL and call that DLL from some other program. This tutorial is consisted of two parts, the first section shows the details for building a DLL using MS VC++ 6.0 and the second section shows the way to call it from another C/C++ program. My function takes to char pointers and returns a byte pointer.
I have Microsoft Visual C++ 6.0 Enterprise Edition installed on my Windows XP SP2 computer.

Before starting the tutorial I strongly recommend you to download the free utility program InspectEXE which helps us to explore DLL symbols. I also want to note that I only have a few experience with DLLs and MSVC++ so the way I show here may not be the only and supported /clearer way but this is one way I figured it out and it works. Use it at your own risk :)

1. Building the DLL

Create a new DLL Project (File->New->Projects->Win32 Dynamic-Link Library)

We choose BuildDLL as the project name.

Image

Press the OK button. On the next dialog choose “A DLL that exports some symbols” and press Finish.

Image


Now the IDE builds the source files for you to explore.
BuildDLL.h and BuildDLL.cpp

If you want your function residing in the DLL to be called from outside your function must be preceded with __declspec(dllexport). BuildDLL.h contains a macro for this as a shortcut.

#define BUILDDLL_API __declspec(dllexport)

In order to define my trial function that takes two char*s and returns a byte*

I add the lines

typedef unsigned char byte;

BUILDDLL_API byte* myTrialFunction(char*,char*);
to BuildDLL.h

and the following code listing to BuildDLL.cpp

extern "C" BUILDDLL_API byte* myTrialFunction(char* param1,char* param2)
{
byte* p = (byte*) malloc(sizeof(byte));
*p='a';
return p;
}


Build->BuildDLL.dll(F7) resulted in my dll to be build. Since I have installed InspectExe before, I do right click on the dll open the properties window and choose Exports to see what my dll has exported.
Image Image



Well., sort of strange names… I check the C++ Style names checkbox and see

Image

Here comes the tip of the first section of the tutorial:

My function’s name is myTrialFunction and I will use this function name when I want to load the dll and use the functionality from another program. In order to avoid the mangled name “?myTrialFunction@@YAPAEPAD0@Z” you should add ‘extern “C”’ to your function decleration.If you fail to do this, the program calling your dll’s function with the name “myTrialFunction” will not be able to locale the method with GetProcAddress().

So the line in BuildDLL.dll becomes
extern "C" BUILDDLL_API byte* myTrialFunction(char*,char*);

and BuildDLL.cpp becomes

extern "C" BUILDDLL_API byte* myTrialFunction(char* param1,char* param2)
{

byte* p = (byte*) malloc(sizeof(byte));
*p='a';
return p;
}


Note: You should add #include stdlib.h to use malloc()

So the DLL export symbols look like

Image


So, this is the end of first section, we have seen how to build a DLL that contains a function having two char pointers as arguments and returning a byte pointer. In the next section we will build another C++ program to load the BuildDLL.dll and call that myTrialFunction function.

2. Calling the function from the DLL

Create a new project by clicking File->New->Project->Win32 Console Application

Image
We chose DLLCaller as the project name.



Choose “A Simple Hello World!” application from the next window and click finish.

There are three API calls that you should know at this point to load a DLL and call a function in it.

LoadLibrary() : Locates and loads the DLL into memory
GetProcAddress(): Gives you a function pointer to your function
FreeLibrary() : To release resources when you are done with the DLL.


Also BuildDLL.dll should be in the DLL lookup path of your new program so you must copy the BuildDLL next to DLLCaller.exe (you can also place it in system32 which is a very ugly way)


First we add the following two lines to define a shortcut to the function pointer.

typedef unsigned char byte;
typedef byte* (*ptr_myTrialFunction)(char*,char*);


and #include for DLL calling API functions.


And the main() method in DLLCaller.c becomes

// DLLCaller.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int main(int argc, char* argv[])
{
HINSTANCE hDLL = NULL; //A DLL instace
Ptr_myTrialFunction func; //Pointer to my function
byte* function_retval; //return value of the function

hDLL = LoadLibrary("BuildDLL"); // Load the DLL
if(hDLL==NULL)
{
//If the LoadLibrary() call can not locate and load the DLL
//it returns NULL
fprintf(stderr,"%s\n","Unable to load DLL");
return -1;
}
else //DLL is loaded
{
func = (Ptr_myTrialFunction)GetProcAddress(hDLL, "myTrialFunction");
//first parameter to the GetProcAddress is the DLL instance containing the function
//second parameter is the name of function in the DLL
if(func==NULL)
{
//If the GetProcAddress() call can not find the function
//it returns NULL
fprintf(stderr,"%s\n","Unable to locate function");
return -1;
}
else // function is found and a pointer to it is located
{
function_retval=func("a","b");
if(function_retval==NULL)
{
fprintf(stderr,"%s\n","Function can not return null?");
return -1;
}
else // function returned successfully
{
fprintf(stdout,"%d\n",*function_retval);
}
}
}
fprintf(stderr,"%s\n","Finished!");
return 0;
}


Executing the program yields the following result
Image

Where 97 is the ASCII code of ‘a’

Final note for the curious: If we do not put the 'extern "C"' in the decleration of myTrialFunction in the DLL side we can still call the function with its manged name ?myTrialFunction@@YAPAEPAD0@Z" so the line
func = (Ptr_myTrialFunction)GetProcAddress(hDLL, "myTrialFunction");

will become
func = (Ptr_myTrialFunction)GetProcAddress(hDLL, "?myTrialFunction@@YAPAEPAD0@Z");

and it also works.

Good luck!

25 November 2005

Why I Hate Java Swing API ?

Image
I have been developing Java applications professionally since 2000, if you add collage days, it becomes 1998(the old java 1.0 days with strange event model, remember the handleEvent() method? )

I believe Java is a very successful programming language,it has fulfilled all it promised.WORA(Write Once Run Anywhere), garbage collection (no dangling pointers), build-in threading support in the language,several APIs(servlet,jdbc,javamail,jsp,rmi,) making life easier and standadized...It is a perfect fit for building robust, scallable, enterprise level server side applications.

But when it comes to client side, unfortunately things are not the same

Whenever I have to build some GUI using swing, a sudden pain starts in my stomach.
I do totaly understand that swing is an extemely flexible development API with is MVC based architecture, and I agree with this but that's all.In today's world where buzz words like 'abstraction', 'resusability' have great importance, swing is a failure.

What makes swing diffucult to develop is, if you have to develop something more complex that adding a button on a canvas or setting a label's text you need to do lots of lots of tricks.

Suppose you want to make some rows of your table uneditable, suprise! there is no such functionaly, neither JTable not DefaultTableModel has it.Solution?, of course with swing you can do anything.Now you 'just' have to subclass DefaultTableModel, then code your own table model's isCellEditable() function

The same applies if you want to make some columns invisible, you should again introduce a brand new table model class , and aggange getColumnCount() accordingly.
The same story applies for most classes in the API.

The question is: where is abtraction,where is reuseablity? where is rapid application development using the API model. I can not reuse DefaultTableModel even for such simple and basic invisible column/uneditable row needs.

As a concusion java is the superior language for server side development, but for client side development I still miss the Delphi days..