Generics - Java Basic Features


Recently I had to do portlet coding from scratch and refreshed some of JAVA basics and one of that is "Generics" (To get more clarity around difference between Map<String, ?> and Map<String, Object>)

Generics are much like the more familiar formal parameters used in method declarations. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types

public class Box {
    private Object object;
public void set(Object object) { this.object = object; }
    public Object get() { return object; }
}

Can write as below using the generics

public class Box<T> {
    // T stands for "Type"
    private T t;
    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

A type variable can be any non-primitive type you specify: any class type, any interface type, any array type, or even another type variable.

You can use any letter (you can use 'X' instead of 'T' in above example) or letter combination , but by convention and to avoid confustion between the actual type , type parameter names are single and uppercase letters. 

E - Element (used extensively by the Java Collections Framework)
K - Key
N - Number
T - Type
V - Value

Type Parameter , eg: public class Box<T> , here 'T' is type parameter
Type Argument, eg: Box<Integer> a=new Box<Integer>(); , here 'Integer' is type argument


Multiple type parameters

Generic classes can also have multiple type parameters ( you can also substitute type parameter with parameterized type)

public class Order<K, V>{
   K key;
   V value;
}
Order<String, Box<String>> boxOder = new Order<String, Box<String>();

NOTE:
In Java SE 7 and later, you can replace the type arguments required to invoke the constructor of a generic class with an empty set of type arguments (<>) as long as the compiler can determine. This pair of angle brackets, <>, is informally called the diamond. For example, you can create an instance of Box<Integer> with the following statement:

Box<Integer> integerBox = new Box<>();

RawType

Assume you have generic class definition as below
public class Box<T> {
    // T stands for "Type"
    private T t;
    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

You can create the object like

Box rawBox = new Box();   //It compiles and runs fine but it gives you java warning. This is just backward compatibility.

You can assign parametric object to rawType reference as below

Box<Integer> box = new Box<>(); //Java7 allows this diamond , by default it considers as Box<Integer>
Box rawBox = box;

Generic Methods

Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared.

class Util{
public static <K,V> boolean compare(Order<K,V> order1, Order<K,V> order2){
return order1.getKey().equals(order2.getKey()) && order1.getValue().equals(order2.getValue());
}
}

//Generic Methods
Order<Integer, String> order1 = new Order<Integer, String>(1111,"First Order");
Order<Integer, String> order2 = new Order<Integer, String>(2222,"Second Order");
Util.<Integer, String>compare(order1, order2);

Util.compare(order1, order2);  //you can also ignore/remove the parameterized the type while calling the method.


Bounded Parameters (using extends in generics)

There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound . Extends is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).

//Generics Extends
List<? extends Number> testList1 = new ArrayList<Number>();
List<? extends Number> testList2 = new ArrayList<Integer>();
List<? extends Number> testList3 = new ArrayList<Double>();

testList2.add(new Integer(10)); //This is still a error

You can't add any object to List<? extends T> because you can't guarantee what kind of List it is really pointing to, so you can't guarantee that the object is allowed in that List. The only "guarantee" is that you can only read from it and you'll get a T or subclass of T.

Multiple Bound Parameter

Type parameter can have multiple bounds. A type variable with multiple bounds is a subtype of all the types listed in the bound. If one of the bounds is a class, it must be specified first. 

<T extends B1, B2, B3>

Generics inheritance

Box<Integer> is not a subtype of Box<Number> even though Integer is a subtype of Number. Given two concrete types A and B (for example, Number and Integer), MyClass<A> has no relationship to MyClass<B>, regardless of whether or not A and B are related




Wildcard

In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific). The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.

Upper Bound Wildcard
You can use an upper bounded wildcard to relax the restrictions on a variable. Upper bounded wildcard restricts the unknown type to be a specific type or a subtype of that type and is represented using the extends keyword.

For example, say you want to write a method that works on List<Integer>, List<Double>, and List<Number>; you can achieve this by using an upper bounded wildcard.

To declare an upper-bounded wildcard, use the wildcard character ('?'), followed by the extends keyword, followed by its upper bound.
public static void process(List<? extends Foo> list){ }

Unknown Wildcard
The unbounded wildcard type is specified using the wildcard character (?), for example, List<?>. This is called a list of unknown type

public static void printList(List<Object> list) {
    for (Object elem : list)    System.out.println(elem + " ");
}

The goal of printList is to print a list of any type, but it fails to achieve that goal — it prints only a list of Object instances; it cannot print List<Integer>, List<String>, List<Double>, and so on, because they are not subtypes of List<Object>. To write a generic printList method, use List<?> .
For any concrete type A, List<A> is a subtype of List<?>

It's important to note that List<Object> and List<?> are not the same. You can insert an Object, or any subtype of Object, into a List<Object>. But you can only insert null into a List<?>

Difference between Map<String, ?> and Map<String, Object>

An instance of HashMap<String, String> matches Map<String, ?> but not Map<String, Object>

A thing sometimes misunderstood in Java's generics is that List<String> is not a subtype of List<Object>. (But String[] is in fact a subtype of Object[], that's one of the reasons why generics and arrays don't mix well. (arrays in Java are covariant, generics are not, they are invariant)).



Lower bound wildcard
lower bounded wildcard restricts the unknown type to be a specific type or a super type of that type.  A lower bounded wildcard is expressed using the wildcard character ('?'), following by the super keyword, followed by its lower bound: <? super A>.

Say you want to write a method that puts Integer objects into a list. To maximize flexibility, you would like the method to work on List<Integer>, List<Number>, and List<Object> — anything that can hold Integer values.

public static void addNumbers(List<? super Integer> list) {
    for (int i = 1; i <= 10; i++) {
        list.add(i);
    }
}



Resources

Splunk for Websphere Application Server


Recently I had to monitor and analyze the logs after go live for couple of days . Attended Splunk training earlier but didn't get chance to use it much and started exploring it.

  1. Basic installation is simple , downloaded the latest version from

For the installation instructions ,check this video

  1. After successful installation , it asked me to enter the userid and password  (For the first time login default user id and password are "admin/changeme")



  1. For simple log file analysis like log4j logs … etc , you just need to feed the input data or log files

  1. Splunk provides out of the box App to analyze and monitor websphere appserver server config and logs (events).
  2. You can install this WAS app from the Splunk UI directly



                    6. provide the Splunk account details to download the app , once the installation is done it asks restart.




You need provide the was admin crendentials If you want to gather the JMX metrics (Like WAS out of the box  PMI metrics). 






By default it provides couple of dashboards




On each WAS machine from which you will collect log data, you must install a Splunk universal forwarder and the Splunk Forwarder Add-on for WAS. If you want to collect JMX performance data, then you must have a stand-alone host with network access to the WAS Deployment Manager and an installed Splunk universal forwarder with the Splunk Forwarder Appliance Add-on for WAS installed. To collect, search,and store the data in your environment you must have a Splunk instance with the Splunk App for WAS installed.

Note: As I have single server , I have installed it as a standalone App , In this case you do not need the FA or the Forwarder Add-ons.


For detailed integration information , check the below link

Resources:

Installing CTC 3.0.0.1 (Content Template Catalog) on WCM 7

Download the content template solution (CTC 3.0.0.1) for the websphere 7
https://greenhouse.lotus.com/plugins/plugincatalog.nsf/assetDetails.xsp?action=editDocument&documentId=9867495EE281C75985257919004DBBEB

Download the portal solution installation (1.2.0.6) for the Websphere portal

Pre-requisites
IBM WebSphere Portal 7.0.0.1 plus Combined Cumulative Fix 008 or higher must be installed


Upgrading WP 7.0 to WPS 7.0.0.1 and CF19

System Requirements

Download Fix from
Or

Portal Update Installer

Health checker tool


After downloading fix and update installer

  1. Create the directory "update" under the portal server (c:/IBM/Websphere/PortalServer/update)
  2. Copy the extracted update installer files into that directory
  3. Created "fixes" directory under update folder (c:/IBM/Websphere/PortalServer/update/fixes)
  4. Copy the extracted fix pack files into the 'fixes' directory
  5. Extract and copy the healthchecker.zip from the update installer directory to portal server root (C:/IBM/WebSphere/PortalServer). This just contains a filename called "upgrade_health_check.xml" and this gets copied to "C:\IBM\WebSphere\PortalServer\installer\wp.config\config\includes" folder.
  6. Run the Heathchecker tool to validate the existing environment
C:\IBM\WebSphere\wp_profile\ConfigEngine>ConfigEngine.bat -DRequiredWAS=7.0.0.13 action-health-check-validation

Build failed with following error
The specified product version is not supported: version=7.0.0.11

  1. So WAS is not up to required fix level , so I had to upgrade WAS first (from 7.0.0.11 to 7.0.0.13)
  2. Once the WAS upgrade is successful, run the updatePortalWizard.bat
  3. Installation was successful.



Upgrading WAS from 7.0.0.11 to 7.0.0.13

WAS fix list

WAS update installer download


  1. Download and extract files to "temp" folder , 
  2. Execute the "setupCmdLine.bat" from WAS_Root/bin folder
  3. Run the following command

When I just run the  "install" command , I got the following error "Java could not be found, please specify -is:javahome <java_home_dir> even though I set the environment variables  (my local WAS instance is not installed in default location that is "c:/program files/IBM/WebSphere/AppServer")





I had to execute the following command to start the wizard properly (Make sure path is valid in responsefile.updiinstaller.txt).

C:\IBM\WP7\WebSphere\AppServer\UpdateInstaller>install -options C:\IBM\WP7\WebSphere\AppServer\UpdateInstaller\responsefile.updiinstaller.txt -is:javahome C:\IBM\WP7\WebSphere\AppServer\java

  1. After the update installer installed, install the maintenance pack. ( I ran into problem where it was not able to delete some of the files while installing, and had to restart the machine. So suggest to restart the machine after start installing the maintenance pack )
  2. Retried after server restart and it is installed successfully.


Installing the Portal Solution Installer
  1. From the extracted directory , update the settings.properties file
C:\temp\SolutionInstaller\commands\windows
  1. Execute the C:\temp\SolutionInstaller\commands\windows>install-SolutionInstaller.bat


Installing CTC 
  1. From the CTC-install directory , update the profile path in ctc.properties and execute C:\temp\CTCInstall3001>ctc-install.bat
  2. Eexecute the folowing command C:\temp\CTCInstall3001>ctc-install.bat

Note: You can find more details specific to CTC installation options like how to disable CTC-Demo , or CTC-Theme …etc in the documentation provided in the downloaded zip file

IBM Portal/WCM documentation


Came across new IBM portal/WCM documentation.

Check this link




Resources :

Copy entire WCM library : WCM 8


There was no direct way to copy the entire WCM library earlier (One of possible ways that I tried to copy the site content is posted couple of years back).

But with WCM 8, you can create the copy of the entire WCM library using simple ConfigEngine tasks (Similar to one used for import/export).

ConfigEngine.bat export-library-copy -DLibraryPath=path_to_export_file -DLibraryName=library_name_to_export -DWasPassword=password -DPortalAdminPwd=password

ConfigEngine.bat import-library-copy -DLibraryPath=path_to_export_file -DLibraryName=library_name_to_import -DWasPassword=password -DPortalAdminPwd=password

NOTE:
  1. When you export a library as a copy, new IDs are generated for all items in the library. This ensures that there are no conflicts with existing libraries or items when you import the copy into a web content server that already contains the original library. In this way, you can perform multiple imports to the same web content server, resulting in a new library for each import.


Please refer to Info center link provided below for more information.


Resources:
  1. http://infolib.lotus.com/resources/portal/8.0.0/doc/en_us/PT800ACD004/wcm/wcm_config_wcmlibrary_exportcopy.html

Updates to inline editing feature in the WCM 8.0.0.1


Was going through the WCM 8.0.0.1 changes and came across the following updates to inline editing feature in the WCM 8.0.0.1.


Creating URL node under content root directly


If you observe closely , you don’t have option to create the URL node under the “Content Root” in manage pages portlet.




But still you can create a one using simple work around i.e create the URL node in another level and move it content root. This works fine J .