Mostrando entradas con la etiqueta Java. Mostrar todas las entradas
Mostrando entradas con la etiqueta Java. Mostrar todas las entradas

viernes, 11 de mayo de 2012

Warning!!!! Thread.sleep called in loop

Wow serveral months since last post!

Well returning to the topic, when you write a code block like this:
 while(timeout()){  
  try{  
   Thread.sleep(1);  
  }catch(Exception e){}  
 }  
Some IDEs as Netbeans or some software quality tools popup a warning informing that this kind of code usually is a design flaw or a bad practice, in other words a code smell. If you search in google you will get quick answers like "if you put a Thread.sleep inside a loop you are writting inneficient code, you should use notify and wait" but at the end of the day I have never found a clear example of how this code conversion from a "while" loop to a monitored code should be done. So.... here's the example, lets think an hipotetical problem where one thread is pooling a message bus. If you send a message trough the message bus you must wait an amount of time for another message that is a response for the sent message. The amateur way of implementing this would look like:
 Message lastMessage = null;  
 void sendMessage(Message messageToSend){  
   messageToSend.send();  
   while(!timeout()){  
    if(lastMessage != null){  
     reponseReceived(lastMessage);  
     lastMessage = null;  
    }  
    try{Thread.sleep(sleepTime);}catch(Exception e){}  
   }   
 }  
 //The message bus listener code, this is not that relevant  
 //We can just assume that this method is called from other thread.  
 void messageFoundInBus(Message responseMessage){  
  lastMessage = responseMessage;  
 }  
This code works but have two main problems. First, this is not efficient because sleepTime will put the Thread to sleep for a fixed amount of time. E.g. If you have 10 seconds in this constant the worst scenario is receiving the Message just after start sleeping making the Thread wait 9.x seconds to be aware of the response even if the message arrived long time ago. You could say, just use a smaller value but that could cause a different problem because if the sleep time is to short or you even decide to not put the Thread.sleep you could face starvation. The second problem is that while you are sleeping you could get a second message and override your response. There's no locking code. You could just include some synchronized sentences but you could forget it just because you are not forced to synchronize anything. If you use notify and wait you will be forced to synchronize this code avoiding this kind of problems from the beggining. Here's a second aproach using notify and synchronize:
 Message lastMessage = null;  
 final Object responseMonitor = new Object();  
 void sendMessage(Message messageToSend){  
   try{  
    messageToSend.send();    
    if(lastMessage != null){  
     synchronized (responseMonitor) {  
       responseMonitor.wait(timeout);
     }     
    }  
    if(lastMessage != null){  
     reponseReceived(lastMessage);  
     lastMessage = null;  
    }  
   }catch(Exception e){}  
 }  
 //The message bus listener code, this is not that relevant  
 //We can just assume that this method is called from other thread.  
 Message lastMessage = null;  
 void messageFoundInBus(Message responseMessage){  
  synchronized (responseMonitor) {  
   lastMessage = responseMessage;  
   responseMonitor.notify()  
  }  
 }  
The solution that I present is not an absolute rule, there are a lot of reasons not related to wait for a resource that could bring you to need a loop with a sleep inside, but almost every time you should be able to find a better way in order to avoid this kind of code.

martes, 11 de enero de 2011

Integrating liquibase in your java code

In modern software developing, versioning your source code is a most do and you can easilly find robust opensource and privative solutions to mantain a healthy versioned code. In the other hand, most developers agreed that versioning the changes made in your data model is as important than versioning your source code, but the tools available to do this task are not as extended and documented as the first ones.

In most projects that I have had the opportunity to participate the usual way to version the database is creating SQL scripts and run them in a progresive way. This does the job but have some drawbacks, for example:

1 If you use an ORM for the persistence of your project then you must write the versioning scripts for all the different database providers that you want to support.
2 If you need rollback functionallity then you must mantain two scripts.
3 If you have different branches in your projects merging changes can be a tiring process.
4. You must write plumbing code for versioning in your project. The old reinventing the wheel problem.

We decided to try Liquibase, an interesting database versioning tool that solves most the problems presented, mantaining the changes of your database in an "engine independent" way and supports rollbacks, diffs and tagging. We are not explaining how to use this tool here because the official documentation that you can find in liquibase.com is really good, what we will be explaining here is something that we couldn't find in the official documentation and this is including the liquibase library directly in you java code and use this as an API.

Liquibase was intended to be used via command line, ANT scripts and maven. In our case this wasn't enough and we wanted to be able the call and use the liquibase services directly in our java code to have the flexibility to do runtime updates in our own project. We tried to access directly the Liquibase object with no luck, we experimented many exceptions and hard times because the source code of liquibase is not documented as we would like, so the final desition was using the command line integration class.

First you need to download liquibase 2.0 and the jdbc connector for your database and include them in your project libraries. Next you need to extend from the class liquibase.integration.commandLine.Main (yes this is really ugly, we will still searching a better way).



public class DatabaseVersioningService extends liquibase.integration.commandline.Main implements DatabaseVersioningServiceLocal {
private static final String DATABASENAME_CHANGELOG_PARAM = "DATABASENAME";
private static final String CHANGELOG_PATH = "changeLogs/changelog_master.xml";
private static final String MYSQL_CLASS_DRIVER = "com.mysql.jdbc.Driver";
private static final String UPDATE_COMMAND = "update";

public void updateToHEAD(String dbUser, String dbPassword) {
try {
setMigrationParameters(dbUser, dbPassword);
applyDefaults();
configureClassLoader();
doMigration();
} catch (Throwable ex) {
ex.printStackTrace();
}
}

private void setMigrationParameters(String dbUser, String dbPassword, String command) throws URISyntaxException, SQLException {
changeLogFile = getClass().getResource(CHANGELOG_PATH).getPath();
username = dbUser;
password = dbPassword;
driver = MYSQL_CLASS_DRIVER;
url = new URI(padposDataSource.getConnection().getMetaData().getURL());
command = command;
}
}



Like you can see in the sample code is really simple but figure out this from the liquibase source code wasn't that easy, so we hope this can help someone else that wants to integrate liquibase directly in code. We will be studying liquibase code and maybe we will be writting a service tier to make this in a cleaner and elgant way.

viernes, 22 de octubre de 2010

Cannot navigate association field [field] in the SET clause target TOPLINK

We migrated an application from Hibernate to TopLink with almost no efford, having an standard pesistence layer is awesome! Anyway some querys after the migration wasn't working and we were getting
'cannot navigate association field [field] in the SET clause target exceptions'. This happends because TopLink is a little more strict about your Entity Relations.

Example:

You have an entity School that includes an entity adress, and in the same way the adress is identified using an integer adressID.

School Entity


@Entity
class School{
@ID
private int schoolID;
@OneToOne
private Address address;
}



@Entity
class Address{
@ID
private int addressID;
}


If you create this query:

UPDATE School s SET s.address.adressID = :anAddressID

Hibernate will not complain but Toplink will fail. In toplink is mandatory to use the entity object instead the attributes of the entity: The correct query in toplink is:

UPDATE School s SET s.address = :anAddress

In my opinion is better using the entity object and not the ids 'cause you are taking advantage of the object abstraction provided by the persistence provider.

miércoles, 20 de octubre de 2010

Bypass the browser sandbox with a Java Applet

This is an aproach we followed some months ago to bypass the browser sandbox and to be honest this solution (for our porpouses) was simply terrific. We want to share it because there's not a lot of documentation in the net about communicating your applet, browser and OS.

First a brief about how browsers "sandbox" work. All the browsers (at least the secure ones) have a tier that is called the "sand box", this "sand box" prevents executing harmfull code in a webpage, for example, this denies any operation in ports, hard drive, monitor, sound card, etc. This "sand box" is an important safe in all browsers because no one wants to enter a webpage and allow some nasty code to format our harddrive, but in the same way this limits the posibilities of the developers of writing code that interacts with the hardware of the user.

Our requirement was reading a string displayed in a webpage and when the user clicks a button send the string via serial COM. The possible approaches that we figured out are:

1. Using an ActiveX Control:

Pros:

There's already a control that does this work.

Cons:

This code will work only in Internet Explorer.
This is a payed solution.
Theres no security control in ActiveX.
We hate ActiveX!

2. Use an stand alone application and comunicate with the browser using a common database.

Pros:

Easy to implement. We know how to comunicate a web page using php,jsp,etc to a database and we know how to communicate a stand alone to a database.
Is free.
Crossplatform.

Cons:

You will have three diferent systems to mantain. A common and accesible database, some server pages and a stand alone.
You will have to provide a lot of configuration information to your customer. A database conection, how to install your standalone, etc.
You will need to implement a polling algorithm in the standalone that reads every X time the database for changes. This is really really nasty.

3. Using a Java Applet!

Pros:

You can embed the applet in the page and the user does not have to install anything. When he enters the page the applet installs automatically.
The applet can be signed to provide a high level of security.
You only need to mantain one component, the Applet!
Crossplatform.
Is free.

Cons:

Lately the people is stopping using applets. The applet boom has passed and now is really strange to find new implementations using this technology.
You need to install the JRE in the client terminal.

Extra

4. Using Google native code HTML5 libraries. This is really an extra because is not ready for production.

So whats the deal? Well, you need to write an applet that sends data to the serial COM (or that sends music to your sound card, or that erase completly the harddrive, etc....). This is easy well documented, we used RXTX java library without problems. Next you need to paste it in your webpage and using javascript read the required information from the HTML controls.

Let's see a practical examples.

WebPage example code:

We can achieve the goal of communicate javascript code with the applet code to send the string characters to the COM port. To do that we need to put this code in our HTML document:



<script src="http://www.java.com/js/deployJava.js"></script>
<script>
var parameter = "Some data you want to pass to applet at init time";
var attributes = { id: 'app', MAYSCRIPT: 'true', code:'<full qualified name of the applet class ie. mx.ssf.project.MyApplet.class>', archive:'<path to look at for the .jat file>', width:430, height:490} ;
var parameters = {nameOfParameterOnTheApplet: parameter} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>

Ok, let's try to explain what's going on in the above sniped of code.

The line

<script src="http://www.java.com/js/deployJava.js"></script>

imports a tiny javascript library file, the deployJava.js. This library contains all the code needed to integrate and deploy the applet in the web page that you want. This is a very comfortable
way to deploy the applet, you only need add this file and call the corresponding methods or functions that the library gives you, and it's done. If you look well, the file is on the Java.com site
so you don't need to download it.

Next, the block of code:

<script>
var parameter = "Some data you want to pass to applet at init time";
var attributes = { id: 'app', MAYSCRIPT: 'true', code:'<full qualified name of the applet class ie. mx.ssf.project.MyApplet.class>', archive:'<path to look at for the .jat file>', width:430, height:490} ;
var parameters = {nameOfParameterOnTheApplet: parameter} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>

Determines the way the Applet will be deployed. The first line declare a local javascript variable that we can use to send some data to the applet from the beginning like a parameter.

In the next line, we declare the attributes for the applet. For example, the id of the applet that can referenced through the javascript script, the full qualified name for the class
of the applet and the path for the .jar file that contains the bytecode to tell the Java plugin where to find that class. It's important to notice the attribute "MAYSCRIPT: true",
this attribute it's the responsible for the communication between javascript and the applet, if this attribute is not declared, such communication can't exists.

The next line, defines an array of parameters to be passed to the applet. Notice that we use the javascript variable (var parameter) in this array declaration. It's imperative that we declare
a parameter name to be used inside the applet. In this exameple that name is "nameOfParameterOnTheApplet".

At the end, we simply call the runApplet function that it's declared in the deployJava.js file passing the attributes and parameters arrays and the version of the java run time environment that we want to use to launch the Java Applet.

This demostrates how easy it's the implementation and deployment of a java applet.


Calling to an Applet method from JavaScript.

Now, I'm going to show how to call to an applet method from a javascript scrip using the example above.

Suppose that we want to send to the COM port some string that is calculated in some maner in the HTML page. To acomplish this, first it's needed a javascript function like this:


<script language="javascript">
function reimprimir(){
var ticket = document.forms[0].ticketArea.value;
var applet = document.getElementById('app');
applet.print(ticket);
}
</script>


This function can be called from a javascript event taking the value of a text area control of the form. The reference to the applet is obtained via getElementById function using the id defined as an attribute of the applet like showed earlier in this example. Once we have the reference to the applet, we simply call the applet method like
if we were programming in the java language. The applet method "print" it's defined to receive a String value, that value is the string we have in the text area component of the form. When
the applet method it's called, the logic it's executed as expected.

Applet Code:

There is nothing especial in the applet code. It can do everything that is allowed by the Java Run Time Enviroment policy. Only one thing it's required to skip the browser sandbox. We need to sign the resulting
.jar file to the client browser can trust in our application.To do that, we need to do the following:

In a command line console, perform:

$ keytool -genkey -alias


Remember, the alias name can be anything you want :)

$ jarsigner -keystore -storepass -keypass


The alias-name is the same that we used in the earlier. The .keystore file usually is created in the "home" directory. (We assume a Linux operating system).

With that done, the only step left is include the signed jar file in the Web application project to start using it.

When the user enters your web page a popup will request the JRE plugin installation in an automated way, after that the applet will load and will ask the user for permission (this permission can be permanent based in the virtual machine configuration) and finally the displayed information in the page will start flowing via COM port. Sweet.

lunes, 16 de agosto de 2010

Some thoughts about byte data types in Java and C#

We developed a simple communication application between JME and C# using sockets. We send some ASCII data from a C# to a java midlet, this data can contain printable ASCII (from 0 to 128) and non printable ASCII (from 129 to 255).

Everything was working smooth until we had to extract some bytes from the frame in the java midlet and compare them to non printable ASCII. Example:


byte x =byte[30]; //This position contains a non printable Happy Face ASCII

if(x == 254){
//This condition never is true
}


This happen because the java byte is signed, this means that this goes from -127 to 128, in the other hand c# byte is non-signed (from 0 to 255). Our first aproach was to convert all the byte arrays in java to short arrays adding 256 to negative ones, but thats not really necesary.

The rule is easy, it doesn't matter what operation you are doing over the signed byte, adding, substracting, multiplying, etc, always the result will be the same even if it is signed or unsigned. Why? The sign is in your mind! The sign is no more than an interpretation. But what happend when you want to compare this values or print them? In that case this will not work because casting a negative byte to char in java is not the same as deleting the sign.

Another example:


char x = (char)-1;

//x is not 255.


Whats the correct way to proceed?

Easy, you need to add, substract, multiply, etc signed or unsigned bytes? Don't worry do it, it will work always and even if this is signed or unsigned you will get exactly the same result. You need to compare the chars obtained? Delete the sign of the signed byte usign this line:


byte x = -1;
char y = (char)(x & 0xFF)


Sweet..