Showing posts with label Java EE. Show all posts
Showing posts with label Java EE. Show all posts

Wednesday, September 24, 2008

IBM Websphere Application Server (WAS) V6.1 Network Deployment Certification 253



Preparation for this examination (253) was kinda harsh. I only managed to cram 2.5 of the related IBM Red Books and struggled to get the other questions right using my project experiences.

Study Materials:

WebSphere Application Server 6.1 Planning and Design (SG24-7305-00)
WebSphere Application Server 6.1 System Management and Configuration (SG24-7304-00)
WebSphere Application Server 6.1 Security Handbook (SG24-7304) - Part 1

I really want to read up another one about Performance, Scalability and HA but my schedule was extremely tight, well, maybe will do the reading if going for the advanced certification.

Score: 89%




Sunday, September 14, 2008

Web Services Protocol Stack



Adopted from IBM red book: Websphere Application Server V6.1 Planning and Design (pg 254).


Sunday, August 31, 2008

J2EE EAR File Structure



A diagram from IBM Websphere redbook. I just keep it here to remind my rusted high performance brain.




Thursday, August 28, 2008

JNDI Application Client in WAS 6.1 - Part 2




Continued from my previous post, this post attempts to address some of technical intricacies that you might face when try to authenticate yourself outside Java EE containers when doing naming operations.

Previously, I simply assigned the necessary rights to EVERYONE in Websphere Application Server V6.1 Administrative Console to enable anyone (Including those Unauthenticated) to perform naming operations.

However, this setting is not appropriate in production environment because some operations such as removing bindings and create new bindings are considered as privileged operations that require thoughtful considerations.

Assuming that you are created a new WAS User named "NamingUser1" and assigned this user with relevant rights (i.e. CosNaming Delete, etc)

Now the trick is to pass these credentials to WAS from the Java program.

So, the first mistake that might happened is you assumed the following codes will work:


Hashtable env = new Hashtable();

env.put(Context.PROVIDER_URL, "corbaloc:iiop:localhost:2810/NameService");
env.put(Context.INITIAL_CONTEXT_FACTORY
,"com.ibm.websphere.naming.WsnInitialContextFactory");

env.put(Context.SECURITY_PRINCIPAL, "NamingUser1");
env.put(Context.SECURITY_CREDENTIALS, "password1");



No, this will not work. You will shoot by the below exception:


javax.naming.NoPermissionException: NO_PERMISSION exception caught [Root exception is org.omg.CORBA.NO_PERMISSION:
>> SERVER (id=11c328fe, host=eddy) TRACE START:
>> org.omg.CORBA.NO_PERMISSION: Caught WSSecurityContextException in WSSecurityContext.acceptSecContext(), reason: Major Code[0] Minor Code[0] Message[ null] vmcid: 0x49424000 minor code: 300 completed: No
>> at com.ibm.ISecurityLocalObjectBaseL13Impl.PrincipalAuthFailReason.map_auth_fail_to_minor_code(PrincipalAuthFailReason.java:83)
>> at com.ibm.ISecurityLocalObjectBaseL13Impl.CSIServerRIBase.authenticateSecurityTokens(CSIServerRIBase.java:2575)
>> at com.ibm.ISecurityLocalObjectBaseL13Impl.CSIServerRI.receive_request(CSIServerRI.java:485)
>> at com.ibm.rmi.pi.InterceptorManager.invokeInterceptor(InterceptorManager.java:592)
>> at com.ibm.rmi.pi.InterceptorManager.iterateServerInterceptors(InterceptorManager.java:507)
>> at com.ibm.rmi.pi.InterceptorManager.iterateReceiveRequest(InterceptorManager.java:738)
>> at com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:602)

...
...



You need to use JAAS to perform the authentication.

To make the case clearer, let us focus on the following source codes:


package lab.namespace;

import java.rmi.RMISecurityManager;
import java.security.PrivilegedAction;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.security.auth.login.LoginContext;

import com.ibm.ejs.models.base.bindings.applicationbnd.Subject;
import com.ibm.websphere.naming.PROPS;
import com.ibm.websphere.security.auth.WSSubject;
import com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl;
import com.ibm.ws.security.auth.callback.WSCallbackHandler;

public class Connect {
public static void main(String[] args) throws Exception {
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "corbaloc:iiop:localhost:2810/NameService");
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
final Context initialContext = new InitialContext(env);
initialContext.lookup("");

LoginContext loginContext =
new LoginContext("WSLogin",new WSCallbackHandlerImpl("NamingUser1","password1"));

loginContext.login();

javax.security.auth.Subject s = loginContext.getSubject();

WSSubject.doAs(s, new PrivilegedAction(){
public Object run() {
try{
initialContext.bind("hello", "1234");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});

System.out.println(loginContext.getSubject());

}

}



You also need to add the following JARs to the class path:


${WAS_INSTALLED_FOLDER}/com.ibm.ws.webservices.thinclient_6.1.0.jar


Then you crossed your finger and execute the program again. And yet it still fails.


Exception in thread "P=172625:O=0:CT" java.lang.SecurityException: Unable to locate a login configuration
at com.ibm.security.auth.login.ConfigFile.(ConfigFile.java:129)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1263)
at javax.security.auth.login.Configuration$3.run(Configuration.java:239)
at java.security.AccessController.doPrivileged(AccessController.java:241)
at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:233)
at javax.security.auth.login.LoginContext$1.run(LoginContext.java:260)
at java.security.AccessController.doPrivileged(AccessController.java:192)
at javax.security.auth.login.LoginContext.init(LoginContext.java:257)
at javax.security.auth.login.LoginContext.(LoginContext.java:426)
at lab.namespace.Connect.main(Connect.java:38)
Caused by: java.io.IOException: Unable to locate a login configuration
at com.ibm.security.auth.login.ConfigFile.init(ConfigFile.java:238)
at com.ibm.security.auth.login.ConfigFile.(ConfigFile.java:127)
... 10 more


Now you shall setup JAAS specific environment.

Copy the following files to your workspace:


${PROFILE_HOME}\properties\sas.client.props
${PROFILE_HOME}\properties\sas.client.props
${PROFILE_HOME}\properties\wsjaas.client.conf


Modify the sas.client.props


com.ibm.CORBA.validateBasicAuth=false
com.ibm.CORBA.securityServerHost=localhost
com.ibm.CORBA.securityServerPort=2809
com.ibm.CORBA.loginSource=none
com.ibm.CORBA.loginUserid=NamingUser1
com.ibm.CORBA.loginPassword=password1


Note: Here I assume that the bootstrap port is 2809.


Modify the ssl.client.props


user.root=C:/IBM/WebSphere/ND/profiles/AppSvr01
com.ibm.ssl.keyStore=C:/IBM/WebSphere/ND/profiles/AppSvr01/etc/key.p12
com.ibm.ssl.trustStore=C:/IBM/WebSphere/ND/profiles/AppSvr01/etc/trust.p12


Note: Here I just used the same keystore from the server. It might not be the case for production environment.

You will also need to modify the source code to include the following line:


System.setSecurityManager(new RMISecurityManager());


Create one new file named "security.policy" and specify the following in it.


grant {
permission java.security.AllPermission;
};


Note: This is just for demostration purposes. You should tune the security policy instead.

Lastly you must add few JVM arguments for execution.


-Djava.security.auth.login.config=${YOUR_PATH}\wsjaas.conf
-Dcom.ibm.CORBA.ConfigURL=${YOUR_PATH}\sas.client.props
-Djava.security.policy=${YOUR_PATH}\security.policy
-Dcom.ibm.SSL.ConfigURL=file:${YOUR_PATH}\ssl.client.props



Potential Mistake #2: JVM argument "com.ibm.SSL.ConfigURL"

The value specified for this argument must start with "file:" for file URL. Fail to do this will make your head spin.


Finally, the program will be successfully executed and the new String object is bound to the name space. You can use dumpNameSpace utility to verify this.


Good luck.



JNDI Application Client in WAS 6.1




If you deployed your application into the web container or EJB container of the J2
EE/Java EE application server and you try to perform naming operations, basically the container already setup all necessary environment configuration for you to obtain the initial context. Initial context basically is the starting point in the name space that you want to manipulate. In Websphere, an initial context can be treated as a connection to the name server where the connection is defined by the bootstrap host, bootstrap port and protocol as part of the provider URL.

In the event that you need to develop application client that runs outside the containers, then you shall need to configure this connection yourself or as part of the application assembly process assisted by the tool. AST and Rational Application Developer can do all these dirty works for you.

However, under the circumstances that you don't have the luxury of using these tools, then you really need to know what to do.

In this example, I'm using IBM Websphere Application Server V6.1 with FP0.

Sample code:


package lab.namespace;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;

public class Connect {

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

Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "corbaloc:iiop:localhost:9809");
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");

Context initialContext = new InitialContext(env);
Context myCtx = (Context)initialContext.lookup("cell/persistent");
myCtx.bind("hello", "123");


}


Without additional information, when you execute this program, you shall hit the first error:


Exception in thread "main" javax.naming.NoInitialContextException: Cannot instantiate class: com.ibm.websphere.naming.WsnInitialContextFactory [Root exception is java.lang.ClassNotFoundException: com.ibm.websphere.naming.WsnInitialContextFactory]
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:669)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:259)
at javax.naming.InitialContext.init(InitialContext.java:235)
at javax.naming.InitialContext.(InitialContext.java:209)
at lab.namespace.Connect.main(Connect.java:19)
Caused by: java.lang.ClassNotFoundException: com.ibm.websphere.naming.WsnInitialContextFactory
at java.lang.Class.forName(Class.java:164)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:57)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:666)
... 4 more


You can solve this by adding the appropriate JAR into your class path. Locate ws_runtimes.jar at


${your_was_installed_dir}\deploytool\itp\plugins\com.ibm.websphere.v61_6.1.0\ws_runtimes.jar


You can try to execute again, and this time possibly you will hit the second error:


Exception in thread "main" java.lang.NoClassDefFoundError: com/ibm/CORBA/iiop/ObjectURL
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.ibm.websphere.naming.WsnInitialContextFactory.init_implClassCtor(WsnInitialContextFactory.java:172)
at com.ibm.websphere.naming.WsnInitialContextFactory.getInitialContext(WsnInitialContextFactory.java:112)
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.init(Unknown Source)
at javax.naming.InitialContext.(Unknown Source)
at lab.namespace.Connect.main(Connect.java:19)


The stack trace pointed out that the program need more JARs.

Here you have 2 choices as solution to the problem.

1. Change your JRE from SUN to IBM

To do this in Eclipse, go to Windows->Preferences->Java->Installed JREs

And specify the location of IBM JRE


${your_was_installed_dir}\java\jre\


And set this JRE as default JRE.

2. Add in only the specific JARs in your class path

Locate the following JARs:


${your_was_installed_dir}\java\jre\lib\ibmorb.jar
${your_was_installed_dir}\java\jre\lib\ibmorbapi.jar


High chance is that you still encounter another error after you added the above JARs.


WARNING: jndiNamingException
Exception in thread "P=762318:O=0:CT" javax.naming.NoPermissionException: NO_PERMISSION exception caught [Root exception is org.omg.CORBA.NO_PERMISSION:
>> SERVER (id=144d42ac, host=eddy) TRACE START:
>> org.omg.CORBA.NO_PERMISSION: Not authorized to perform bind_java_object operation. vmcid: 0x0 minor code: 0 completed: No
>> at com.ibm.ws.naming.cosbase.WsnOptimizedNamingImplBase.performAuthorizationCheck(WsnOptimizedNamingImplBase.java:4745)
>> at com.ibm.ws.naming.cosbase.WsnOptimizedNamingImplBase.bind_java_object(WsnOptimizedNamingImplBase.java:1267)
>> at com.ibm.WsnOptimizedNaming._NamingContextImplBase._invoke(_NamingContextImplBase.java:125)
>> at com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:613)
>> at com.ibm.CORBA.iiop.ServerDelegate.dispatch(ServerDelegate.java:466)
>> at com.ibm.rmi.iiop.ORB.process(ORB.java:503)
>> at com.ibm.CORBA.iiop.ORB.process(ORB.java:1552)
>> at com.ibm.rmi.iiop.Connection.respondTo(Connection.java:2673)
>> at com.ibm.rmi.iiop.Connection.doWork(Connection.java:2551)
>> at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:62)
>> at com.ibm.ejs.oa.pool.PooledThread.run(ThreadPool.java:95)
>> at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1498)
>> SERVER (id=144d42ac, host=eddy) TRACE END.
vmcid: 0x0 minor code: 0 completed: No]
at com.ibm.ws.naming.jndicos.CNContextImpl.doBind(CNContextImpl.java:2322)
at com.ibm.ws.naming.jndicos.CNContextImpl.bind(CNContextImpl.java:534)
at lab.namespace.Connect.main(Connect.java:23)
Caused by: org.omg.CORBA.NO_PERMISSION:
>> SERVER (id=144d42ac, host=eddy) TRACE START:
>> org.omg.CORBA.NO_PERMISSION: Not authorized to perform bind_java_object operation. vmcid: 0x0 minor code: 0 completed: No
>> at com.ibm.ws.naming.cosbase.WsnOptimizedNamingImplBase.performAuthorizationCheck(WsnOptimizedNamingImplBase.java:4745)
>> at com.ibm.ws.naming.cosbase.WsnOptimizedNamingImplBase.bind_java_object(WsnOptimizedNamingImplBase.java:1267)
>> at com.ibm.WsnOptimizedNaming._NamingContextImplBase._invoke(_NamingContextImplBase.java:125)
>> at com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:613)
>> at com.ibm.CORBA.iiop.ServerDelegate.dispatch(ServerDelegate.java:466)
>> at com.ibm.rmi.iiop.ORB.process(ORB.java:503)
>> at com.ibm.CORBA.iiop.ORB.process(ORB.java:1552)
>> at com.ibm.rmi.iiop.Connection.respondTo(Connection.java:2673)
>> at com.ibm.rmi.iiop.Connection.doWork(Connection.java:2551)
>> at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:62)
>> at com.ibm.ejs.oa.pool.PooledThread.run(ThreadPool.java:95)
>> at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1498)
>> SERVER (id=144d42ac, host=eddy) TRACE END.
vmcid: 0x0 minor code: 0 completed: No
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:67)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:521)
at com.ibm.rmi.iiop.ReplyMessage._getSystemException(ReplyMessage.java:241)
at com.ibm.rmi.iiop.ReplyMessage.getSystemException(ReplyMessage.java:189)
at com.ibm.rmi.iiop.ClientResponseImpl.getSystemException(ClientResponseImpl.java:232)
at com.ibm.rmi.corba.ClientDelegate.intercept(ClientDelegate.java:982)
at com.ibm.rmi.corba.ClientDelegate.invoke(ClientDelegate.java:459)
at com.ibm.CORBA.iiop.ClientDelegate.invoke(ClientDelegate.java:1150)
at com.ibm.rmi.corba.ClientDelegate.invoke(ClientDelegate.java:778)
at com.ibm.CORBA.iiop.ClientDelegate.invoke(ClientDelegate.java:1180)
at org.omg.CORBA.portable.ObjectImpl._invoke(ObjectImpl.java:484)
at com.ibm.WsnOptimizedNaming._NamingContextStub.bind_java_object(_NamingContextStub.java:174)
at com.ibm.ws.naming.jndicos.CNContextImpl.cosBindJavaObject(CNContextImpl.java:3962)
at com.ibm.ws.naming.jndicos.CNContextImpl.doBind(CNContextImpl.java:2260)
... 2 more


The exception occured due to the fact that WAS V6.1 control the usages of CORBA Naming Service to only those users/groups who is assigned the following rights depending on the action.


Cos Naming Read, Cos Naming Write, Cos Naming Create, Cos Naming Delete


You will need to acess Administrative Console (Integrated Solution Console) to grant the rights.

1. Open Administrative Console
2. Go to Environment -> Naming -> CORBA Naming Service Groups
3. Click on the EVERYONE group (This is just for simplicity, you can use other group)
4. Select the right(s)
5. Save and restart the server.
6. Modify the original program


package lab.namespace;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;


public class Connect {

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

Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "corbaloc:iiop:localhost:9809");
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");

Context initialContext = new InitialContext(env);
Context myCtx = (Context)initialContext.lookup("cell/persistent");
myCtx.bind("hello", "1234");

}

}


You're done. Good luck.




Top Blogs

Monday, April 09, 2007

Generalization and Specialization

At some stages in life, you will suddenly have a desire to do a turn-around in your career, whether to continue specializing something or generalizing to handle more tasks. Face it, people who are specialized in an area for ages will have difficulties in adapting to the idea of multi-area + multi-process + multi-tasking. The same happened for generalized worker, they might have phobia of scaring entering a job dead-end or ceasing of learning curve. Anyway, ignore what I had said, these are just crappy murmuring.

Here's the meat. There are reasons why you need certified and well trained personnel to deploy your applications into production environments. One of it is that they always got some well-kept secrets that make them different from typical persons who try to be hero or force to be. For the sake of goodness of your enterprise, pay whatever that is necessary to get the job done properly. Cheapskate is not the way to survive.

Like thousands of others outside, me as a generic person, sometimes need to do stuff i'm not good at (or at least not at the current moment). Last week, I setup a Websphere Application Server in a machine which is Windows domain member. Naively, I just do whatever I did in the company test environment, thought it will turns on and run flawlessly. Well, most of the features do.

I had this problem of obtaining list of Windows groups and users from the LocalOS registry when try to map security roles in the deployed applications. WAS smartly returned me "*null" message on the screen and some "User not found" or "Not authorized" or "Password something" in the logs.

Stratching my nearly bald head and suspecting something to do with Windows domain, I look up the WAS 6 information center, and search for LocalOS registry. The fact is that WAS has different setting requirements for standalone machine, domain member and domain controller if you are using LocalOS.

A quick fix will be to add "com.ibm.websphere.registry.UseRegistry" custom property with the value "local" to the LocalOS custom property sheet. This will explicitly stop the WAS from querying domain registry for list of groups and users (That's my requirement, your's might be different). If you want it to get the list from both domain and local registry, then read on the documentation, there are a list of things to set up for the user who starts WAS process.

This is just one issue that I encountered so far, however just cross my finger and hopes there are no others.


The risks of being not specialized.

Saturday, April 15, 2006

J2EE and Java EE. Which one sounds better?


The name of the Java platform for the enterprise has been simplified. Formerly, the platform was known as Java 2 Platform, Enterprise Edition (J2EE), and specific versions had "dot numbers" such as J2EE 1.4. The "2" is dropped from the name, as well as the dot number. So the next version of the Java platform for the enterprise is Java Platform, Enterprise Edition 5 (Java EE 5).


Personally, I like Java EE. I dislike the idea of introducing quantifiable numeric into the name of a product. I just felt that the existence of numbers in any name will causes some degree of loss of abstraction, creativity and makes people speak like as if they are really a nerd (Which in fact they might not). The name of J2EE is even worst as the number 2 is located in the middle, not as prefix or suffix of the name.

No offence to people who named J2EE. Just my 2 cents. :p

Saturday, March 25, 2006

The Advantages of the Java EE 5 Platform

A Conversation with Distinguished Engineer Bill Shannon


Version 5 of the Java Platform, Enterprise Edition (Java EE, formerly referred to as J2EE), has arrived. Its streamlined features offer added convenience, improved performance, and reduced development time, all of which enable developers to bring products to market faster.

To get an update on the Java EE 5 platform, we met with Java EE specification lead Bill Shannon, a Distinguished Engineer at Sun Microsystems. Shannon has been with Sun since 1982 and previously worked on the JavaMail API, the HotJava Views product, the Common Desktop Environment (CDE), the Solaris Operating Environment, and all versions of SunOS. He graduated from Case Western Reserve University with an MS in Computer Engineering.


Read More

Many of the highly anticipated features and technologies crawled into J2EE 5.0. Among them are the new EJB 3.0 and Java Persistence API, JSF, simplified component and service development. Evolving from the J2EE 1.4 orientation on Web Service for J2EE (JSR109) and related JSRs, J2SE 5.0 annotation definitely makes a difference on the ease of creation of services. If you still being scared away by the intricacy of SOAP,WSDL,UDDI,End Point configurations and etc etc, well, check out how Bill Shannon answered the following question:

Question: If you could speak to an audience of 1000 talented developers who were on the fence, and considering moving to Java EE 5, what would you say to them?



This is not your father's J2EE!