One of our visitors (Priyank) asked these questions via email. Thanks Priyank for your participation.
Can we have two java.lang.Class instances of the same Type?
Yeah... we can have any number of java.lang.Class instances of the same type provided we get the Type loaded by a different ClassLoader instance everytime. Please note that even if we use the same ClassLoader class, but if we use different instances of that class to load a Java Type then each time we'll get a different java.lang.Class instance for the loaded Type. If no ClassLoader instance is explicitly specified then the default ClassLoader instance (Application Class Loader for user classes - Read more in this article - Class Loaders in Java >>) is used which the user doesn't need to create instead JVM creates and maintains for the users.
The loadClass method of the ClassLoader class is used to load any Java Type. This method has two variants:
As you would have noticed that both these methods are instance methods and hence they can be called only on an instance of type ClassLoader. You can create your own instances of any valid ClassLoader type and call the loadClass method to load a Java class to have separate java.lang.Class instances every time you use a separate instance of type ClassLoader to call the loadClass method upon.
To understand how a Type is loaded, linked and initialized in Java you may like to read a separate article discussing this in detail - Loading, Linking, & Initialization of Types in Java >>
How can we change the properties of a singleton object?
Well... it's no different than changing the properties of any other object. The convention is to have public setter methods for all the mutable fields. Singleton doeesn't really play any role here. After all that's also an object (though we have only one shared copy of it) and it can be changed by calling the corresponding setter methods on that instance. I hope this answers your question otherwise please let me know if you meant something else.
Does volatile maintain mutual exclusion as well?
No... volatile doesn't maintain mutual exclusion. Declaring a variable volatile simply solves the communication problem i.e., every thread will read the last modified value of the variable. To implement this the optimizer simply skips creating local cache variables (local to the thread) of any volatile variable and all threads need to read the value of such a variable (of course the variable should be shared) from one copy only.
Synchronization helps solving two major issues in a multithreading environment - mutual exclusion and communication problem. volatile is a simpler and faster way of overcoming just the latter one. In case your multithreading requirements doesn't need mutual exclusion (for example: if you're sure that at one point of time only one of the several threads will try to modify the value of a shared variable) then using a synchronized block will be a waste as such a simple case can be more efficiently solved by using volatile only. As already explained that it's internally implemented by enforcing the compiler/optimizer to have only one copy of the variable and donesn't really need any locking/unlocking mechanism (as required by synchronization) hence it'll always be significantly faster than synchronization. More about synchronization in this article - Synchronization in Java >>
Note: Hey Priyank, feel free to correct me in case I misinterpreted any of your questions or if you're not satisfied with the answers.
Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.
Wednesday, August 27, 2008
Diff java.lang.Class instances for the same Type ?
Tuesday, August 26, 2008
Using Reg Ex to identify Strings representing int/float
Write a Java program using RegEx to identify a String representing int/float (Whitespaces allowed)
Some of you may think why to use Reg Ex to identify Strings reprenting numbers as Java has other options as including the well known Scanner class introduced in Java 5.0, but the point here is not to discuss if we really need to use Reg Ex instead the idea is to make you familiar with usage of Regular Expressions in Java.
If you are comfortable with Regular Expression then you can straightaway go to the Java code doing the required task - Java Program to test Strings using RegEx >>. But, if you want to have a look at how the regular expressions were built then please proceed with this article. The article gives a step-by-step explanation of how to build Regular Expressions to validate Strings representing int or float values - with or without Whitepaces. In this article I'm considering only Blank Spaces as Whitespaces. For other whitespaces you may simply need to tweak the code a bit.
Regular Expression for testing Strings containing int - we will first try to build Regular Expressions for Basic int processing which will be able to validate only those Strings which contain a valid int value without any Whitespaces. Then we'll move on to build a regular expression which will be able to validate Strings containing int values having leading or trailing Whitespaces. Finally we'll move on to build a regular expression which will be able to validate any String representing an int value with leading, trailing and/or embedded Whitespaces.
RegEx for basic int processing: in this case were are considering the String doesn't contain any Whitespaces. Find below the code-snippet which follows an explanation of every bit of it
...
String intString = "-100";
Pattern patternForIntWithoutWSH = Pattern.compile( "((-?+)(\\+{0,1}+))([0-9]+)" );
Matcher mi = patternForIntWithoutWSH.matcher(intString);
boolean result = mi.matches(); // ... returns true
...
A valid int value can contain only two non-digit characters - a mandatory minus sign (-) for negative int valus and an optional plus sign (+) for positive int values. And any of the two non-digit characters will always precede the actual int value which will be a sequence of one or more digits. We'll divide the task into multiple sub-tasks and form the RegEx for all those sub-tasks which will be used to form the actual RegEx. The sub-tasks in this case are:-
- Identify occurrences of minus (-) or plus (+) signs: This sub-task can again be broken down into three sub-sub-tasks: (i) to ensure that if a minus sign occurs it occurs only once - the Reg Ex for this will be -?+ (ii) to ensure that a valid positive int can either have one and only one plus sign or no sign at all - the Reg Ex for this will be \+{0,1}+ (iii) to ensure that either sub-sub-task (i) happens or sub-sub-task (ii) happens in case and not both - the Reg Ex in this case will be (-?+)(\+{0,1}+)
- Identify any digit: The Reg Ex will be [0-9]
- Identify a sequence of one or more digits: The Reg Ex in this case will be [0-9]+ and NOT [0-9]* as the latter will allow an empty String or a String having only -/+ signs
Now that we have regular expressions of the sub-sub-tasks then we can easily form the complete regular expression which can test Strings having basic int values and this Regular Expression will be: ((-?+)(\+{0,1}+))([0-9]+)
RegEx for int values having Leading and/or Trailing Blanks:
...
String iswlotw = " - 1007 ";
Pattern patternForIntWithWSH = Pattern.compile( "([ ]*)((-?+)(\\+{0,1}+))([ ]*)([0-9]+)([ ]*)" );Matcher mi1 = patternForIntWithWSH.matcher(iswlotw);
...
It's easy to understand that we can use [ ]* to represent any number of Blank Spaces. Note that these spaces can be either leading or trailing to the actual int value. These spaces can also precede and trail the minus (-) or plus (+) sign and that way it can be embedded between minus/plus sign and the actual int value. That means we'll require to add [ ]* in the above Regular Expression before and after every single logical unit identifying a valid character and this will get us the revised regular expression as: ([ ]*)((-?+)(\+{0,1}+))([ ]*)([0-9]+)([ ]*)
RegEx for int values having Embedded Blanks as well:
...
String iscomplete = " - 1 0 ";
Pattern patternForIntWithCompleteWSH = Pattern.compile( "([ ]*)((-?+)(\\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)" );Matcher mi2 = patternForIntWithCompleteWSH.matcher(iscomplete);
...
the previous regular expression will not work for int values having embedded blanks like "-1 890". To make this capable of identifying such String as well we will require to replace the part "([0-9]+)" with "([0-9]+)([ 0-9 ]*)". Here the presence of ([0-9]+) ensures that at least one digit is always present. Why can't only ([ 0-9 ]+) work here? Because this will return true for a String (for example: " - ") having only minus/plus sign and blank spaces which of course is incorrect. Though it'll correctly return false for these Strings: "-", "+", "". The final regular expression for identifying any int value represented by a String will be: ([ ]*)((-?+)(\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)
Regular Expression for identifying float values: regular expression of identifying float values should be able to identify the occurrence of zero or one decimal point (.) in addition to identifying a valid int value before and after that decimal point (if it exists). Another point to note here is that the minus (-) or plus (+) sign (if at all any one of the two exist) can only precede the int value before the decimal point. Find below the code snippet:-
...
String floatString = " -1 007 . 0 5 ";
Pattern patternForFloat = Pattern.compile( "([ ]*)((-?+)(\\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)((\\.)([ ]*[0-9]+))?+([ ]*)([ 0-9 ]*)([ ]*)" );Matcher mf = patternForFloat.matcher(floatString);
...
((\\.)([ ]*[0-9]+))?+ part of the above regular expression is actually doing the identification of a possible decimal point ( the character '.' has a special meaning and hence escape character '\' is preceding this) and if the decimal point exists then we need to ensure that at least one digit follows it and that responsibility is being carried off by ([ ]*[0-9]+) sub-part.
In case of floating value identification we need to ensure that the decimal point if exists then it is preceded as well as followed by at least one digit each. Strings like " - 9 . ", " - .8 ", " - . ", etc. should not be allowed. This has been taken care by adding ([0-9]+) before and after the decimal point check. Before the decimal-point check we anyway need it as a float processing regular expression should successfully identify an int value as well. A logical AND of (\\.) and ([0-9]+) ensures that a mandatory digit will be checked only if a decimal point exists. I hope we all can now move to the complete code listing - Java program using Reg Ex to identify int/float >>
Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.
Java Code: Using Reg Ex to identify Strings rep of int/float
Using Reg Ex to identify String representation of int/float (Whitespaces allowed)
Find below a complete Java program illustrating the usage of Regular Expressions (introduced in Java 1.4) to identify String representations of int or float values. The program first tries to identify Strings representing only a valid int value without any leading, trailing or embedded whitespaces and subsequently moves on to identify all possible String representations of int/float values with whitespaces embedded anywhere in it. Download the code as a PDF doc if the below listing looks very clumsy. Unfortunately I'm yet to find a better way to display source code in Blogger.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExStringToNumTest {
public static void main(String[] args) {
//... basic int String having no Whitespaces
String intString = "-100"; //... positive test case
String intString_ntc = "-"; //... negative test case
Pattern patternForIntWithoutWSH = Pattern.compile( "((-?+)|(\\+{0,1}+))([0-9]+)" );
Matcher mi = patternForIntWithoutWSH.matcher(intString);
System.out.println("RegEx for int without Whitespaces - ((-?+)|(\\+{0,1}+))([0-9]+)");
System.out.println("Positive Test Case - For String \"" + intString + "\" return value: " + mi.matches());
Matcher mi_ntc = patternForIntWithoutWSH.matcher(intString_ntc);
System.out.println("Negative Test Case - For String \"" + intString_ntc + "\" return value: " + mi_ntc.matches());
//... int String with Leading or Trailing Whitespaces
String iswlotw = " - 1007 "; //... positive test case
String iswlotw_ntc = " - "; //... negative test case
Pattern patternForIntWithWSH = Pattern.compile( "([ ]*)((-?+)|(\\+{0,1}+))([ ]*)([0-9]+)([ ]*)" );
Matcher mi1 = patternForIntWithWSH.matcher(iswlotw);
System.out.println("\nRegEx for int with Leading/Trailing Whitespaces - ([ ]*)((-?+)|(\\+{0,1}+))([ ]*)([0-9]+)([ ]*)");
System.out.println("Positive Test Case - For String \"" + iswlotw + "\" return value: " + mi1.matches());
Matcher mi1_ntc = patternForIntWithWSH.matcher(iswlotw_ntc);
System.out.println("Negative Test Case - For String \"" + iswlotw_ntc + "\" return value: " + mi1_ntc.matches());
//... int String with complete Whitespace Handling - Embedded and/or Leading/Trailing
String iscomplete = " - 2 0 " +
"0 1 " +
" 009"; //... positive test case
String iscomplete_ntc = " - "; //... negative test case
Pattern patternForIntWithCompleteWSH = Pattern.compile( "([ ]*)((-?+)|(\\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)" );
Matcher mi2 = patternForIntWithCompleteWSH.matcher(iscomplete);
System.out.println("\nRegEx for complete int processing - ([ ]*)((-?+)|(\\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)");
System.out.println("Positive Test Case - for String \"" + iscomplete + "\" returns: " + mi2.matches());
Matcher mi2_ntc = patternForIntWithCompleteWSH.matcher(iscomplete_ntc);
System.out.println("Negative Test Case - For String \"" + iscomplete_ntc + "\" return value: " + mi2_ntc.matches());
//... float String with complete Whitespace Handling
String floatString = " -1 007 . 0 5 "; //... positive test case
String floatString_ntc1 = " - 9 . "; //... negative test case - 1
String floatString_ntc2 = " - . 8 "; //... negative test case - 2
String floatString_ntc3 = " - . "; //... negative test case - 3
Pattern patternForFloat = Pattern.compile( "([ ]*)((-?+)|(\\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)((\\.)([ ]*[0-9]+))?+([ ]*)([ 0-9 ]*)([ ]*)" );
Matcher mf = patternForFloat.matcher(floatString);
System.out.println("\nRegEx for complete float processing - ([ ]*)((-?+)|(\\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)((\\.)([0-9]+))?+([ ]*)([ 0-9 ]*)([ ]*)");
System.out.println("Positive Test Case - For String \"" + floatString + "\" returns: " + mf.matches());
Matcher mf_ntc1 = patternForFloat.matcher(floatString_ntc1);
System.out.println("Negative Test Case #1 - For String \"" + floatString_ntc1 + "\" return value: " + mf_ntc1.matches());
Matcher mf_ntc2 = patternForFloat.matcher(floatString_ntc2);
System.out.println("Negative Test Case #2 - For String \"" + floatString_ntc2 + "\" returns: " + mf_ntc2.matches());
Matcher mf_ntc3 = patternForFloat.matcher(floatString_ntc3);
System.out.println("Negative Test Case #3 - For String \"" + floatString_ntc3 + "\" returns: " + mf_ntc3.matches());
}
}
Output:-
RegEx for int without Whitespaces - ((-?+)|(\+{0,1}+))([0-9]+)
Positive Test Case - For String "-100" return value: true
Negative Test Case - For String "-" return value: false
RegEx for int with Leading/Trailing Whitespaces - ([ ]*)((-?+)|(\+{0,1}+))([ ]*)([0-9]+)([ ]*)
Positive Test Case - For String " - 1007 " return value: true
Negative Test Case - For String " - " return value: false
RegEx for complete int processing - ([ ]*)((-?+)|(\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)
Positive Test Case - for String " - 2 0 0 1 009" returns: true
Negative Test Case - For String " - " return value: false
RegEx for complete float processing - ([ ]*)((-?+)|(\+{0,1}+))([ ]*)([0-9]+)([ 0-9 ]*)([ ]*)((\.)([0-9]+))?+([ ]*)([ 0-9 ]*)([ ]*)
Positive Test Case - For String " -1 007 . 0 5 " returns: true
Negative Test Case #1 - For String " - 9 . " return value: false
Negative Test Case #2 - For String " - . 8 " returns: false
Negative Test Case #3 - For String " - . " returns: false
If you are not quite familiar with Regular Expressions and want a step by step explanation of this program then please read this article - Using Reg Ex to identify Strings containing int/float >>
Monday, August 18, 2008
zip vs jar. When to use what? Which one is performant?
zip vs jar. When to use what? Which one is performant?
jar - the default 'jar' utility (and a file format as well. Read more about the JAR file format in this article - JAR, WAR, and EAR >>) is the Sun's implementation which has been written in Java language. This is obviously slower (though only slightly) than those 'jar' utilities which have been written using C language. 'fastjar' is an example of a 'jar' tool written in C. Though it has its own limitations, but it's slightly faster than the default 'jar' implementation supplied by Sun Microsystems with JDK.
'jar' mainly supports class, audio, and image file formats and whenever a new file is added to a jar file then the utility first checks the format of the file and accordingly it may need to the MANIFEST file or any other indexes if applicable. Read more about the manifest file in this article - MANIFEST file of a jar file >>
zip - this is a simple archiving and compressing tool (and a file format as well). In fact the JAR file is also internally archived and comprssed as a zip file only. Unlike a jar file it doesn't maintain any additional information about the files or the type of the files contained in the archive. Obviously this archiving tool is much more faster than 'jar', and hence this is recommended in the cases where the archiving of the files is all what the user needs.
jar vs zip
Thus we see that 'zip' will almost always have better performance and hence recommended if the user is interested only in archiving and 'jar' should be used only when the extra information supplied with the resultant JAR files are being used (or will be used in the future) by the application (or the tool) in some way or the other.
Wednesday, August 13, 2008
How many ways of creating objects in Java?
How many ways of creating objects in Java? Is there any other different way of creating objects in Java? I don't think that there is any other way. Using JNI may pop up as another possible way, but I don't think that JNI offers any different way of object creation due to the fact that JNI is not meant for object creation instead it's used for interacting with native methods written in some other languages (mainly in C/C++) and hence a Java class using JNI code is same as any other Java from object creation perspective. Therefore, I think it uses any one of the above mentioned approaches only - most commnonly the explicit 'new' calls. I personally don't have much exposure to JNI and I sincerely welcome comments from the JNI experts if they think otherwise.
Well... there aren't many different ways I suppose. But from an application programmer perspective here are the different possible ways of creating objects in Java:-
Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.
Tuesday, August 12, 2008
How can we access an unreachable object in Java?
Can we access an unreachable object in Java?
Yeah... we can. Sounds strange? But, it's true. We can access an unreachable object in Java.
This can be done by overriding the finalize() method and inside the method we can assign the reference 'this' to some other active reference and this way the unreachable object becomes reachable again which can be accessed like any other object. However this is not a good practice and it's seldom used (if at all).
What's finalization in Java and what's it used for?
In Java it's mainly used for doing the postmortem cleanup activities particularly used for reclaiming native resources or any other non-memory resources which can't directly be recollected by the Garbage Collector.
How the finalization of an object happens internally?
protected void finalize() throws Throwable is the signature of the finalize() method in the Object class and whenever any class overrides this method then an object of that class is internally marked by the JVM as finalizable. If such an object becomes unreachable then the Garbage Collector adds it to the JVM's finalization queue. It also makes sure that all the objects reachable from that object are also retained as it can't be sure what all objects may be accessed from inside the finalize() method. Now the object is dequeued from the finalization queue and the finalize() method is executed on that object. Once the control exits from the finalize() method then the object is considered to be finalized which is again tested by the Garbage Collector and if the GC finds that the finalilzed object is unreachable then it reclaims the memory space occupied by that object and also the spaces occupied by other unreachable objects which were retained simply because they were reachable from the finalizable object.
You can easily deduce that such a lengthy process obviously takes time and consequently slows down the performance. Hence it's always advisable to use (override) the finalize() judiciously.
What if the super class is finalizable but not the sub class?
This is not possible as the sub class will automatically become finalizable by inheriting the finalize() method from the super class. Do consider the consequences thoroughly before making any class finalizable otherwise you may end up with memory renetion problems. For example: if a super class is finalizable and sub class which is not explicitly finalizable is having fields occupying huge memory chunks then reclamation of memory occupied by a sub class instance will be delayed till the associated super class instance gets finalized. How to deal with such a situation? Well... you can use composition in stead of inheritance to avoid this problem. This will make sure that reclaimation of only the field of the finalizable class type gets delayed and not the entire object. You can easily have a method disposing the other fields which otherwise would have kept occupying the precious memory for no real purpose. This approach is quite useful in case you are using a third-party finalizable class.
In case you are writing the class yourself then you may break the class into two class - one having the code which really require finalization (i.e., the code which uses native or other non-memory resources) and the other class which simply uses the former class as a member and other non-finalizable members. Now you only need to make the former class finalizable and not the latter.
The bottom line is that don't make any class finalizable unless you have a very good reason behind it and in case you need to make then also make sure that the finalization process doesn't really cause unnecessary memory-renetion.
Is finalization guaranteed? What's the actual contract?
No... it's not guaranteed that the finalization of all the finalizable objects will happen before they are reclaimed so it obviously doesn't make sense to put any other code except the clean-up code inside the finalize() method. In fact finalizer is mainly used for having clean-up code for non-memory and native resources only.
The JVM doesn't guarantee the actual order in which the finalization of the finalizable objects will take place. All the finalizers either from the application or from the libraries are treated equally with no exception.
The JVM doesn't guarantee which thread will invoke the finalize() method of a particular object and only guarantees that the thread which will invoke the method will not have any user-visible synchronization lock at the time of finalize() invocation.
Grrr... so much of non-determinism involved. Yeah... unfortunately it's like this only. So think twice before making any class finalizable.
What if the finalize() method throws any Exception?
If an uncaught exception is thrown from within the finalize() method then it's simply ignored and the finalization of that object terminates immediately.
Any alternative to Finalization in Java?
One possible alternative is to use weak references instead of finalization. This will ensure that the programmer has a complete control over how to reclaim the resources, how to prioritize the reclaimation process (may be based on the availability of a particular native or non-memory resource), etc. We'll discuss about the weak references and about this approach in some other article.
Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.
Generate unique primary key automatically in MySQL
How to generate unique primary key automatically for every record in MySQL?
Note: This question was asked by one anonymous visitor as a comment. Sharing the response as a separate article to make it more visible to our visitors.
I've not used MySQL for quite a while now. When I used MySQL some 3-4 years back I probably couldn't find any direct support for Sequences in MySQL (unlike Oracle) and hence I used the AUTO_INCREMENT feature which served my purpose of automatic unique ID generation.
What I could interpret from your question that you simply want a mechanism to generate unique numbers which will serve as primary keys of the records being inserted in the table. If this is the case then it's very easy to implement using the AUTO_INCREMENT feature only. You just need to append the 'AUTO_INCREMENT' clause to the primary key column of the table. For example:-
CREATE TABLE table_name(
id INT PRIMARY KEY AUTO_INCREMENT,
column_name1 ...,
...);
Once the table is created you can set the initial value of the AUTO_INCREMENT counter by using the following statement:-
ALTER TABLE table_name AUTO_INCREMENT = value;
You can of course not specify a value less than or equal to any value that has already been used for that table. In such a case MyISAM resets the AUTO_INCREMENT counter to the current maximum value plus one. InnoDB might also take care of it accordingly. But it's always better to avoid setting such a value and the start value is normally set in the very beginning before any insertion. From there on MySQL engine automatically increments the current maximum value by one to get the new unique number. The default value of the AUTO_INCREMENT counter is 1.
You can use LAST_INSERT_ID() to get the unique number generated by the previous INSERT opration executed on a table which had an AUTO_INCREMENT column. You can even pass an expression as an argument to the LAST_INSERT_ID() function. In this case the value of the argument will be returned by the function and the same value is remembered to be returned by the next invocation of the LAST_INSERT_ID() function. You may use this to create a table serving as a Sequence:-
CREATE TABLE sequence_table(
seq INT NOT NULL
);
Initialize the sequence counter by inserting a record:-
INSERT INTO sequence_table VALUES(100);
Updating the sequence and reading the value:-
UPDATE sequence_table SET seq = LAST_INSERT_ID(seq + 1);
SELECT LAST_INSERT_ID();
These are probably the two most commonly used mechanisms of implementing sequences. I guess the former suits your requirement better in most of the cases.
Friday, August 8, 2008
WSDL - Web Services Description Language
WSDL - Web Services Description Language
You may like to refresh your understanding of the Web Services by going through this article - Web Services - What, Why, Usage, & Shortcomings>>
The WSDL (Web Services Description Language) is a grammar which uses XML for describing all the details of a Web Service which a consumer may like to have for using that Web Service. These details are:-
- Message Exchanges - this is used to define the input and out message exchanges between the Web Service and the Consumer. Why to use a new language for it? Can't we use XML Schema to define such message exchanges? No... the XML Schema is not capable of describing it. Take one example to understand it - suppose you have two XML elements RequestMessage and ResponseMessage and if you want to specify that if the Consumer sends the RequestMessage then it will get the ResponseMessage. Now in this case XML Schema can't be used as it's not capable of describing the relation between the XML Elements. WSDL uses the concept of 'operations' to describe such a situation.
- Grouping of similar operations into interfaces - WSDL helps grouping similar operations into interfaces which can be mapped to the programmatic interfaces in object-oriented languages.
- Binding Specification - binding is actually a combination of an interface and the communication protocol and it's used to specify the concrete details of what actually travels on the wire. In addition to the interfaces and communication protocol, the binding is influenced by the Style of the Service (which can either be 'document' or 'RPC') and by the Encoding Mechanism (which can either be 'literal' or 'encoded'). For one interface we may have multiple binding for the simple reason that a binding is a combination of the interface and the communication protocol. So for the same interface we may have different bindings for TCP, HTTP, SMTP, etc. communication protocols. For every binding there will be a distinct URI each of which can be used to consume the Web Service.
In a nutshell we can say that WSDL uplifts the capabilities of XML Schema by providing a way of describing the message exchanges in form of operations and by providing a way of grouping similar operations into interfaces. It also facilitates the specification of the particular communication protocol, style, and encoding mechanism used by the Web Service. Every combination of the interface and communication protocol is represented by a binding and every binding will have a distinct URI. That means the same service may be consumed by using different communication protocols by simply using the corresponding URIs.
There are other techniques for describing the Web Services, but WS-I Basic Profile v1.0 makes it mandatory to use the WSDL and XML Schema for describing any Web Service. This ensures the interoprability at the service description layer.
A WSDL document is simply an XML document and hence it's quite easier for the developer to read, interpret and generated the code to consume the Web Service. We have many tools available by reputed vendors which can be directly used to consume any Web Service.
WSDL 1.1 is was being used as a de-facto standard until mid of the year 2007 when W3C came up with WSDL 1.2 which is more commonly known as WSDL 2.0 and the tools and infrastructure developers have already started following this version.
WSDL Elements
Find below the elements of a typical WSDL document:-
- types - this element is used to define an abstract type which will be used by the XML Schema.
- message - this element is used to define an abstract message and it may consist of multiple parts where each part may be of different type - either a built-in type or an abstract type defined by the 'types' element.
- portType - this element is used to define the interface by grouping similar operations together. As discussed above, one interface may be combined with multiple communication protocols to form different end-points (URIs) of the same service.
- binding - this element is used to specify the details of the communication protocol, style of service, and encoding mechanism for the particular URI (end-point) of a particulat portType element. One binding element is used to completely describe one URI for a particular portType element and hence one portType element may have multiple binding elements to have as many different end-points.
- service - this element is used to represent a collection of ports. A port is given a name and a binding is assigned to it which this port will expose. Now every port is given an URL which is used to access the service. Now if we have more than one binding element for the same portType element then we can simply have as many port elements in the serive element and assign all these port elements a distinct URL. The associated binding element for any URL will determine which communication protocol to consume the service will be used in that case.
Now that you know what all elements a WSDL doc may have and what these elements actually mean, check this Sample WSDL Document and try to identify and co-relate all the elements of it.
References
Security Model in Java and its evolution
Security Model in Java and its evolution
Java was originally designed for developing Network Applications and as we know that such applications are more prone to potential attacks hence a need for the Security Model was felt as one of the most important feature of the Java architecture.
Since the inception of the Java architecture, the Security Model has also evolved from the Basic Sandox to the rich security architecture for access control in Java 1.2 by supplying a concrete implementation of the Security Manager with the Java 2 Platform. The three major evolutions of the Security Model took place in Java 1.0, Java 1.1, and then in Java 1.2 which are briefly discussed below:-
- Security Model in Java 1.0 - the basic security model implementation was very restrictive for any untrusted code. Any applet downloaded from a remote untrusted machine was considered untrusted and hence such a code used to have a very limited set of priviledges on the client machine. This security model is commonly known as The Basic Sandbox where the term 'sandbox' represents a virtual box where the untrusted code will reside and that code can executed only within the boundaries of the sandbox. This is why the original sandbox based security model implementation in Java 1.0 restricted many activities for the untrusted code on the local machine. These restricted activities include Read/Write on the local disk, Createtion of a new process, Loading of a new dynamic library, etc. The untrusted code was not allowed to establish any network connection to any other host except the host it was downloaded from. Thus we can easily see that the untrusted code in Java 1.0 was having very limited access on the local machine which obviously limited the scope of even trustworthy applets as the security model in that version of Java was not able to differentiate between trustworthy and untrusted applets. Obviosuly a need arises to enable the security model with this capability and consequently the model was revised and made more capable in Java 1.1 which is discussed below.
A sample WSDL document
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:y="http://example.org/math/"
xmlns:ns="http://example.org/math/types/"
targetNamespace="http://example.org/math/">
<types>
<xs:schema targetNamespace="http://example.org/math/types/"
xmlns="http://example.org/math/types/"
elementFormDefault="unqualified" attributeFormDefault="unqualified">
<xs:complexType name="MathInput">
<xs:sequence>
<xs:element name="x" type="xs:double"/>
<xs:element name="y" type="xs:double"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MathOutput">
<xs:sequence>
<xs:element name="result" type="xs:double"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Add" type="MathInput"/>
<xs:element name="AddResponse" type="MathOutput"/>
<xs:element name="Subtract" type="MathInput"/>
<xs:element name="SubtractResponse" type="MathOutput"/>
<xs:element name="Multiply" type="MathInput"/>
<xs:element name="MultiplyResponse" type="MathOutput"/>
<xs:element name="Divide" type="MathInput"/>
<xs:element name="DivideResponse" type="MathOutput"/>
</xs:schema>
</types>
<message name="AddMessage">
<part name="parameters" element="ns:Add"/>
</message>
<message name="AddResponseMessage">
<part name="parameters" element="ns:AddResponse"/>
</message>
<message name="SubtractMessage">
<part name="parameters" element="ns:Subtract"/>
</message>
<message name="SubtractResponseMessage">
<part name="parameters" element="ns:SubtractResponse"/>
</message>
<message name="MultiplyMessage">
<part name="parameters" element="ns:Multiply"/>
</message>
<message name="MultiplyResponseMessage">
<part name="parameters" element="ns:MultiplyResponse"/>
</message>
<message name="DivideMessage">
<part name="parameters" element="ns:Divide"/>
</message>
<message name="DivideResponseMessage">
<part name="parameters" element="ns:DivideResponse"/>
</message>
<portType name="MathInterface">
<operation name="Add">
<input message="y:AddMessage"/>
<output message="y:AddResponseMessage"/>
</operation>
<operation name="Subtract">
<input message="y:SubtractMessage"/>
<output message="y:SubtractResponseMessage"/>
</operation>
<operation name="Multiply">
<input message="y:MultiplyMessage"/>
<output message="y:MultiplyResponseMessage"/>
</operation>
<operation name="Divide">
<input message="y:DivideMessage"/>
<output message="y:DivideResponseMessage"/>
</operation>
</portType>
<binding name="MathSoapHttpBinding" type="y:MathInterface">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="Add">
<soap:operation soapAction="http://example.org/math/#Add"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="Subtract">
<soap:operation soapAction="http://example.org/math/#Subtract"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="Multiply">
<soap:operation soapAction="http://example.org/math/#Multiply"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="Divide">
<soap:operation soapAction="http://example.org/math/#Divide"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="MathService">
<port name="MathEndpoint" binding="y:MathSoapHttpBinding">
<soap:address location="http://localhost/math/math.asmx"/>
</port>
</service>
</definitions>
Reference: Understanding WSDL at MSDN Library