Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Wednesday 10 June 2015

Top Ten Things Every Java Programmer Should Know

These are in no particular order, but these are things that all Java programmers should probably know.
  1. Who Invented Java, and when?
    James Gosling, at Sun Labs, around 1992; the group was building a set-top box and started by "cleaning up" C++ and wound up with a new language and runtime. 
  2. What does Java stand for?
    Java is not an acronym (not even Just Another Vague Acronym :-)). The language was first named Oak, after the tree outside James' window. The lawyers found a computer company called Oak so, legend has it, the gang went out to the local cafe to discuss names and wound up naming it Java; the "0xCafeBabe" magic number in the class files was named after the Cafe where the Java team used to go for coffee.
  3. What is the JLS?
    JLS is The Java Language Specification. Every developer should buy or download (free) this specification and read it, a bit at a time.
  4. How do changes get into Java? JCP (Java Community Process).
  5. Why is there no printf-like function in Java?
    Actually there are! This was fixed in Java 5; see Java Cookbook (2nd Edition) Chapter 9. Java 5 (J2SE 1.5) includes printf (and scanf), String.format(), and lots more.
  6. What is the GOF book?
    The Gang Of Four book is entitled Design Patterns, by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides. This is a very good book. You should read it. Not when you're just learning Java, but when you've let it sink in for about six months.
  7. What other Java book do I need?
  8. What is the Java Cookbook?
    That's my own book of Java recipes (for the programming language, not the coffee, but some bookstores still wind up listing it under Cooking).
  9. What other Java sites do I need to know about?
  10. What else do I need to know? Everything! But nobody can know everything about Java - the subject is now too vast. Imagine somebody saying that they know everything about every single Microsoft product and technology. If someone like that calls me, I'm always out.

Wednesday 22 April 2015

Understanding Java Garbage Collection

What are the benefits of knowing how garbage collection (GC) works in Java? Satisfying the intellectual curiosity as a software engineer would be a valid cause, but also, understanding how GC works can help you write much better Java applications.

This is a very personal and subjective opinion of mine, but I believe that a person well versed in GC tends to be a better Java developer. If you are interested in the GC process, that means you have experience in developing applications of certain size. If you have thought carefully about choosing the right GC algorithm, that means you completely understand the features of the application you have developed. Of course, this may not be common standards for a good developer. However, few would object when I say that understanding GC is a requirement for being a great Java developer. 

This is the first of a series of "Become a Java GC Expert" articles. I will cover the GC introduction this time, and in the next article, I will talk about analyzing GC status and GC tuning examples from NHN.

The purpose of this article is to introduce GC to you in an easy way. I hope this article proves to be very helpful. Actually, my colleagues have already published a few great articles on Java Internals which became quite popular on Twitter. You may refer to them as well.
Returning back to Garbage Collection, there is a term that you should know before learning about GC. The term is "stop-the-world." Stop-the-world will occur no matter which GC algorithm you choose. Stop-the-world means that the JVM is stopping the application from running to execute a GC. When stop-the-world occurs, every thread except for the threads needed for the GC will stop their tasks. The interrupted tasks will resume only after the GC task has completed. GC tuning often means reducing this stop-the-world time.

Generational Garbage Collection 

Java does not explicitly specify a memory and remove it in the program code. Some people sets the relevant object to null or use System.gc() method to remove the memory explicitly. Setting it to null is not a big deal, but calling System.gc() method will affect the system performance drastically, and must not be carried out. (Thankfully, I have not yet seen any developer in NHN calling this method.)
In Java, as the developer does not explicitly remove the memory in the program code, the garbage collector finds the unnecessary (garbage) objects and removes them. This garbage collector was created based on the following two hypotheses. (It is more correct to call them suppositions or preconditions, rather than hypotheses.) 
  • Most objects soon become unreachable.
  • References from old objects to young objects only exist in small numbers.
These hypotheses are called the weak generational hypothesis. So in order to preserve the strengths of this hypothesis, it is physically divided into two - young generation and old generation - in HotSpot VM.

Young generation: Most of the newly created objects are located here. Since most objects soon become unreachable, many objects are created in the young generation, then disappear. When objects disappear from this area, we say a "minor GC" has occurred. 

Old generation: The objects that did not become unreachable and survived from the young generation are copied here. It is generally larger than the young generation. As it is bigger in size, the GC occurs less frequently than in the young generation. When objects disappear from the old generation, we say a "major GC" (or a "full GC") has occurred. 
Let's look at this in a chart.
Figure 1: GC Area & Data Flow.
Figure 1: GC Area & Data Flow.
The permanent generation from the chart above is also called the "method area," and it stores classes or interned character strings. So, this area is definitely not for objects that survived from the old generation to stay permanently. A GC may occur in this area. The GC that took place here is still counted as a major GC. 
Some people may wonder:
What if an object in the old generation need to reference an object in the young generation?
To handle these cases, there is something called the a "card table" in the old generation, which is a 512 byte chunk. Whenever an object in the old generation references an object in the young generation, it is recorded in this table. When a GC is executed for the young generation, only this card table is searched to determine whether or not it is subject for GC, instead of checking the reference of all the objects in the old generation. This card table is managed with write barrier. This write barrier is a device that allows a faster performance for minor GC. Though a bit of overhead occurs because of this, the overall GC time is reduced. 
Figure 2: Card Table Structure.
Figure 2: Card Table Structure.

Composition of the Young Generation

In order to understand GC, let's learn about the young generation, where the objects are created for the first time. The young generation is divided into 3 spaces. 
  • One Eden space
  • Two Survivor spaces
There are 3 spaces in total, two of which are Survivor spaces. The order of execution process of each space is as below:
  1. The majority of newly created objects are located in the Eden space.
  2. After one GC in the Eden space, the surviving objects are moved to one of the Survivor spaces. 
  3. After a GC in the Eden space, the objects are piled up into the Survivor space, where other surviving objects already exist.
  4. Once a Survivor space is full, surviving objects are moved to the other Survivor space. Then, the Survivor space that is full will be changed to a state where there is no data at all.
  5. The objects that survived these steps that have been repeated a number of times are moved to the old generation.
As you can see by checking these steps, one of the Survivor spaces must remain empty. If data exists in both Survivor spaces, or the usage is 0 for both spaces, then take that as a sign that something is wrong with your system.
The process of data piling up into the old generation through minor GCs can be shown as in the below chart:
Figure 3: Before & After a GC.
Figure 3: Before & After a GC.

Note that in HotSpot VM, two techniques are used for faster memory allocations. One is called "bump-the-pointer," and the other is called "TLABs (Thread-Local Allocation Buffers)." 
Bump-the-pointer technique tracks the last object allocated to the Eden space. That object will be located on top of the Eden space. And if there is an object created afterwards, it checks only if the size of the object is suitable for the Eden space. If the said object seems right, it will be placed in the Eden space, and the new object goes on top. 

So, when new objects are created, only the lastly added object needs to be checked, which allows much faster memory allocations. However, it is a different story if we consider a multithreaded environment. To save objects used by multiple threads in the Eden space for Thread-Safe, an inevitable lock will occur and the performance will drop due to the lock-contention. TLABs is the solution to this problem in HotSpot VM. 

This allows each thread to have a small portion of its Eden space that corresponds to its own share. As each thread can only access to their own TLAB, even the bump-the-pointer technique will allow memory allocations without a lock. 

This has been a quick overview of the GC in the young generation. You do not necessarily have to remember the two techniques that I have just mentioned. You will not go to jail for not knowing them. But please remember that after the objects are first created in the Eden space, and the long-surviving objects are moved to the old generation through the Survivor space.

GC for the Old Generation

The old generation basically performs a GC when the data is full. The execution procedure varies by the GC type, so it would be easier to understand if you know different types of GC. 
According to JDK 7, there are 5 GC types. 
  1. Serial GC
  2. Parallel GC
  3. Parallel Old GC (Parallel Compacting GC)
  4. Concurrent Mark & Sweep GC  (or "CMS")
  5. Garbage First (G1) GC
Among these, the serial GC must not be used on an operating server. This GC type was created when there was only one CPU core on desktop computers. Using this serial GC will drop the application performance significantly. 
Now let's learn about each GC type.

Serial GC (-XX:+UseSerialGC)

The GC in the young generation uses the type we explained in the previous paragraph. The GC in the old generation uses an algorithm called "mark-sweep-compact."
  1. The first step of this algorithm is to mark the surviving objects in the old generation.
  2. Then, it checks the heap from the front and leaves only the surviving ones behind (sweep).
  3. In the last step, it fills up the heap from the front with the objects so that the objects are piled up consecutively, and divides the heap into two parts: one with objects and one without objects (compact).
The serial GC is suitable for a small memory and a small number of CPU cores.

Parallel GC (-XX:+UseParallelGC)

Figure 4: Difference between the Serial GC and Parallel GC.
Figure 4: Difference between the Serial GC and Parallel GC.
From the picture, you can easily see the difference between the serial GC and parallel GC. While the serial GC uses only one thread to process a GC, the parallel GC uses several threads to process a GC, and therefore, faster. This GC is useful when there is enough memory and a large number of cores. It is also called the "throughput GC." 

Parallel Old GC(-XX:+UseParallelOldGC)

Parallel Old GC was supported since JDK 5 update. Compared to the parallel GC, the only difference is the GC algorithm for the old generation. It goes through three steps: mark – summary – compaction. The summary step identifies the surviving objects separately for the areas that the GC have previously performed, and thus different from the sweep step of the mark-sweep-compact algorithm. It goes through a little more complicated steps.

CMS GC (-XX:+UseConcMarkSweepGC)

Figure 5: Serial GC & CMS GC.
Figure 5: Serial GC & CMS GC.
As you can see from the picture, the Concurrent Mark-Sweep GC is much more complicated than any other GC types that I have explained so far. The early initial mark step is simple. The surviving objects among the objects the closest to the classloader are searched. So, the pausing time is very short. In the concurrent mark step, the objects referenced by the surviving objects that have just been confirmed are tracked and checked. The difference of this step is that it proceeds while other threads are processed at the same time. In the remark step, the objects that were newly added or stopped being referenced in the concurrent mark step are checked. Lastly, in the concurrent sweep step, the garbage collection procedure takes place. The garbage collection is carried out while other threads are still being processed. Since this GC type is performed in this manner, the pausing time for GC is very short. The CMS GC is also called the low latency GC, and is used when the response time from all applications is crucial
While this GC type has the advantage of short stop-the-world time, it also has the following disadvantages.
  • It uses more memory and CPU than other GC types.
  • The compaction step is not provided by default.
You need to carefully review before using this type. Also, if the compaction task needs to be carried out because of the many memory fragments, the stop-the-world time can be longer than any other GC types. You need to check how often and how long the compaction task is carried out.

G1 GC

Finally, let's learn about the garbage first (G1) GC. 
Figure 6: Layout of G1 GC.
Figure 6: Layout of G1 GC.
If you want to understand G1 GC, forget everything you know about the young generation and the old generation. As you can see in the picture, one object is allocated to each grid, and then a GC is executed. Then, once one area is full, the objects are allocated to another area, and then a GC is executed. The steps where the data moves from the three spaces of the young generation to the old generation cannot be found in this GC type. This type was created to replace the CMS GC, which has causes a lot of issues and complaints in the long term.
The biggest advantage of the G1 GC is its performance. It is faster than any other GC types that we have discussed so far. But in JDK 6, this is called an early access and can be used only for a test. It is officially included in JDK 7. In my personal opinion, we need to go through a long test period (at least 1 year) before NHN can use JDK7 in actual services, so you probably should wait a while. Also, I heard a few times that a JVM crash occurred after applying the G1 in JDK 6. Please wait until it is more stable.
I will talk about the GC tuning in the next issue, but I would like to ask you one thing in advance. If the size and the type of all objects created in the application are identical, all the GC options for WAS used in our company can be the same. But the size and the lifespan of the objects created by WAS vary depending on the service, and the type of equipment varies as well. In other words, just because a certain service uses the GC option "A," it does not mean that the same option will bring the best results for a different service. It is necessary to find the best values for the WAS threads, WAS instances for each equipment and each GC option by constant tuning and monitoring. This did not come from my personal experience, but from the discussion of the engineers making Oracle JVM for JavaOne 2010.
In this issue, we have only glanced at the GC for Java. Please look forward to our next issue, where I will talk about how to monitor the Java GC status and tune GC
I would like to note that I referred to a new book released in December 2011 called "Java Performance" (Amazon, it can also be viewed from safari online, if the company provides an account), as well as “Memory Management in the Java HotSpotTM Virtual Machine,” a white paper provided by the Oracle website. (The book is different from "Java Performance Tuning.")
By Sangmin Lee, Senior Engineer at Performance Engineering Lab, NHN Corporation.

Tuesday 8 July 2014

How to print all the Java system properties

The other day, when I was trying to compile all the Tame Swing examples, I had a problem running one of the examples. The problem was that I was running the example in Eclipse, and I was getting an error message showing the Eclipse (the JVM really) couldn't find the icon image files.

I thought I had everything configured properly, but still I kept getting the same error message. Finally I decided to look at my Java system properties and see what my build path really looked like. I couldn't think of the right Java property to show the build path, so instead of trying to print just the one Java property, I decided to print all the Java properties, then dig through them manually. You print Java system properties with the System.getProperties() method.

Here's the code I used to print all the Java system properties:

Properties p = System.getProperties();
Enumeration keys = p.keys();
while (keys.hasMoreElements()) {
  String key = (String)keys.nextElement();
  String value = (String)p.get(key);
  System.out.println(key + ": " + value);
}
And here's the output from that section of code:
java.runtime.name: Java(TM) 2 Runtime Environment, Standard Edition
sun.boot.library.path: /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Libraries
java.vm.version: 1.5.0_07-87
awt.nativeDoubleBuffering: true
gopherProxySet: false
java.vm.vendor: "Apple Computer, Inc."
java.vendor.url: http://apple.com/
path.separator: :
java.vm.name: Java HotSpot(TM) Client VM
file.encoding.pkg: sun.io
user.country: US
sun.os.patch.level: unknown
java.vm.specification.name: Java Virtual Machine Specification
user.dir: /Users/al/DD/Projects/TameSwing
java.runtime.version: 1.5.0_07-164
java.awt.graphicsenv: apple.awt.CGraphicsEnvironment
java.endorsed.dirs: /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/lib/endorsed
os.arch: i386
java.io.tmpdir: /tmp
line.separator: 

java.vm.specification.vendor: Sun Microsystems Inc.
os.name: Mac OS X
sun.jnu.encoding: MacRoman
java.library.path: .:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
java.specification.name: Java Platform API Specification
java.class.version: 49.0
sun.management.compiler: HotSpot Client Compiler
os.version: 10.4.10
user.home: /Users/al
user.timezone: 
java.awt.printerjob: apple.awt.CPrinterJob
file.encoding: MacRoman
java.specification.version: 1.5
java.class.path: /Users/al/DD/Projects/TameSwing/bin:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/.compatibility/14compatibility.jar
user.name: al
apple.awt.graphics.UseQuartz: true
java.vm.specification.version: 1.0
java.home: /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home
sun.arch.data.model: 32
user.language: en
java.specification.vendor: Sun Microsystems Inc.
awt.toolkit: apple.awt.CToolkit
java.vm.info: mixed mode, sharing
java.version: 1.5.0_07
java.ext.dirs: /Library/Java/Extensions:/System/Library/Java/Extensions:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/lib/ext
sun.boot.class.path: /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/classes.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/ui.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/laf.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/sunrsasign.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/jsse.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/jce.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/charsets.jar
java.vendor: Apple Computer, Inc.
file.separator: /
java.vendor.url.bug: http://developer.apple.com/java/
sun.io.unicode.encoding: UnicodeLittle
sun.cpu.endian: little
mrj.version: 1040.1.5.0_07-164
sun.awt.exception.handler: apple.awt.CToolkit$EventQueueExceptionHandler
sun.cpu.isalist:

Monday 27 January 2014

ZIP and UNZIP with Passwords in Java

Zip and Unzip are a very common activities for a computer user. A user normally uses the zip utility to compress a directory to create a zip file. There are many ready-made software such as winzip,7zip, and winrar that are available to achieve this. 

However, it is also possible to protect the zip file with a password so that the end user has to provide the password to unzip the zip file. This is the very common scenario that can be achieved by a zip utility tool. The significant part of my article is to provide you with the solution to achieve this using a Java program. While developing the project you may encounter a scenario in which you have to create a password-protected zip file that can be unzipped by any zip tool like winzip. Let me provide a complete scenario for your understanding.

In a system, some files are generated for a user and all the files are zipped with a password. The generated password protected zip file is sent to the user through email and the password for the zip file to open is sent to the particular user as an SMS to the user's mobile. 

 Similarly the end-user creates a password protected zip file and uploads to a online system with the user's password in a text field. In this case we have to develop a system where the system will be able to create a password protected zip file and should be able to extract all the files from a password protected zip file. Let me show you how you can achieve it.

Technicalities
However, Java provides the feature of creating a zip file and also provides the feature to unzip or decompress a zip file. But there is no default java API to create a password protected zip file and also there is no default java API to unzip a password protected zip file. To facilitate this feature of zip utility some developers have developed java API in this regard. We have to use their API to achieve this. We have to look into the following aspects of zip utility.
  1. Java-enabled system should be able to generate a password protected zip file and that password protected zip file can be unzipped by any zip utility like winzip and others
  2. Java-enabled system should be able to decompress or unzip a password protected zip file created by any zip utility like winzip and others.
The followings are the APIs you have to use for this objective:

1.To create a password protected zip file in java, you have to use “winzipaes”. It is avilable in Google code. You can download the .jar file and the source code from the following link.

This API helps to add a password to a already created zip file. It means that if you want to create a password protected zip file, first you have to create a zip file and then you can add a password that zip file. It is a pure java API works with any operating system. You have to download the following jar file from the above URL.

passwordcompressor.jar

2.To unzip or decompress a password protected zip file, you have to use “sevenzipjbind”. It is available in sourceforge.net site. You can download the .jar files from the following link: http://sourceforge.net/projects/sevenzipjbind/files/. This API helps to extract all the files and folders from password protected zip file created by any zip utility tool. You have to download the following .jar files from the above URL.
sevenzipjbinding-AllPlatforms.jar
sevenzipjbinding.jar

3.For password protection, you have to use Bouncecastle cryptographic API. You can download the .jar file from the following link.
http://www.bouncycastle.org/
You have to download the following .jar files from the above URL.
bcprov-jdk15-145.jar

After downloading all the .jar files, put all the .jar files in your classpath. I have written a java program by using all these APIs to achieve all the above mentioned functionalities.
Have a look at the following code structure.

Code for ZipUtil.java


Tuesday 3 December 2013

Get and set pixels on a Buffered Image


In this tutorial we are going to show you how to set and get the RGB value of each pixel of a Buffered Image. This is particularly useful when you want to perform several operation on images based on the RGB values of each individual image. Or if you want your UI to interact in some way according to the values of the pixel that the user points to.
In short in order to flip an image one should take the following steps:
  • Load an image from a source usingToolkit.getDefaultToolkit().getImage method
  • Use an ImageObserver to monitor the loading of the image. When the image is fully load the user will be notified
  • Create a buffed image from the source image with a format more close to the custom display environment using GraphicsEnvironmentGraphicsDevice and GraphicsConfiguration to perform several image configurations
  • Use Image.getRGB(x,y) to get the RGB value of a specific pixel and Image.setRGB(x, y, rgbValue) to set the RGB value of the pixel.
  • And simply paint the buffered image in a new Frame
Let’s take a look at the code snippet that follows


package com.myDrea,.snippets.desktop;

import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;

public class BufferedImagePixels {

  static boolean imageLoaded = false;

  public static void main(String[] args) {

// The ImageObserver implementation to observe loading of the image

ImageObserver myImageObserver = new ImageObserver() {

  public boolean imageUpdate(Image image, int flags, int x, int y, int width, int height) {

    if ((flags & ALLBITS) != 0) {

imageLoaded = true;

System.out.println("Image loading finished!");

return false;

    }

    return true;

  }

};

// The image URL - change to where your image file is located!

String imageURL = "image.png";

/**

 * This call returns immediately and pixels are loaded in the background

 * We use an ImageObserver to be notified when the loading of the image

 * is complete

 */

Image sourceImage = Toolkit.getDefaultToolkit().getImage(imageURL);

sourceImage.getWidth(myImageObserver);

// We wait until the image is fully loaded

while (!imageLoaded) {

    try {

  Thread.sleep(100);

    } catch (InterruptedException e) {

    }

}

// Create a buffered image from the source image with a format that's compatible with the screen

GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();

GraphicsDevice graphicsDevice = graphicsEnvironment.getDefaultScreenDevice();

GraphicsConfiguration graphicsConfiguration = graphicsDevice.getDefaultConfiguration();

// If the source image has no alpha info use Transparency.OPAQUE instead

BufferedImage image = graphicsConfiguration.createCompatibleImage(sourceImage.getWidth(null), sourceImage.getHeight(null), Transparency.BITMASK);

// Copy image to buffered image

Graphics2D graphics = image.createGraphics();

// Paint the image onto the buffered image

graphics.drawImage(sourceImage, 0, 0, null);

graphics.dispose();

int x = 10;

int y = 10;

// Get a pixel

int rgb = image.getRGB(x, y);

System.out.println("Pixel at [" + x + "," + y + "] RGB : " + rgb);

// Get all the pixels

int w = image.getWidth(null);

int h = image.getHeight(null);

int[] rgbs = new int[w*h];

image.getRGB(0, 0, w, h, rgbs, 0, w);

// Set a pixel

rgb = 0xFF00FF00; // green

image.setRGB(x, y, rgb);

  }

}

Tuesday 10 September 2013

Java Bean

A JavaBean is a specially constructed Java class written in the Java and coded according to the JavaBeans API specifications.
Following are the unique characteristics that distinguish a JavaBean from other Java classes:
  • It provides a default, no-argument constructor.
  • It should be serializable and implement the Serializable interface.
  • It may have a number of properties which can be read or written.
  • It may have a number of "getter" and "setter" methods for the properties.

JavaBeans Properties:

A JavaBean property is a named attribute that can be accessed by the user of the object. The attribute can be of any Java data type, including classes that you define.
A JavaBean property may be read, write, read only, or write only. JavaBean properties are accessed through two methods in the JavaBean's implementation class:
MethodDescription
getPropertyName()For example, if property name is firstName, your method name would be getFirstName() to read that property. This method is called accessor.
setPropertyName()For example, if property name is firstName, your method name would be setFirstName() to write that property. This method is called mutator.
A read-only attribute will have only a getPropertyName() method, and a write-only attribute will have only a setPropertyName() method.

JavaBeans Example:

Consider a student class with few properties:
package com.tutorialspoint;

public class StudentsBean implements java.io.Serializable
{
private String firstName = null;
private String lastName = null;
private int age = 0;

public StudentsBean() {
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public int getAge(){
return age;
}
public void setFirstName(String firstName){
this.firstName = firstName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
public void setAge(Integer age){
this.age = age;
}
}

Accessing JavaBeans:

The useBean action declares a JavaBean for use in a JSP. Once declared, the bean becomes a scripting variable that can be accessed by both scripting elements and other custom tags used in the JSP. The full syntax for the useBean tag is as follows:
<jsp:useBean id="bean's name" scope="bean's scope" typeSpec/>
Here values for the scope attribute could be page, request, session or application based on your requirement. The value of the id attribute may be any value as a long as it is a unique name among other useBean declarations in the same JSP.
Following example shows its simple usage:
<html>
<head>
<title>useBean Example</title>
</head>
<body>

<jsp:useBean id="date" class="java.util.Date" />
<p>The date/time is <%= date %>

</body>
</html>
This would produce following result:
The date/time is Thu Sep 30 11:18:11 GST 2010 

Accessing JavaBeans Properties:

Along with <jsp:useBean...>, you can use <jsp:getProperty/> action to access get methods and <jsp:setProperty/> action to access set methods. Here is the full syntax:
<jsp:useBean id="id" class="bean's class" scope="bean's scope">
<jsp:setProperty name="bean's id" property="property name"
value="value"/>
<jsp:getProperty name="bean's id" property="property name"/>
...........
</jsp:useBean>
The name attribute references the id of a JavaBean previously introduced to the JSP by the useBean action. The property attribute is the name of the get or set methods that should be invoked.
Following is a simple example to access the data using above syntax:
<html>
<head>
<title>get and set properties Example</title>
</head>
<body>

<jsp:useBean id="students"
class="com.tutorialspoint.StudentsBean">
<jsp:setProperty name="students" property="firstName"
value="Zara"/>
<jsp:setProperty name="students" property="lastName"
value="Ali"/>
<jsp:setProperty name="students" property="age"
value="10"/>
</jsp:useBean>

<p>Student First Name:
<jsp:getProperty name="students" property="firstName"/>
</p>
<p>Student Last Name:
<jsp:getProperty name="students" property="lastName"/>
</p>
<p>Student Age:
<jsp:getProperty name="students" property="age"/>
</p>

</body>
</html>
Let us make StudentsBean.class available in CLASSPATH and try to access above JSP. This would produce following result:
Student First Name: Zara 

Student Last Name: Ali

Student Age: 10

Monday 9 September 2013

JAVA: Hypnosis Animation

Hypnosis animation
Hypnosis animation

package jay;

/**
 *
 * @author jay.thakkar
 */
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.GeneralPath;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class Hypnosis1 extends JComponent implements Runnable {

    private int[] coordinates;
    private int[] deltas;
    private Paint paint;

    public Hypnosis1(int numberOfSegments) {
        int numberOfCoordinates = numberOfSegments * 4 + 2;
        coordinates = new int[numberOfCoordinates];
        deltas = new int[numberOfCoordinates];
        for (int i = 0; i < numberOfCoordinates; i++) {
            coordinates[i] = (int) (Math.random() * 300);
            deltas[i] = (int) (Math.random() * 4 + 3);
            if (deltas[i] > 4) {
                deltas[i] = -(deltas[i] - 3);
            }
        }
        paint = new GradientPaint(0, 0, Color.blue, 20, 10, Color.red, true);

        Thread t = new Thread(this);
        t.start();
    }

    public void run() {
        try {
            while (true) {
                timeStep();
                repaint();
                Thread.sleep(1000 / 24);
            }
        } catch (InterruptedException ie) {
        }
    }

    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Shape s = createShape();
        g2.setPaint(paint);
        g2.fill(s);
        g2.setPaint(Color.white);
        g2.draw(s);
    }

    private void timeStep() {
        Dimension d = getSize();
        if (d.width == 0 || d.height == 0) {
            return;
        }
        for (int i = 0; i < coordinates.length; i++) {
            coordinates[i] += deltas[i];
            int limit = (i % 2 == 0) ? d.width : d.height;
            if (coordinates[i] < 0) {
                coordinates[i] = 0;
                deltas[i] = -deltas[i];
            } else if (coordinates[i] > limit) {
                coordinates[i] = limit - 1;
                deltas[i] = -deltas[i];
            }
        }
    }

    private Shape createShape() {
        GeneralPath path = new GeneralPath();
        path.moveTo(coordinates[0], coordinates[1]);
        for (int i = 2; i < coordinates.length; i += 4) {
            path.quadTo(coordinates[i], coordinates[i + 1], coordinates[i + 2], coordinates[i + 3]);
        }
        path.closePath();
        return path;
    }

    public static void main(String[] args) {
        JFrame f = new JFrame("Hypnosis");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new Hypnosis1(4));
        f.setSize(300, 300);
        f.setVisible(true);
    }
}

Draw text along a curve


package jay;

/**
 *
 * @author jay.thakkar
 */
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class RollingText extends JPanel {
  public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;

    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);

    String s = " http://jaypthakkar.blogspot.in ";
    Font font = new Font("Serif", Font.PLAIN, 24);
    FontRenderContext frc = g2.getFontRenderContext();
    g2.translate(40, 80);

    GlyphVector gv = font.createGlyphVector(frc, s);
    int length = gv.getNumGlyphs();
    for (int i = 0; i < length; i++) {
      Point2D p = gv.getGlyphPosition(i);
      double theta = (double) i / (double) (length - 1) * Math.PI / 4;
      AffineTransform at = AffineTransform.getTranslateInstance(p.getX(),
          p.getY());
      at.rotate(theta);
      Shape glyph = gv.getGlyphOutline(i);
      Shape transformedGlyph = at.createTransformedShape(glyph);
      g2.fill(transformedGlyph);
    }
  }

  public static void main(String[] args) {
    JFrame f = new JFrame("RollingText v1.0");
    f.getContentPane().add(new RollingText());
    f.setSize(600, 300);
    f.setVisible(true);
  }
}

How to Create CurveDraw In Java

In this section, you will learn how to create CurveDraw in java.awt package. This class,supported by thejava.awt.geom package, enables you to create a quadratic or cubic segment. Here, you will see in the following example that provide you complete code of the program.
Program Description:
Define class named CurveDraw, for creating  this component. 


QuadCurve2D.Double(): This QuadCurve2D class is defined as a quadratic parametric curve segment in (x, y) coordinate and the quadratic parametric curve segment is specified with Double Coordinate. This class supplies a coordinate space. Such that this class represents the coordinate parameter and is defined for using the CurveDraw component. A QuadCurve  draws the curve line with Double Coordinate. 

Here is the code of this program:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

public class CurveDraw extends Frame {
  Stroke drawingStroke = new BasicStroke(2);
  QuadCurve2D curve = new QuadCurve2D.Double(30,50,20,200,100,100);

  public void paint(Graphics g) {
  Graphics2D ga = (Graphics2D)g;
  ga.setStroke(drawingStroke);
  ga.setPaint(Color.green);
  ga.draw(curve);

  }

  public static void main(String args[]) {
  Frame frame = new CurveDraw();
  frame.addWindowListener(new WindowAdapter(){
  public void windowClosing(WindowEvent we){
  System.exit(0);
  }
  });
  frame.setSize(200200);
  frame.setVisible(true);
  }
}
Output of this program: