Enterprise build system, Gradle Inc. and repository specialist JFrog have formed a collaborative relationship to work toward a series of offerings that the companies say will enhance user productivity. The companies will begin packaging JFrogs repository manager, Artifactory and Gradle together as a more complete build offering.
Web services testing software vendor eviware has released soapUI 3.5, which now supports the testing of JMS, AMF and databases. Free and open-source, soapUI is a desktop application used in inspecting, invoking, developing, simulating and testing Web services. The interface is designed to feel like the IDEs that are already familiar to developers.
Did you miss our Application Performance Management virtual seminar in February? In these expert presentations discover the best techniques for perfecting performance builds and for finding, diagnosing and fixing performance bugs. Gain instant access to the latest tools for mastering performance management across the lifecycle.
Five articles on classloaders, objects, classes, redeploying, OSGi, Tapestry 5, HotSwap, JRebel and other aspects of Java class reloading and turnaround.
Are you tired of turning every non-trivial class into an interface, and then create an "Impl" that actually does the work when mocking objects for testing? Do you know about JMock's ClassImposterizer? It allows you to mock instances without calling the constructor of the mocked class, ultimately helping you write and test your code faster.
Free your apps from the bugs and headaches of Java NIO. XNIO offers NIO capability but in a hassle-free manner and vastly simplifies the opening of channels with support for SSL and virtual channels within the same API. Learn more about this open source project from JBoss and how to integrate it into your applications.
Learn how to create applications for the OpenCable Application Platform (OCAP). This article, the second in a three-part series, describes how to use standard Java technology and the OCAP Reference Implementation (RI) to create applications, called Xlets, that run atop OCAP.
Software metrics can help you find hidden design elements in your code, enabling them to
emerge as idiomatic patterns. This installment of Evolutionary architecture and emergent design shows how intelligent use of metrics and visualizations lets you discover important code elements that are obscured by accidental complexity.
iBATIS is a project used primarily for data access object (DAO)
and object-relational mapping (ORM). You can use it to easily work with Java
objects and databases. The update for iBATIS 3 beta 9 was posted January 23,
2010. iBATIS 3 is a completely rewritten version of iBATIS and includes some
significant updates. This article introduces some of what's new in iBATIS 3.
The OpenCable Application Platform Reference Implementation (OCAP RI) is a freely available implementation of a comprehensive platform for interactive applications that run on set-top boxes, televisions, and other devices. This article, first in a three-part series, explains OCAP at a high level and describes how to obtain and run the RI. You'll learn how the OCAP RI locates applications and how to run any application.
Atlassian currently is in the process of migrating their employees from Zimbra to Google Apps to reflect their recent move to integrate JIRA Studio, their hosed SDL package, with the Google Apps suite. With the relaunch of the Google Apps Marketplace, JIRA Studio is now available for download on that site as well. Google Apps are used by over 2 mil
One source had confirmed that Twitter was working with the NoSQL data store, Cassandra, late last year. Some more details have finally surfaced about this quiet transition from a MySQL + Memcached system to Cassandra. The MyNoSQL blog recently interviewed Ryan King, who is leading the Cassandra conversion efforts at Twitter.
Today we are witnessing a great bit of excitement with the NoSQL
movement. Call it NoSQL (~SQL) or NOSQL (Not
Only SQL), the movement has a mission. Not all applications need to
store and process data the same way, and the storage should also be
architected accordingly. Till today we have always been force-fitting a
single hammer to drive every nail. Irrespective of how we process data
in...
SpringSource have just announced tcServer Spring Edition, giving
develpers and operators better visibility into their Spring
applications deployed into cloud environments. tcServer,
based on Tomcat is a popular choice for developers who want to take
advantage of the Spring supported application server, and with this
announcement, it gives a more compelling reason to use tcServer for
your...
Designing and improvising a thread based application is a challenge. But by following certain design principles and guidance, this can be easily overcome.
Designing and improvising a thread based application is a challenge. But by following certain design principles and guidance, this can be easily overcome.
Introduction
For many years, we have been using Java Threads for developing numerous Client-Server based applications. While it's always desirable to have a highly responsive Client application,
handling a high volume of client requests has always been a prime goal of any Server application. However, designing a highly-scalable server requires lots of analysis. Without careful
design and adherence to a well thought out underlying policy, a thread based system can fail to produce the desired outcome.
In this article, we'll discuss certain design principles that should be followed when the objective is to build an efficient, thread-safe application.
Thread Safety lies in Domain
As a design principle of thread safety, the vital point to look into is "Domain First." After all, the whole structure of an application lies on the Domain itself. If you get your domain model right,
most of the problems are automatically taken care of. A model represents certain aspects of business logic
consisting of various constraints and invariants. Understanding the pre and post conditions of a model are much needed in order to make the realized application thread-safe.
Let's imagine an travel agency that arranges budgeted cars for their traveler guests. They need an interactive car rental application that allows
them to book multiple cars at different tourist locations on different dates within a specified price range. As they keep making multiple rental requests,
at the same time if the system fails to find a car at particular location within price range, they want to be notified with suggested locations on
the same screen.
We can think of this as a booking Requester taking the renal requests and putting them in a thread safe collection CarBookings that would be read
concurrently by an actual CarFinder process to provide suggested locations. If CarFinder succeeds, it forwards this via the booking engine to the booking rental location. If CarFinder does not succeed, it tries to find the cars based on the price range and nearest location. Once found, it adds the info to another thread safe collection
CarBookingAdvices.
There are many thread safe data structures available, but if you're sure about the Thread Safety policy that you want to adhere to, it's best to create a domain model on your own. For example:
class CarBookings{
private final Set bookings = new HashSet();
public synchronized void putCar(CarBooking booking){
bookings.add(booking);
}
public synchronized Set getBookings(){
return Collections.unmodifiableSet(bookings);
}
}
Since the methods putCar() and getBookings() provide a secure way of accessing the non-thread-safe instance variable bookings, the CarBookings can be used
safely by both the BookingRequester and CarFinder process running in different threads. This meets our simple thread safety requirement.
//Defining BookingAdvice
class BookingAdvice{
private final String bookingId="";
private final BigDecimal rate=new BigDecimal("");
private final String location="";
//Getter and Setter ommited
}
class BookingAdvices{
private final Set<BookingAdvice> advices = new HashSet<BookingAdvice>();
public synchronized void putAdvice(BookingAdvice advice){
advices.add(advice);
}
public synchronized Set<BookingAdvice> getAdvices(){
return Collections.unmodifiableSet(advices);
}
}
//Defining Requester
class BookingRequester{
private CarBookings bookings;
private BookingAdvices advices;
public void requestBooking(CarBooking booking){
bookings.putCar(booking); //Line 1
displayAdvice(advices.getAdvices()); //Line 2
}
private void displayAdvices(Set<BookingAdvice> advices){
//Displays the advices on the same screen
}
}
//Defining Finder
class CarFinder{
private BookingAdvices advices;
private CarBookings bookings;
public void processAdvice(){
List<BookingAdvice> adviceList = getGeneratedAdvices();
for(BookingAdvice advice: adviceList)
advices.putAdvice(advice); //Line 3
findAndProcessBookings(bookings.getBookings()); //Line 4
}
private List<BookingAdvice> getGeneratedAdvices(){
//Generate advice based on requests
}
private void findAndProcessBookings(Set<CarBooking> bookings){
//Finds advice for the booking if required
}
}
Hiding Model State
But, there is a caveat: if the CarBooking class is mutable, then there is a possibility of modifying each CarBooking instance in the set returned by getBookings(). Does it make our model brittle? Well, as long as we can make sure that it won't be modified later on, we'll be fine with that. But, sometimes it's easier get thread safety by hiding the model state and blocking the access to it thereafter. Here, we make CarBooking immutable and add a copy constructor:
class CarBooking{
private final String bookingId;
private final String location;
private final BigDecimal rate;
//Copy constructor
public CarBooking(CarBooking booking){
this.bookingId= booking.getBookingId();
this.location= booking.getLocation();
this.rate= booking.getRate();
}
//public Getter methods below
}
class CarBookings{
//Modified version
public synchronized Set getBookings(){
Set newBookings = new HashSet();
for(CarBooking b : bookings){
CarBooking newBooking = new CarBooking(b);
newBookings.add(newBooking);
}
return Collections.unmodifiableSet(newBookings);
}
}
So, when getBookings() returns, it returns a copy of the CarBooking, thus not allowing modification of the original state--which makes it purely thread safe.
Do Thread Delegation if you can
Sometimes you might find yourself being overburdened with handling the thread safety in your domain model; in that case you can simply delegate it to a range
of Java built-in data structures that are already proven and tested to be thread safe. Like in our example, if we had to use bookings as HashMap<String, CarBooking>, where String could represent bookingId, we could have easily replaced that with ConcurrentHashMap--which is a thread safe HashMap. Likewise there are many other data structures available (under the java.util.concurrent package) like CopyOnWriteArrayList and ConcurrentLinkedQueue, to name a few.
Figuring Single Thread Confinement
To coordinate multiple threads in a lock-based application, the OS and JVM have to burn fair amount of CPU cycles for context switching and thread
scheduling--making the system less responsive sometimes.
This can be avoided by allowing only one thread to gain access to work on a unit model (either CarBooking or BookingAdvice) at a time, and also making sure that same unit model should not be re-worked by the same thread. To make this happen, we can employ bounded BlockingQueues (BookingQ and AdviceQ) that would act
as a mediator between Requester and CarFinder.
So, for a rental request, the Requester would just create a CarBooking and put it in the BookingQ queue, and on the other hand, CarFinder would take that
off of the queue. The same thing will be done by the CarFinder to return a BookingAdvice in the AdviceQ queue. This way, multiple Requesters and CarFinders can work
asynchronously, making the system highly responsive.
Use synchronized lock wisely
While synchronized lock provides an easy way to work with multiple threads, improper usage of the lock may cause unpredictable results. This becomes obvious when multiple locks are acquired to perform an atomic operation where the first lock is held until last lock operation is performed. Let's consider our BookingRequester and CarFinder that are using simple java Sets instead of CarBookings and BookingAdvices. Here two operations: putting request and getting
advices for Requester (vice versa for CarFinder, lines 5,6,7 and 8) become implicitly atomic under the same lock:
class BookingRequester{
private final Set bookings = new HashSet();
private final CarFinder finder;
public BookingRequester(CarFinder cf){
finder = cf;
}
public synchronized void requestBooking(CarBooking booking){
bookings.add(booking); //Line 5
displayAdvice(finder.getAdvices()); //Line 6
}
public synchronized Set getBookings(){
return bookings;
}
}
class CarFinder{
private final Set advices = new HashSet();
private BookingRequester bookings;
public CarFinder(BookingRequester br){
bookings = br;
}
public synchronized void processAdvice(){
List adviceList = getGeneratedAdvices();
for(Advice advice: adviceList
advices.add(advice); //Line 7
findAndProcessBookings(bookings.getBookings()); //Line 8
}
public synchronized Set getAdvices(){
return advices;
}
}
Now, a problem starts to creep in when two threads T1 and T2 try to call Requester requestBooking() and CarFinder processAdvice() respectively at the
same time. During requestBooking, before T1 calls getAdvices() on CarFinder (Line 6), it has to wait for T2 to complete processAdvice. But to complete processAdvice, T2 needs to call getBookings() on Requester (Line 8), which won't happen until T1 completes requestBooking()--leading to a deadlock situation.
In our previous implementation of BookingRequester and CarFinder, we have already delegated the two operations to be handled independently under different locks (one for CarBookings and another for BookingAdvices, lines 1, 2, 3 and 4) to avoid any deadlock.
But, here we can simply resolve it by moving synchronized from the entire method to only the time required to put the booking (Line 5) and advice (line 7).
Another important point regarding deadlocks would be the order in which the resources are accessed in an atomic operation. If two threads work on an operation with two resource locks being held in a different order, it can lead to a deadlock situation too. So, make sure all threads calling an atomic operation get all resource locks in the same order.
Conclusion
Designing and improvising a thread based application is a challenge. But by following certain design principles and guidance, this can be easily overcome. At the same time, clear understanding of thread safety policy is also essential as it helps you simplify the design. There are many other techniques available that we couldn't cover here. However, the principles presented here will always assist you in overcoming some of the thread safety related hurdles you might be facing as you develop thread-safe applications intended for operation on modern multicore and multiprocessor computers.
Dibyendu Roy has more than ten years of design and development experience in various domains including Banking and Financial Systems, Business Intelligence tools and ERP products.
Part of the Java Standard Edition since the release of the Java Development Kit 1.1, the Java Database Connectivity (JDBC) API has become the industry standard for providing standards-based data access from Java. It allows you to have a single API into a database connectivity driver--whether it be Oracle, SQL server, or DB2--and to write your application code in such a way that you needn't concern yourself with the underlying data source.
Evolution of JDBC drivers
The JDBC API specification and the drivers it enables have evolved over time, from the original (Type1) drivers--JDBC-ODBC bridges that are dependent upon ODBC drivers and native database libraries on the client side and that are comparatively lacking in features--to native-protocol (Type 4) drivers, also known as Direct to Database Pure Java Drivers, which are entirely written in Java, are platform-independent, and are run inside the client's Java Virtual Machine (JVM) requiring no associative software (such as libraries) to work. Some type 4 drivers have also come to offer numerous features--single sign-on, Kerberos security, and NTLM authentication, for example--largely addressing the need to securely integrate JDBC drivers with complex application servers and database features targeting the enterprise market.
As much as JDBC driver architecture has evolved, however, evolution within the enterprise Java ecosystem has left it with some troublesome shortcomings. Ironically, one trend that has helped to make Java-based, data-driven applications so pervasive in global IT organizations has also taken JDBC off the radar for many developers, who remain unaware of these shortcomings and/or how to address them. That trend is the movement away from a data access model where Java developers program directly to JDBC to a model where they instead use a framework-based object-relational mapping (ORM) technology--such as JPA, Hibernate, or Spring--or an application server such as JBoss that sits on top of JDBC. With these newer, more accessible data models that permit no access to underlying JDBC calls, developers almost never think about JDBC or what JDBC driver to use as part of determining a data access strategy.
However, the JDBC drivers used in contemporary enterprise application design, deployment, and runtime scenarios are well worth thinking about. As things have stood, evaluating a JDBC driver has meant simply selecting a JDBC driver with the best architecture--that is, a Type 4 JDBC driver. Until very recently, however, JDBC architecture types have remained constant in the face of rapidly changing IT conditions within the enterprise. Aside from the widespread adoption of ORM-based data access models discussed above, some of the more sweeping and significant developments include virtualization, advancements and new features in database technologies, and rapid adoption of business intelligence and data warehousing initiatives:
The proliferation of virtualizing both hardware and software resources has made it possible for IT organizations to deliver massive scalability on an affordable growth curve, placing a much higher value than ever before on efficiency and optimum performance throughout the entire application stack.
The increasingly more complex features and functionality of relational database offerings, while in high customer demand, frequently involve complicated and proprietary implementations that have made them all but inaccessible to most applications.
And enterprise organizations standardizing on a single RDBMS platform as their data warehouse must move vast amounts of data from diverse systems and are discovering that time-consuming data loads using batch mechanisms are impeding the production of timely business intelligence reports.
Limitations of Type 4 JDBC drivers
While superior to other JDBC driver architecture types, most Type 4 drivers come with glaring limitations that make them impractical for today's Java-based enterprise application environments. Most, for instance, require changes in an application's JDBC code in order to be tuned for performance. Doing this for each unique application deployment scenario is unmanageable and impractical. When you throw an ORM on top, if you must have a vendor-specific statement method, you'll be unable to do that casting without modifying the code of the ORM. So unless you want to be modifying, let's say, a Hibernate implementation, you need to make sure that those JDBC drivers are clean--that is, that they adhere to the standard while yet executing things in a flexible manner.
Suppose you've been tasked with tracking down the memory usage of an application you've written with Hibernate. You've traced and tuned, and think you should be able to squeeze more out of your Oracle database drivers. For this specific example, we'll say that we need to tune parameter bindings.
In order to more accurately control the amount of memory the driver allocates for each parameter in the PreparedStatement using Oracle's Thin driver, you must use the OraclePremparedStatement.defineColumnType() method (which is not part of the JDBC specification).
However, if on a subsequent execute you should re-bind your parameters using larger data sizes, then the driver will be silently truncated to the size specified--not a good thing. Also, due to the fact that Hibernate abstracts the actual JDBC calls themselves, you lose the power to customize these calls unless you modify the Hibernate code itself, thus casting the PreparedStatement to an OraclePreparedStatement in the process. This is generally unacceptable, as it is costly to modify the Hibernate code and you must duplicate the code changes every time you upgrade the version of Hibernate you're using.
A much less costly option would be to tune memory at the JDBC driver level, where connect options could be specified to set the initial size to be tried for each parameter. This simple solution would save you from having to change Hibernate code in order to tune the application, and could also--by having the driver auto-adjust for the parameter's size--remove the limitation of truncating the data on subsequent executes and binds, making it unnecessary for you to spend time analyzing every parameter binding.
One of the promises on which the typical Type 4 driver architecture has failed to deliver is simple and uncomplicated deployment. It is anything but. Multiple JAR files are required to support deployment across different JVMs or hardware, as well as to access all supported versions of a particular database. This limitation can be overcome by packaging the JDBC driver as a single JAR file regardless of the IT environment, having no dependencies on external DLLs or shared libraries or native database components outside the JVM.
The support of typical Type 4 drivers for mission-critical database features targeting the enterprise is nearly always limited to a bare minimum of functionality. Many such features require proprietary code and the use of external DLLs or shared libraries--security features, bulk data loading, high availability, and XA features ordinarily do, for instance. With each data source that an application must support, the amount of data-source-specific code that must be maintained increases. In most cases, the driver simply exposes whatever support for these features is implemented by the database layer. Consequences of this strategy include inefficiency due to performance overhead, use of proprietary code, and requirements to license expensive database clustering technologies. These can be addressed with 100 percent JDBC-compliant driver-layer-only implementations.
Bulk load and JDBC drivers
Bulk load, a type of feature that addresses the limitations of batch data loads mentioned earlier, deserves a closer look in this context--not least because it has real potential to be a truly game-changing concept for organizations implementing or planning to implement data warehousing for reporting, decision support, and data mining purposes--in other words, just about any enterprise-scale business organization today.
Traditionally, moving very large amounts of data required the use of something called a bulk-moving tool or bulk-loading tool. An example would be a SQL loader, or a Sybase SQL Server BCP, or the DB2 Load command. Available for decades, these are tools that people use and build within their infrastructure on the back end. The demand for data in the enterprise makes such tools necessary; however, in light of the trend to standardize data on a single warehouse platform, the challenge becomes whether or not these tools can be used in a standard way. You've got SQL loader and BCP and DB2 Load, and they're all different. To this point, the only way to do this in any API has been through a batch mechanism such as JDBC batches. But batch methods are prohibitively slow for most data warehousing initiatives.
With JDBC driver technology that communicates directly in the native "wire" protocols of target databases, bulk load technology that's long been locked in C code can be applied to Java for bulk loading even non-relational data from a mainframe platform into a relational data warehouse. Say you have a key application in your organization that stores its data in a VSAM file on the mainframe. But all your BI dashboards and reporting analysis run against Oracle. How do you unlock that crucial data and make it available to your analysis staff so they can operate on the data using their accustomed tools?
You might deploy an event-driven scenario to trigger a bulk load into Oracle from the VSAM file whenever a given set of conditions is met. It would perform a single Select statement from the VSAM file, pass the ResultSet to the load method on a bulk load object for the Oracle database, and insert the data. If you imagine that it would take an awful lot of coding to accomplish this, you'd be mistaken. This graphic gives a real-life example of the code used to implement one such scenario.
Figure 1. A look at the code
In this example, a mere five lines of code were used to pull data out of VSAM and bulk load it into an Oracle database!
Conclusion
JDBC Type 4 drivers offer the best architecture and are adequate for many data-driven Java-based applications and scenarios. Nevertheless, the numerous solutions required to address serious shortcomings within demanding, complex, and sophisticated enterprise environments warrant looking beyond what a bare-bones Type 4 architecture typically offers--that is, client-side, single-tier, 100 percent Java architecture. A JDBC driver thus designed but that also embraces a comprehensive suite of such solutions might even, perhaps, be better thought of as a "Type 5" JDBC driver. To sum up what a "Type 5" driver should offer:
Unrestricted performance: Data throughput is maximized regardless of the runtime environment or data access model.
Codeless enhancement: Features and functionality can be added, configured, or tuned for any application without changing application code, regardless of runtime or data access model.
Resource efficiency: Use of application runtime CPU and memory resources is minimized and can be tuned as needed to fit specific runtime environment parameters or limits.
All-in-one deployment: A single driver JAR file that maximizes the data access simplicity for any Java environment or application.
Streamlined standard: No proprietary extensions to the JDBC specification are required for any supported data source--a "clean" spec implementation.
Such "Type 5" JDBC drivers would truly enable modern data-driven Java applications to take advantage of years of innovation in database features, data access models, and virtualization technologies--in many cases without requiring code changes. This in turn would save organizations considerable time and money enhancing their modern data-driven Java applications by expanding feature sets and improving performance and reliability without having to make major changes to those applications.
Jesse Davis is a Senior Program Manager at Progress|DataDirect, responsible for product development initiatives and forward looking research. Jesse is an active member of the JDBC Expert Group, working on the next version of JDBC.
The following background is prerequisite for complete understanding of this article:
basic knowledge about web service simulation
understanding of basic servlet technology concepts
basic understanding of XML
See the Resources section for references on these technologies.
Introduction
Web service simulation is a growing need for every web service based assignment. Many of the assignments do not have the ready-to-use web service available during development stage, so the developers try to write their own mock implementation. A typical way of simulating a web service is:
Using a bottom up approach, generate the artifacts from WSDL.
Write the logic to choose the alternate response.
Deploy to some server.
This is a common mechanism for simulating each service, and this effort is repeated for each simulation. Suppose you have 1000 web services: you have to repeat these three steps 1000 times. However, these can be avoided by writing one servlet which accepts all soap input messages and generates the response file name using the message content. This way, there is no need to create a web service for each WSDL, resulting in lot of time and money savings. Let's look at the some common cons of the standard web service simulation approach.
[Note: This article only provides conceptual knowledge. You need to do your own implementation.]
Drawbacks of the common web service simulation approach
As discussed in the introduction section, the standard three steps are typically repeated for each web service simulation. Buth this method has to the following drawbacks:
Effort Repetition/Time consumed for the three steps
Effort for defect resolution in simulation itself
Deployment to servers (Generally, large projects have different environments, for example, Development, QA, etc). It also constitutes some effort
Of course, these are not all the drawbacks. However, some common issues can be mitigated with clever design and simulation. In the next section, I will discuss one of the web service simulation design practices that can mitigate these issues.
Web service simulation - designing using servlets
Let's go into the basics of web services and soap envelopes. The intended message resides in the soap body and is based on the message/content of the body; the response from the file system is picked up and can be returned to the caller.
This task simply can be achieved with servlets using following steps.
Extract the soap envelop from input stream.
Retrieve the first node of soap body.
Apply the algorithm to generate the response file name using input message. (I'll discuss one of the algorithm in following sections).
Read the response from file system.
Prepare the soap envelop and send it to the caller
Let's discuss the algorithm to generate file name using input message.
Response File Name Generation algorithm
Let's discuss the algorithm using one example: the input SOAP message as shown in Listing 1.
Note 1 - Expected response file to be picked from file system is findPlace_redlands_G.xml Note 2 - Careful observations of the soap envelope suggest that the expected response file name convention is findPlace_ placeName_ filterType.xml
Let's understand this convention:
findPlace is the first local node name of the soap body
placeName is the child of findPlace (its xpath is //m:findPlace/placeName)
filterType is the child of the node placeFinderOptions (its xpath is //m:findPlace/placeFinderOptions/filterType)
Concatenating these three xpaths yields the expected response file name findPlace_redlands_G.xml. So, the crux of the algorithm is to use xpath to retrieve the node values and concatenate them. In the following section, I'll discuss the high level design & implementation to achieve this.
Designing the fully configurable algorithm
The heart of the idea is now how to achieve the above mentioned algorithm in a configurable manner so that there should not be any need to write any java code -- in other words 100% configurable and no deployment required for any change.
To achieve this, let us define XSD/XML of the form as in Listing 2. It is just a sample XML and you can define your own XML structure. Of course, you will have to write your one time xml parser/processor to process this XML.
Here is the basic defination of XML element and attribute used in Listing 2:
servicename - It is an attribute representing the name of the web service
methodName - It is an attribute representing the name of the method inside the webservice
cfg:constant - It specifies the constant value to be used for file name generation
cfg:xpath - Specify the Xpath to node whose value will be used as a part of file name
Let's apply the algorithm using the Listing 2 XML.
Web service client sends a request to simulation servlet (Say WebServiceSimulatorServlet)
Web service simulator servlet extracts the first node from received soap body. This node is the actual web service message.
WebServiceSimulatorServlet calls the FileNameGenerator component to generate the response file name (It is the component which actually implements the file name generation algorithm. You need to write your own component)
FileNameGenerator uses the Listing 2 XML to generate the file name. It reads the XML, apply the xpath/xsl/etc on the input message received from servlet and concatenates the all values to generate the file name.
FileNameGenerator returns the file name to the WebServiceSimulatorServlet.
WebServiceSimulatorServlet reads the response from file system
WebServiceSimulatorServlet prepares the soap envelop and returns it to the caller.
The web service simulation has been achieved using a simple mechanism. During the journey key findings are:
Servlet to simulate web service.
Alter response file name generation logic can be done using simple XML logic.
You need to write your own XML structure to achieve this. You can customize my XSD to accomplish your task.
This logic needs to be developed once and afterwards there is no java coding is required. It's fully configurable which saves lot of effort, time and money.
Let's follow some good design and save the effort, time and money. You can find a sample XSD design to make a configurable web service simulator.
Adhir Mehta is Technical Solution Architect. He has experienced in full life cycle of software design process, including requirement definitions, initial analysis, architecture, design, implementation, testing and maintenance with strong analytical and problem solving skills.
If you use Maven, or even if you just use Maven repositories for your dependency management, you should be using a Maven Repository Manager. It's like using a kayak without paddles: you'll get there eventually without them, but your life will be much easier if you are properly equipped.
In this article, we'll be looking at some of the things a repository manager can do for you. A correctly-configured repository manager can speed up your builds, save bandwidth, help you share artifacts within your organization, and give you better control as to what dependencies are used in your projects and where they are coming from. It can also play a key role in your development infrastructure, helping you set up a fully-blown automated build and deployment pipeline.
There are currently three main Maven repository managers on the market. Archiva is a light-weight repository manager in the Apache fold. Artifactory is a powerful and quite innovative product from JFrog. And Nexus is a powerful, flexible, and superbly documented repository manager, this time from Sonatype, the company behind Maven. All are free and open source, though both Nexus and Artifactory have professional versions with extra features aimed at enterprise requirements. Most of the examples in this article will be using Nexus and it's commercial cousin Nexus Pro, though many of the techniques and general approaches are also applicable to the other products.
So read on, and learn how a repository manager can simplify your life as a software developer! And if you are already using a repository manager, this article might give you some tips as to how to get the most out of your repository.
Why use a Repository Manager
Probably the most fundamental role of a repository manager is to act as a proxy/cache between you and the internet. One of the most important features of Maven is the notion of declarative dependency management. Indeed, in a Maven project, you don't store the JAR files your project needs in a lib directory within your project - rather you list the dependencies you need directly in your build script. Ant users can also use declarative dependency management, either by using the Maven ant libraries or by using Ivy.
By default, Maven will attempt to download any dependencies it needs from public repositories on the internet, such as the Maven Central repository or the Codehaus repository. Any given jar file is only downloaded once, and cached on your workstation, no matter how many projects need it. And that's just fine if you are working alone. However, software development is a collaborative game, and most of us work in teams. So every developer will have to download the dependencies from the internet separately. In addition, Maven itself also downloads its own dependencies, so in a team of any size the quantity of downloaded files, and the time taken to download them, can mount up very quickly.
The first role of any Maven repository manager is to optimize this process (see Figure 1). It sits between your developer workstation and the internet repositories. Rather than going directly to the internet to download the required dependencies, Maven goes to the repository manager. Repository managers cache the files they download, so if the repository manager has already downloaded the dependency before, it can serve it out directly. If not, it goes to the internet to get it. In terms of overall build performance and consumed bandwidth, the gains are enormous.
Figure 1. A Repository Manager acts as a proxy server between you and the internet
Finer control on your downloads
But the benefits don't stop at economizing bandwidth. Once the repository manager becomes the central point of access for Maven dependencies within your organization, you can also use it to control where these dependencies come from, in much the same way as an internet proxy controls which web sites users can view. Indeed, many organizations like to have a clear visibility and control over what public repositories developers are using, and a repository manager can provide just that. Developers can no longer add arbitrary public repositories into their pom files - all dependencies must come from the repository manager, and all public repositories are configured and managed inside the repository manager. This also has the pleasant side effect of simplifying the repository configuration on the developer machines: you no longer need to maintain a long list of public repositories in each developer's settings.xml file.
This is typically done using the notion of Groups (in Nexus) or Virtual Repositories (in Artifactory). Repositories are organized into groups, so that a single URL (such as 'http://myserver:8081/nexus/content/groups/public/') provides access to an arbitrary list of real repositories (see Figure 2). From the point of view of the Maven user, all dependencies come from this single URL. However, behind the scenes, you can associate (and manage) many physical repositories. This gives organizations much better control over which repositories they want to authorize.
Figure 2. Repository Managers hide several public and internal repository URLs behind a single point of access.
In some organizations, such as in Defense or in the medical sector, requirements are even stricter. Developers cannot add arbitrary new versions of Spring or Hibernate, for example: new libraries must first be approved by an Enterprise Architect or Security Specialist before they can be deployed to production. Some organizations even require vetting of new libraries before they can be used by development teams. Another common requirement is to be able to vet artifacts provided by external vendors before using them internally.
A repository manager can help to rationalize and organize this process. In organizations like this, developers may only be allowed to use a repository containing approved dependencies, for example. Using Artifactory, you could achieve this by copying or moving artifacts between repositories by hand. The Nexus Procurement Suite, available in Nexus Pro, provides more sophisticated support for several procurement scenarios, including both approving individual JAR files and verifying entire configurations before they go into production.
Figure 3. Using a Repository Manager to allow only selected JAR files to be used for development.
This centralized management also opens the way to other forms of build optimization. For example, Nexus also has the notion of Routes, a very flexible feature which lets you give Nexus hints about where certain artifacts can be found. The latest version of Artifactory has a similar concept in the form of Include/Exclude patterns for each remote proxy. In my own repository, for example, internal artifacts (in the 'com.wakaleo' domain) are deployed to the local Snapshots and Releases repositories. Likewise, no 'org.apache' artifacts are ever deployed to these repositories - it would be a waste of time to look for them there. So, as shown in Figure 4 I have configured Nexus to only look for the internal artifacts in the Snapshots and Releases repositories, and never to look for the Apache artifacts in these repositories. In a similar vein, Nexus also lets you set up mirrors for your repositories, so that requests to a particular repository will go to a closer or faster mirror instead. This sort of fine-tuning reduces the number of places Nexus needs to look for a given artifact, and speeds up performance accordingly.
Figure 4. Setting up Routes in Nexus to optimize downloads by giving it hints about where to find certain artifacts.
The Repository Manager as part of the build lifecycle
But that's not all a repository manager can do for you. The second fundamental function of a repository manager is to make it easier to share build artifacts (JAR files, WAR files, and so forth) within an organization. You do this by setting up hosted repositories, internal repositories that are designed to store your own internal JAR files as well as proprietary JAR files not available from the public repositories.
Internal artifacts are typically released and deployed following a well-defined build lifecycle. For example, while work is in progress on a particular version, releases will only be made available for team members. Once the product is ready for further testing, it might be released to a test or UAT (User Acceptance Testing) platform, and then to production. Depending on your infrastructure setup, your repository manager can play a key role in this process.
In Maven development, for instance, it is good practice to distinguish between SNAPSHOT versions, which are under active development and are not considered stable or finalized, and RELEASE versions, which are tested and officially made public with a unique version number. A common best practice which is well supported by all the repository managers involves deploying SNAPSHOT versions and RELEASE versions to different hosted repositories within your repository manager.
Security considerations are also important. Larger organizations may want to limit deployment rights for projects, so that only developers from a given project team are allowed to deploy snapshot or release artifacts for that project to the repository. One way to do this would be to set up a separate repository for each project, but this is not a very scalable solution. A better approach is to define rules defining who is allowed to deploy to different parts of the repository. Nexus in particular provides a particularly fine-grained security model that lets you specify rules like this using a combination of regular expressions and pre-defined 'privileges'. The Apache repository is a good example of this - all of the release artifacts are stored in a single hosted Nexus repository, but developers for each of the many hosted projects can only deploy artifacts for their own projects.
For larger organizations, it is often important to be able to work with an existing LDAP repository when configuring what users are allowed to do with the repository. Artifactory supports basic authentication LDAP. As of its latest version (1.4.2), Nexus comes with sophisticated LDAP support, including both authentication and support for more advanced features such as mapping LDAP groups to Nexus roles.
The repository manager can also play a more active role in the build lifecycle. Typically, once a version has been released, it needs to be tested and validated by QA before it can be deployed to production. You can do this by using different repositories for different build promotion stages. Smaller organizations can often get away with a simple architecture consisting of just a snapshots repository (for work in progress) and a release repository (for release candidates and official releases). However, larger organizations will usually need a more sophisticated build promotion strategy.
Figure 5 illustrates one such possible build promotion strategy. In this architecture, snapshot builds are automatically deployed to the Enterprise Snapshots repository, to be used by developers within the project team itself. Release Candidate builds are prepared using the Maven Release plugin, and deployed to the Release Candidates repository. Builds in this repository can be deployed to System and UAT (User Acceptance Testing) testing environments. Once a version has been approved in the UAT environment, it can be promoted and deployed to the official Enterprise Releases repository, from where it can be deployed to production. This staged approach ensures that only properly validated versions can be deployed to production environments.
Figure 5. An example of a build promotion architecture.
In practice, implementing this sort of build promotion architecture requires a little thought and often some manual scripting. Indeed, the build promotion process itself can be tricky. You can rebuild and deploy from the source code for each platform, or redeploy manually to another repository; some repository managers like Artifactory even let you manually copy or move artifacts between repositories, though duplicating the same artifact between repositories is not considered to be good practice.
Nexus Pro, the commercial version of Nexus, comes with the Staging Suite which provides more sophisticated support for the build promotion process. The Staging Suite works by intercepting certain deployed artifacts and placing them in a special staging repository, dynamically-created by Nexus. For example, you might set up a staging configuration to intercept all artifacts from the com.mycompany.killerapp project. Whenever a developer deploys an artifact for this project, Nexus creates a special staging repository and places the newly deployed artifacts here (see Figure 6).
Figure 6. Staged artifacts are deployed to a special repository created by Nexus.
Once all the artifacts are deployed, the administrator can lock down the staging repository and make it available for further testing (for example, via an automated deployment to a QA platform). One approach is to make the staging repository available in a special Release Candidate repository group, from which it can be deployed to the various UAT and other testing environments (see Figure 7). At this point, other interested users will be notified that the artifacts have been staged.
Figure 7. Adding the staged repository to the Release Candidate repository group
If the testing is conclusive, the administrator can promote the build and deploy it to it's final repository (see Figure 8). If not, the administrator simply drops the staging repository and the developer redeploys a fixed version later on.
Figure 8. Promoting an artifact in Nexus.
There is also a Maven plugin for the Nexus Staging plugin, allowing this process to be integrated into Hudson or another CI tool.
This whole process makes generating releases from Maven projects a relatively smooth and painless operation. It is also a good example of how a repository manager is not just a directory of JAR files, but can underpin your whole deployment lifecycle as well.
Keeping your repository clean
A repository manager can also help you keep your repository clean. For example, automated builds can take up a lot of disk space, especially if you are generating regular snapshot builds. A repository manager will help you avoid wasting space with excessive numbers of snapshots. Nexus, for example, will regularly delete older snapshots, with the option of deleting all the snapshots for a particular artifact once that artifact is released.
Conclusion
A Maven repository manager is much more than a file server. In addition to the obvious performance benefits, using a repository manager also gives you more control over what artifacts are being downloaded, and from where. More advanced features such as Procurement can give an even finer control over the dependencies being used in development and/or being deployed to production.
A repository manager also can and should play a key role in your build promotion strategy. For smaller organizations, a simple snapshot/release repository setup may be enough, whereas larger organizations will often want to use the repository manager to underpin the entire build promotion and staging process.
John Ferguson Smart is a freelance consultant specialising in Enterprise Java, Web Development, and Open Source technologies, currently based in Wellington, New Zealand.
jQuery: Novice to Ninja is a compilation of best-practice jQuery solutions to meet the most challenging JavaScript problems. In this question-and-answer book on jQuery, you'll find a cookbook of ready-to-go solutions to help breathe life into your web page. All code used to create each solution is available for download and guaranteed to be simple, efficient and cross-browser compatible.
Get 97 short and extremely useful tips from some of the most experienced and respected practitioners in the industry, including Uncle Bob Martin, Scott Meyers, Dan North, Linda Rising, Udi Dahan, Neal Ford, and many more. They encourage you to stretch yourself by learning new languages, looking at problems in new ways, following specific practices, taking responsibility for your work, and becoming as good at the entire craft of programming as you possibly can.
Get 97 short and extremely useful tips from some of the most experienced and respected practitioners in the industry, including Uncle Bob Martin, Scott Meyers, Dan North, Linda Rising, Udi Dahan, Neal Ford, and many more. They encourage you to stretch yourself by learning new languages, looking at problems in new ways, following specific practices, taking responsibility for your work, and becoming as good at the entire craft of programming as you possibly can.
There's a good article by Ed Ort about deploying RIAs in mixed environments on the Sun Developer Network. It's worth a read as a reminder to always check to see if the application you've written has any specific requirements - does it need a certain version of the JRE? Does it need the latest plug-in? He focuses on using the deployment toolkit to setup an environment correctly for a rich internet application.
The results of the Reader's Choice Awards 2010 have been announced. Congratulations to the winners. I heard there were some very close races to win some of the categories. The following topics will take you to the category winners:
Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. javasight is independent of Sun Microsystems, Inc.