Friday, July 08, 2011

Java_OPTS in ANT

Have you ever run out of Space while building your code, You would have seen your ant complain about "Out of Heap Space".

Solution : set the environment variable

set ANT_OPTS=-Xms512m -Xmx512m (Windows)

export ANT_OPTS="-Xms512m -Xmx512m" (ksh/bash)

setenv ANT_OPTS "-Xms512m -Xmx512m" (tcsh/csh)


now run your build

Saturday, April 30, 2011

MySQL - Quick Command Reference

Alter Table

Change data type of a column
mysql> alter table 
-> change varchar(100); <-- new data type to be changed to

Update Table

Change value of a Column based on a condition

UPDATE table_name SET field1=new-value1, field2=new-value2 [WHERE Clause]

Thursday, April 14, 2011

Tutorial :Building Custom Tags in JSP

I Found this series in stardeveloper.com which has good tutorial on developing custom JSP tags.

I am listing them in order here

1. Developing your first custom tag

2. Introducing Scripting variables in tags

3. Database Access with JSP tags

Wednesday, April 13, 2011

Mysql - execute SQL statements in a script file

1. without username / password

shell> mysql db_name < sqlfile.sql > output.txt

2. with username / password

mysql -u username -p database_name < sqlfile.sql


Saturday, April 09, 2011

Enum in Java 5.0

In 5.0, the Java™ programming language gets linguistic support for enumerated types. In their simplest form, these enums look just like their C, C++, and C# counterparts:

enum Season { WINTER, SPRING, SUMMER, FALL }

But appearances can be deceiving. Java programming language enums are far more powerful than their counterparts in other languages, which are little more than glorified integers. The new enum declaration defines a full-fledged class (dubbed an enum type). In addition to solving all the problems mentioned above, it allows you to add arbitrary methods and fields to an enum type, to implement arbitrary interfaces, and more. Enum types provide high-quality implementations of all the Object methods. They are Comparable and Serializable, and the serial form is designed to withstand arbitrary changes in the enum type.

Static Import – new in Java 1.5.0

The static import construct allows unqualified access to static members without inheriting from the type containing the static members. Instead, the program imports the members, either individually:

import static java.lang.Math.PI;
or en masse:

import static java.lang.Math.*;
Once the static members have been imported, they may be used without qualification:

double r = cos(PI * theta)

App Servers – Hall of fame

Ever Wondered how many app server are cranking up buninesses worl wide comprared to IIS as the only option in .NET world, JBoss , Websphere, BEA Weblogic and Tomcat are the most popular but there are many out there silently labouring to make sure we get to say “Business as usual” here is a list of the unsung heros of planet J2EE

Can a Class (Inner or Outer) be declared static ?

- Short answer –

Yes

- for the impatient but wana know more kind –

only Nested-Top level class can be declared static.

There are 2 types of class Top-level (Opter) and Inner (Anonymous, Local,Member,Nested top-level)

Local – Class declared in a code block or method and is visible inside tha block only like a local variable

Member – is visible for the entire class, you can instantiate this class only with in the context of the object, and hence cannot have its own indivudial existance, and cannot be instantited without an object of the outer class

Nested top level class – is like a member class with static modifier. It is just like anyother top-level class but declaed inside another class,

long answer starts here - :)

Q : How do you Unit Test private methods using JUnit

Soln1: http://sourceforge.net/projects/junit-addons
Look at that. It has a PrivateAccessor class to call private methods and fields. It also has utility classes for array comparision and the likes. I really like it.

Soln2: Make it non-private. Or for every private foo(), add another method foo_FOR_TESTING_ONLY() that calls foo(). Or zap the class with reflection to make the method non-private temporarily.

Ever wondered about the image when you signUp

JCaptcha is one such tool, which will help you do get it into your web App – details in the link

WSDL2JAVA for developing Web Services Client

Its very convinent to create a Web Service Client using the tool WSDL2JAVA. Below are the steps to create one in Eclipse.

Step-1. Create a project in Eclipse ( we will call it testWSClient )

Step-2. Create a new run time configuration in Eclipse by clicking on “Run” and the new run time configuration Icon on the pop-up dialog box.

    1. Main Tab –
      1. In the new Run-time config’s “Main” Tab enter “org.apache.axis.wsdl.WSDL2Java” for Main Class Test box
      2. Enter or Browse Project name “testWSClient”
      3. Type some name for this config in the name text box ( ex – runwsdl2java )
    2. Arguments Tab -
      1. Enter the following in the Argument Tab - http://machinename.companyname.com:8080/module/services/servicemodule/MyService?wsdl -o src - This is the URL of the Web Service for which you want to generate Java code, and the command ” -o src” instructs wsdl2java to do just that
    3. Class Path Tab -
      1. Make sure you have actvitation.jar, axis.jar, common-discovery.jar, common-logging.jar, commons-net.1.3.0.jar, javamail1.4.jar, jaxrpc.jar, saaj.jar and wsdl4j.jar in the classpath of your project and run time config

Step-3 - Now Run the runwsdl2java by selecting it from the Run dropdown, you should see the following

  1. Objects with package details being created for “ComplexTypes” in the WSDL, these are plan data objects
  2. A Port Type Interface with Methods corrspoinding to “Port Types” created
  3. Service and ServiceLocator classes created with methods
    1. getServiceHttpPort(java.net.URL portAddress)
    2. getServiceHttpPort()
  4. A HTTP Binding Stub Class

Note : It should be noted that all these classes are generated automatically by the wsdl2java tool.

Step-4 - Now Write your Client to invoke and access the methods in the WSDL, and interact with the web services.

NOte : Before we start make sure that the “ServiceHttpPort_address” variable in ServiceLocator class is pointing to the correct WSDL URL, which you provided when you were running the wsdl2java, it normally will be, but this is just a check, might not be required.

Now you can write a client, example below

public static void main(String[] args) throws MalformedURLException
{

Service service = new ServiceLocator();
try {
System.out.println(service.getServiceHttpPort().xyzMethod(getMyObject()));
}
catch (Exception e) {
System.out.println(e.toString());
}
}

private MyObject getMyObject() {

// Note this MyObject will be a complexType in the WSDL and generated by the wsdl2java tool, we are creating it to pass it to the method xyzMethod ( also in WDL as a Port Type and acccessible thru ServiceLocater) which takes MyObject as a parameter

MyObject obj = new MyObject( someparameter);

}

Stop (Java vs PHP) Start (Java + PHP :)

Stop cribbing and fighting and GROW UP!!. Java or PhP it does not matter, what matters is it Works!!!.

So do what it takes to get it done, so if Java or PhP or Even Java and Php together. Still can’t believe. http://www.caucho.com/ have already done it. check it out in their website, they have Resin which is a Open Source application Server and Quercus a Java-Php Bridge.

There is also a Open-Source Php-Java Bridge at Source forge – http://php-java-bridge.sourceforge.net/pjb/

How to Make JBoss App talk to MySql

1. Configuring MySql in JBoss

MySQL is an open source database used by many open source projects and small organizations. To use JBoss 4.0 with MySQL, we first need to put the MySQL driver classes into the CLASSPATH. Copy the .jar file mysql-connector-java-3.0.9-stable-bin.jar to the /server/default/lib directory.

To use the MySQL data source, copy /docs/examples/jca/mysql-ds.xml to the /server/default/deploy directory. Modify the mysql-ds.xml configuration file by setting to com.mysql.jdbc.Driver and to jdbc:mysql:///, where is the MySQL host server and is the MySQL database.

After the file is copied to the Deploy folder, this can be monitored from MBean in JMX Console

Next, we need to set the and elements in the standardjaws.xml or jaws.xml file:

   java:/MySqlDS   mySQL  

We also need to set the and elements in the standardjbosscmp-jdbc.xml or jbosscmp-jdbc.xml file:

             java:/MySqlDS        mySQL    

Finally, we modify login-config.xml with MySQL database settings. Add the following element to login-config.xml:

                     sa          sa                                 jboss.jca:service=LocalTxCM,name=MySqlDS                        

By modifying the mysql-ds.xml, standardjaws.xml, standardjbosscmp-jdbc.xml, and login-config.xml files, the JBoss 4.0 server is configured to be used with a MySQL database.

Files Attached for reference

Click here for more info

2. Programming to talk to MySql in JBoss

intricacies of Inner Classes

“One Cannot refer to a non-final variable form inside an inner class defined in a different method”

public void onModuleLoad() {
// TODO Auto-generated method stub

final FormPanel form = new FormPanel(); –> Has to be final in order to be accessed from an inner class method.

VerticalPanel vpanel = new VerticalPanel();

vpanel.add(form);

vpanel.add(new Button(“Submit”, new ClickListener() {
public void onClick(Widget sender) {
form.submit(); –> Here the final form object is being accessed
}
}));

}

Partitoning in Oracle

If you are like me, you might be a Developer with moderate knowledge in database. one of the frustrations we face as developers is when we are forced to work with non-indexed tables, which kill application performance.

Well there is a way to get around this in Oracle by using “partitions” , if your DBA has configured one.

partitions are created based on time interval that is set by the DBA’s , usually its 5 0r 10 min window if its a busy table.

when we query this table we would use partition keyword in Oracle to provide partition id to narrow down to the partition. This might need you to be aware of the time stamp when your data was created or updated, as the partition id’s are normally based out of “time stamp”

an example query would look like this – select * from TABLE partition(P200807022035) where field_name=’value’

“P200807022035″ is the partition id which is based on time stamp at 5 min interval ,

P200807022035 – year = 2008, month = 07, day = 02, time = 20:35

Reflection in Action

Most of us ( Java Developers ) have heard or used tools/apis and frameworks which heavily use Reflection, we might also have used it or at least considered using it at one time or other.

here is a nice article about reflection with great tips on using it and also when to use it. i guess a good opportunity to reflect on your coding history :)

http://today.java.net/pub/a/today/2008/02/12/reflection-in-action.html

Step-By-Step MBean Dev Guide by Matt Harrah

I have been looking for a good ( simple , to-the point ) guide for Developing MBeans, and never found one in JBoss.org/com. Matt Harrah has exactlay that in his Blog Rocket Surgery. Check it out! you will be amazed. Many times Engineers are good at making simple things complex, we need more guides like Matt’s .

Know Your Worst Friend, the Garbage Collector by Romain Guy

Great Article about GC. click here

List of JVM Options byJoseph D. Mocker (Sun Microsystems, Inc.) – click here

Some Java cmd line options for tuning GC

-Xms initial java heap size
-Xmx maximum java heap size
-Xmn the size of the heap for the young generation
-Xss the stack size for each thread

Class.forName() Method and Dynamic Class Loading

This is an Interesting Conversation in DevX Form – click here for details.

Question :I have a doubt regarding the working of Class.forName() method.
How exactly it works in jvm? What is the difference between
Class.forName(“oracle.jdbc.driver.OracleDriver”) & DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver())?
If my JDBC code is something like this:
Class.forName(“oracle.jdbc.driver.OracleDriver”);
Class.forName(“Some other driver class”);
Connection conn = DriverManager.getConnection(“jdbcracle:thin:@hostname:1521:SID”,”user”, “pwd”);

Which class will be loaded and how will DriverManager class will know which driver to communicate?

Answer : Short Answer (Summary)

  • Both Drivers will be loaded and they register themselves by calling DriverManager.registerDriver() method, and based on the connection URL provied the approriate driver is loaded
  • When we instantiate a Object with “new” keyword 2 things happen
    (1)Load the class in to memory, if it is not loaded -
    which means creating in-memory representation of the class from the .class file so that an instance can be created out of it. This includes initializing static variables (resolving of that class)

(2)create an instance of that class and store the reference to the variable.

  • Class.forName does only the first thing.It loads the class in to memory and return that reference as an instance of Class. If we want to create an instance then, we can call newInstance method of that class. which will invoke the default constructor (no argument constructor). BUT The main advantage of using Class.forName is that it takes the class name as a String, so we can change the JDBC Driver at run time by passing a different JDBC driver from a property file or command line. We have to make sure we also pass the Connection url (which is also a String) based on the DB if the DB is changed, there can be cases where the DB is not changed but the dbc driver is changed.

Data Base Performance Tips

Indexes - Faster Reads / Slower Inserts,Updates,Deletes -

Views – Simpler Query / Slower Reads and more work for DB

De normalization - More Space Req and cost of write operations / Faster Reads with fewer join’s required

Normalization - Lesser Space Req, low cost of write operations / Slower Reads with more join’s required.

Continous Integration (CI) & Hudson

Hudson is gaining popularity from startups to Big Blue, ( i wonder how IBM has tutorial on all topics current, and usually they are pretty good ). I have been working on streamling build process and working with Hudson and getting to know it better. some random ramblings and notes with reference below, hope it will be helpful.

CI with Hudson – IBM Tutorial

Case Study about Hudson in Enterperise Deployment

Jar Up and Run – How to run a class in jar file

Ok not so fast – a brief background first. Have you ever used hudson, is it cool to just run it by typing java -jar hudson.war, well you can do it too, but need to take care of some steps before that, here you go!

1. Cerate your application with all the classes and libraries included, and most importantly ONE MAIN class ( which has a MAIN method ) , lets call it MyDriver.java

2. Now create a test file, input.txt with the following info in it (only one line ), Main-Class: classname In this case it will be Main-Class: MyDriver.java (don’t forget the space after Collen “:” – it wont work otherwise ) - click here for more info and search for “jar”

3. now run this command – jar cfm jar-file manifest-addition input-file(s). In this case it will be jar cfm my.jar input.txt *.* (or *.class what every you want to add ) – click here for details on this command

Finally you have your jar ready to run or rather FLY. you can use this command to do exactly that!

java -jar my.jar    ( this should run what ever you have in your main method in your main class ) - clieck here for details

ORACLE : who is connected to My Oracle Instance

You have a DB you call your own, but you cant seem to drop some users eventhough you have stopped all services you were running which might have connected to your Oracle Instnace,

Well they (Apps or users) can’t hide any longer … The Oracle’s best Spy is on your side – here is the SQL which can bring them to the open. ( you need to be the SysDBA to do this though )

1. set linesize 30000 – to make sure everything appears in a single line

2. SQL> select username, sid, serial#, status, osuser, process, machine, terminal, program, logon_time from v$session where username is not null and username not in (‘SYSTEM’,'SYS’,'DBSNMP’);

- All the agents are displayed in a table with their USERNAME, SID,SERIAL#,STATUS,OSUSER,PROCESS,MACHINE,TERMINAL,PROGRAM
you have to decide if you will shoot (force kill ) or negotiate ( stop the services in the machines they are running in )

JavaScript Hacks

1. Make the Images in a web page DANCE ! to your tune :

open the web site ( ex www.google.com ) and replace the url by this script and you have it !

javascript:R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.getElementsByTagName(“img”); DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position=’absolute’; DIS.left=(Math.sin(R*x1+i*x2+x3)*x4+x5)+ “px”; DIS.top=(Math.cos(R*y1+i*y2+y3)*y4+y5)+” px”}R++}setInterval(‘A()’,5); void(0);

2. Want to edit a web page in the Browser as you please …. :

open the web site ( ex www.google.com ) and replace the url by this script and you can custamize any web site to your taste

javascript: document.body.contentEditable = ‘true’; document.designMode = ‘on’; void 0

How to know if all the threads you started have completed

Question : I have one object that have one method named StartDownload(), that starts three threads. How do I make to get a notification when each thread as finished the execution ?

Answer :

There are a number of ways you can do this:

  1. Use Thread.join() in your main thread to wait in a blocking fashion for each Thread to complete, or
  2. Check Thread.isAlive() in a polling fashion — generally discouraged — to wait until each Thread has completed, or
  3. Unorthodox, for each Thread in question, call setUncaughtExceptionHandler to call a method in your object, and program each Thread to throw an uncaught Exception when it completes, or
  4. Use locks or synchronizers or mechanisms from java.util.concurrent, or
  5. More orthodox, create a listener in your main Thread, and then program each of your Threads to tell the listener that they have completed.

To learn more and see code examples refer to the Stack Over Flow PAGE here

DTraceToolkit

The DTraceToolkit is a collection of over 200 useful and documented DTrace scripts developed by

After downloading from this site :

  1. gunzip and tar xvf the file.
  2. cd to the toolkit directory.
  3. Run ./install. (This step is optional. You can use the toolkit without doing this.)
  4. Read the guide to find out how to get started.
  5. A list of scripts is in Docs/Contents.
  6. Enjoy!

Hammer Head

Hammer Head is a FireFox plug-in which works with Firebug and helps to run regression Browser Performance tests. This is helpful when you would like to obtain Browser performacne numbers across multiple performance runs.

click here to download and know more about Hammer Head

Read interactive command-line input with Java

The basic technique of reading a String provided by a user at a command-line is fairly simple, but more lengthy than you’d expect. It involves the use of the System.in object, along with the InputStreamReader and BufferedReader classes. The code in Listing 1 shows how you can prompt the user to enter a String value, such as their name, and then read that value. for more read this

List.contains(Object e) – Howto

If you have a List of Custom object, and you would like to perform operations such as “contains” or “remove” on this List, you need to do the following.

Implement equals(Object o) method in your custom class, note, the method takes Object as a parameter not the custom object as the type, this is because the the code in the contains method in the List (ArrayList) class, does the followng

public int indexOf(Object elem) {
if (elem == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (elem.equals(elementData[i]))
return i;
}
return -1;
}

example method :

public boolean equals(Object bean)
{
boolean result = false;
CustomObject gbean = (CustomObject) bean;

if(Id.equalsIgnoreCase(gbean.getId()))
{
result = true;
}
return result;
}

SVN Status code – Quick Reference

SVN Status Simple Cheat Sheet

svn status cheat sheet

Runtime Command Execution in Java

for everything there is always an obvious and simple way of doing and there is an intutive way of doing the same stuff, as they say its either the “Berkeley way” or the “MIT” way among the techies. For those who are not femaliear with that, here is a bit of background, when you design a software most often you would take one of these approaches, you can make it easy and intutive for the user and hence byte the complexity within the software/code and hence your user interface would look simple, elegant and easy to use, while your code might be a nighmare to maintain – a.k.a “Berkeley way” [OR] you can keep the user interface basic, hard to use and sometimes complex/non-intutive for the user, while keeping the code simple a.k.a “MIT way” . Both are valid apporaches depending on where you apply it.

One such instance is “Executing native command/applications from a Java Application” . It seems a simple task, but i have seen many applications like “Hudson” making a living out of it so read on if you are interested.

Executing a native command from java is a simple task as it can get in java, it can be accomplished in few lines of code, example below.

Runtime rt = Runtime.getRuntime();Process proc = rt.exec("ping localhost");

But think of its impact on the user, if you have ever used hudson to build your code or run your unit test you would realize the importance for the user to know whats going on as the build is being executed, this would be true if he were to be running the command natively, but hudson provides a way to dynamically append the command output as the command is being executed natively rather than dump the results at the end of the execution as it would be in the previous case, which makes it one of the most useful features. details below. for more details check this out

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class RuntimeExec {
public StreamWrapper getStreamWrapper(InputStream is, String type){
return new StreamWrapper(is, type);
}
private class StreamWrapper extends Thread {
InputStream is = null;
String type = null;
String message = null;
public String getMessage() {
return message;
}
StreamWrapper(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line = null;
while ( (line = br.readLine()) != null) {
buffer.append(line);//.append("\n");
}
message = buffer.toString();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
// this is where the action is
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
RuntimeExec rte = new RuntimeExec();
StreamWrapper error, output;
try {
Process proc = rt.exec("ping localhost");
error = rte.getStreamWrapper(proc.getErrorStream(), "ERROR");
output = rte.getStreamWrapper(proc.getInputStream(), "OUTPUT");
int exitVal = 0;
error.start();
output.start();
error.join(3000);
output.join(3000);
exitVal = proc.waitFor();
System.out.println("Output: "+output.message+"\nError: "+error.message);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Database Connection Pooling with Tomcat

I was facing issue with my tomcat setup where it was running out of DB connection and throwing the following error.

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.

I had to dive a bit into jdbc connection pooling in Tomcat to get that resolved. onjava.com has helpful article, i thought i would share it with you all.

- link - Database connection pooling with Tomcat by Kunal Jaggi

Steps to create a DataBase source with no connection timeouts in tomcat

Step-1 : Create the Resource entry in context.xml

autoReconnect=true“
maxWait=”100″
removeAbandoned=”true”
maxActive=”3000″
maxIdle=”100″
autoReconnect=”true”
removeAbandonedTimeout=”60″
logAbandoned=”true”/>

Step-2 : Create the entry for ” res-ref-name” which points to the Resource name in context.xml in the web.xml under your application in the webapps/your_app_fldr/WEB-INF/web.xml


DB Connection
jdbc/mysql
javax.sql.DataSource
Container

How to Print Variables in JMeter

I often find myself looking for this, though i very well know it. Its very useful to print variables in a Post Processor Bean shell in Jmeter, while you are developing / debugging your script. Specially when you are using variables that are picked up from CSV files. So here is a the 2 lines you use in a Beanshell to print the variables in Jmeter.

String auth = vars.get(“oauth_token”);
System.out.println(” AUTH Token = ” + auth);

Jmeter for Functional Tests

Found this article on web, which is an extract from the book “Apache Jmeter” ,I have been using Jmeter for performance measurement and found it to be very useful, but this article talks about the use of Jmeter for functional testing, which is interesting. link below

- http://www.packtpub.com/article/functional-testing-with-jmeter

Thread Dump for Java Process

Thread dump is a essential part of debugging issues with running process apart from looking at the logs, thread dumps provide a “under the hood” view of your java process and its health.

kill -3 or kill -QUIT are usually used to take thread dumps in most UNIX environments, but there is catch for java process which was kicked off by a shell-script.

This blog post explains this in great detail and is a good read if you are stuck trying to take a thread dump on a java process started by a shell script

jps – Java Virtual Machine Process Status Tool

A very power full tool , yet effective for simple use case as well. I use this often when i wasnt to know the specific javaclasses which are running on a server/host.

its a pain to type ps -ef | grep java and read through the pile of information spitted out by the command, instead just use “jps” if you are looking for a java application / calss.

please note : this is not yet supported on Wiondows – for detaile look at sun’s ( now oracle) documentation .

Java Request Sampler in Jmeter

How to write a custom Java Class and use it as part of Java Request in Jmeter

1.

reference – http://henry-tech-notes.blogspot.com/2006/10/testing-hessian-services-with-jmeter.html

How to use SampleResult in Java Request / Why its required

reference – http://stackoverflow.com/questions/2379688/testing-java-classes-with-jmeter

Wednesday, April 06, 2011

MySQL - Run SQL Queries From A cmd prompt

Data setup and tear down is a common task during development and testing. Ability to execute sql queries from command prompt allows developers to automate these tasks.

You can achieve this by using the following command -

mysql -u user -p -e 'SQL Query' database

Where,
-u : Specify mysql database user name
-p : Prompt for password
-e : Execute sql query
database : Specify database name

note : You don't need to specify user and password if you have not set up authentication.

Tuesday, January 18, 2011

Junit 4.0 & TestNG Quick Comparison

JUNIT 4.0

  • Fixtures – should be static in Junit
  • Dependency Testing – Testing Isolation is a strong point, but neglects dependency testing
  • + Test result Turnaround and cycle wastage
  • Focus on Unit Testing of Objects
  • Test Code and Test Data separation is hard, might need to use FIT

TEST NG

No Fixtures – no Static required

  • Dependency Testing - @Test (dependsOnMethods = {"verifyLogIn"}) / but still the scope is single Test class / The test dependency is still within a test class.
  • Time Saved in Test Re-Run ( by generating xml of only failed test cases )
  • * Focus on higher level,
  • EASY Test Code and Test Data Separation, by TestNG's XML configuration
  • Complex Data can be fed to the test by using @DataProvider annotation, which facilitates the mapping of complex parameter types to a test method.