I have a need to test some application code that runs JMX against WebSphere Application Server. This example is for Websphere 8. Note: That you need to use different JARs for WAS 7.

I created a new project in Eclipse and pasted in my code I wanted to use to test. This code uses the IBM WebSphere Application Client framework to communicate with WAS 8 Mbeans.

When I run it I get Errors. You can use the guide , below is how I resolved this and it covers what JARs you may need and required settings for correctly accessing secured MBeans.

The Errors below are caused because the Eclipse project does not have any references to the WebSphere Application Server 8 (WAS8) jar files needed for an application client to compile. Note: In this code will see that I have some code for managing the required properties. The reason there are so many is because the WAS 8 installation I am using has global security turned (Administrative security) on and if we do not pass appropriate properties we cannot access the WAS 8 mbeans via JMX. Most examples I see on the next show how to use JMX with security enabled. This example shows it with Administrative security enabled.

The first step is to download the Application Server client for WebSphere Application Server 8. You will need to use the IBM installation manager for this. (Search my blog on how to use the IBM IM)

Changing Libraries

Next we re-configure the Eclipse project o know where the appropriate JARS are located.

  1. Select Project-Properties

  1. Select “Java Build Path” from the left-hand-side navigator
  2. Select “Add Library”.
    1. What we are doing is adding a Library that contains all the required WAS 8 application client JARS so we can not have to add them individually in future projects.

  1. Select “User Library” from the Add Library window

  1. Click Next

  1. Click “User Libraries”

  1. Click New

  1. Type in WAS 8 Application Client
  2. Click Add JARs

  1. Select all the JARs in the Lib foldser where you installed the WAS 8 Application Client.
    1. You do not need all these JARs, but for now we want them all until we understand which ones are not needed. It will depend on the code that your application uses i.e. WAS 8 Application Client API calls.
    2. In my example the plugins folder was located in c:\Program Files (x86)\ibm\AppClient folder which is the default installation as suggested by the IBM Installation Manager when I installed the App Client.

  1. Click OK
  2. Click Finish
  3. You will be returned to the “Java Build Path” dialog. If you expand the WAS 8 Application Client you will see the JARs listed. I am not going to explain what each of these JARs do nor list the minimum JARs you could get away with. (I do however provide consultancy for that).,

  1. Click OK to return to the project.
  2. You will now see the project can compile.

Now that we have a compiled project, let’s run it against WebSphere 8 and see if you code works?

Error:
Exception in thread “main” java.lang.NoClassDefFoundError: com/ibm/ws/bootstrap/RASWsLoggerFactory
 

    at com.ibm.websphere.management.AdminClientFactory.<clinit>(AdminClientFactory.java:124)

    at com.screv.AdminClientConnection.createAdminClient(AdminClientConnection.java:81)

    at com.screv.AdminClientConnection.main(AdminClientConnection.java:31)

Caused by: java.lang.ClassNotFoundException: com.ibm.ws.bootstrap.RASWsLoggerFactory

    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)

    at java.security.AccessController.doPrivileged(Native Method)

    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)

    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

    … 3 more

Ok what we need to do now is add all the libs form the Lib folder, follow the same process

Error
Exception in thread “main” java.lang.NoClassDefFoundError: com/ibm/CORBA/iiop/ORB
 

    at java.lang.Class.forName0(Native Method)

    at java.lang.Class.forName(Class.java:169)

    at com.ibm.ws.util.PlatformHelperFactory.getBackupHelper(PlatformHelperFactory.java:106)

    at com.ibm.ws.util.PlatformHelperFactory.getPlatformHelper(PlatformHelperFactory.java:79)

    at com.ibm.ws.pmi.server.PmiRegistry.<clinit>(PmiRegistry.java:75)

    at com.ibm.wsspi.pmi.factory.StatsFactory.isPMIEnabled(StatsFactory.java:86)

    at com.ibm.ws.security.auth.ContextManagerImpl.<init>(ContextManagerImpl.java:534)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

    at java.lang.Class.newInstance0(Class.java:355)

    at java.lang.Class.newInstance(Class.java:308)

    at com.ibm.ws.security.core.ContextManagerFactory.createInstance(ContextManagerFactory.java:416)

    at com.ibm.ws.security.core.ContextManagerFactory.getInstance(ContextManagerFactory.java:147)

    at com.ibm.websphere.management.AdminClientFactory.getCacheKey(AdminClientFactory.java:1372)

    at com.ibm.websphere.management.AdminClientFactory.createAdminClientPrivileged(AdminClientFactory.java:234)

    at com.ibm.websphere.management.AdminClientFactory.access$000(AdminClientFactory.java:122)

    at com.ibm.websphere.management.AdminClientFactory$1.run(AdminClientFactory.java:203)

    at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:63)

    at com.ibm.websphere.management.AdminClientFactory.createAdminClient(AdminClientFactory.java:199)

    at com.screv.AdminClientConnection.createAdminClient(AdminClientConnection.java:81)

    at com.screv.AdminClientConnection.main(AdminClientConnection.java:31)

Caused by: java.lang.ClassNotFoundException: com.ibm.CORBA.iiop.ORB

    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)

    at java.security.AccessController.doPrivileged(Native Method)

    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)

    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

    … 23 more

I have done these errors to show you that this often the way that the you might approach this solution. You have to be also away that we want to use the IBM JDK not the One supplied with Eclipse

So what we should also do is add a new JRE so we can use the IBM JDK instead

Adding a new JRE (IBM JRE)

  1. Click Project Properties

  1. Select the “JRE System Library” and click Remove
  2. Click “Add Library
  3. Click JRE System Library

  1. Select “Alternate JRE” and then click “Installed JREs” to add a new one.

  1. Click Add.

  1. Select “Standard VM” fro the Installed JRE type list.

Click Next, Select the location of the IBM JDL that comes with the Application Client for example: “C:\Program Files (x86)\ibm\WebSphere\AppClient\java”

  1. Give the new JRE a valid name for reference. Click Finish
  2. Select the new “WAS 8 JRE” and click OK

  1. Click Finish and modify as required an discrepancies of JREs for the project. You Java Build Path should look like below.

  1. Cick OK to return to the project

Running the Code

When running the code wer get the following errors:

Error
25-Mar-2012 10:42:05 null null
 

WARNING: ADMC0046W

25-Mar-2012 10:42:06 null null

WARNING: Could not find tmx4jTransform.jar in null/etc/tmx4jTransform.jar – Interoperability to older versions of WebSphere is disabled

25-Mar-2012 10:42:06 null null

INFO: ssl.disable.url.hostname.verification.CWPKI0027I

25-Mar-2012 10:42:06 null null

INFO: Client code attempting to load security configuration

Exception creating Admin Client Connection: com.ibm.websphere.management.exception.ConnectorException: ADMC0016E: The system cannot create a SOAP connector to connect to host localhost at port 8880.

This is because my Application Server must be using a different SOAP port. Lets log into the Administrative Console and drill down into the server’s properties to see what port is using doe SOAP.

  1. Log into the WAS 8 Administrative Console

  1. Navigate to Servers/ServerTypes/WebSphere application Servers
  2. I am using WAS 8 Base, so it is a standalone server for this example. Locate and Click on the appropriate serer (JVM)

  1. In the Server’s properties page, locate the “Communications” section and expand “Ports”. We can see that the port is indeed 8880.

What’s the problem? Well if we look at the message correctly it says:


Error
INFO: Client code attempting to load security configuration
 

Exception creating Admin Client Connection: com.ibm.websphere.management.exception.ConnectorException: ADMC0016E: The system cannot create a SOAP connector to connect to host localhost at port 8880.

We are attempting to load the security configuration. What we need to do is ensure we are using the correct keystore and trust stores. We can cheat by copying the appropriate keystore and trust store form the Application Server, just to save time creating our own.

In y example I am using WAS 8 fro developers installed in D:\was8dev\ if I navigate to the “etc” folder of my profile for example “profiles\appsrv01\etc” I can locate the key and trust files. I can just copy these to another location for my application client to have them packaged or just point to them to prove the issue. In my case I am going to modify my code to just point to them. This is not how I would do this for a commercial application client. In the case of commercial code I would create my own key and trust stores.

Code
private String keyStoreFile=“D:/was8dev/profiles/appsrv01/etc/key.p12”;
 

private String keyPassword=“WebAS”;

private String trustStoreFile=“D:/was8dev/profiles/appsrv01/etc/trust.p12”;

private String trustPassword=“WebAS”;

When we next run the code, here is the final result:

Connected to Application Server
 

Server mbean found WebSphere:name=server1,process=server1,platform=proxy,node=node01,j2eeType=J2EEServer,version=8.0.0.1,type=Server,mbeanIdentifier=cells/SteveRobinsonNode01Cell/nodes/node01/servers/server1/server.xml#Server_1183121908656,cell=SteveRobinsonNode01Cell,spec=1.0,processType=UnManagedProcess

Server name: server1. Server state: STARTED

Well, we have now been able to achieve connecting to WebSphere 8 even when it is secured with Administrative Security (Used to be called Global Security) turned on.

Source Code:

Below is the source code for the project.

package com.screv;
 

import java.util.Date;

import java.util.Properties;

import java.util.Set;

import javax.management.InstanceNotFoundException;

import javax.management.MBeanServerConnection;

import javax.management.MalformedObjectNameException;

import javax.management.Notification;

import javax.management.NotificationListener;

import javax.management.ObjectName;

import com.ibm.websphere.management.AdminClient;

import com.ibm.websphere.management.AdminClientFactory;

import com.ibm.websphere.management.exception.ConnectorException;

public class AdminClientConnection

{

private AdminClient adminClient;

private ObjectName server;

private String keyStoreFile=”D:/was8dev/profiles/appsrv01/etc/key.p12″;

private String keyPassword=”WebAS”;

private String trustStoreFile=”D:/was8dev/profiles/appsrv01/etc/trust.p12″;

private String trustPassword=”WebAS”;

public static void main(String[] args)

{

    AdminClientConnection aClient = new AdminClientConnection();

// Create an AdminClient

    aClient.createAdminClient();

}

private void createAdminClient()

{

// Set up a Properties object for the JMX connector attributes

Properties clientProps = new Properties();

clientProps.setProperty(

AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);

clientProps.setProperty(AdminClient.CONNECTOR_HOST, “localhost”);

clientProps.setProperty(AdminClient.CONNECTOR_PORT, “8880”);

clientProps.setProperty(AdminClient.CONNECTOR_SECURITY_ENABLED, “true”);

clientProps.setProperty(AdminClient.USERNAME, “wasadmin”);

clientProps.setProperty(AdminClient.PASSWORD, “wasadmin”);

clientProps.setProperty(“com.ibm.ssl.keyStoreFileBased”, “true”);

clientProps.setProperty(“com.ibm.ssl.trustStoreFileBased”, “true”);

clientProps.setProperty(“com.ibm.ssl.keyStore”, keyStoreFile);

clientProps.setProperty(“javax.net.ssl.keyStore”, keyStoreFile);

clientProps.setProperty(“com.ibm.ssl.keyStorePassword”, keyPassword);

clientProps.setProperty(“javax.net.ssl.keyStorePassword”, keyPassword);

if (keyStoreFile.endsWith(“.p12”) || keyStoreFile.endsWith(“.P12”))

        {

     clientProps.setProperty(“com.ibm.ssl.keyStoreType”, “PKCS12”);

     clientProps.setProperty(“javax.net.ssl.keyStoreType”, “PKCS12”);

        } else

        {

             clientProps.setProperty(“com.ibm.ssl.keyStoreType”, “JKS”);

             clientProps.setProperty(“javax.net.ssl.keyStoreType”, “JKS”);

        }

clientProps.setProperty(“com.ibm.ssl.trustStore”, trustStoreFile);

clientProps.setProperty(“javax.net.ssl.trustStore”, trustStoreFile);

clientProps.setProperty(“com.ibm.ssl.trustStorePassword”, trustPassword);

clientProps.setProperty(“javax.net.ssl.trustStorePassword”, trustPassword);

        if (trustStoreFile.endsWith(“.p12”) || trustStoreFile.endsWith(“.P12”))

        {

             clientProps.setProperty(“com.ibm.ssl.trustStoreType”, “PKCS12”);

             clientProps.setProperty(“javax.net.ssl.trustStoreType”, “PKCS12”);

        } else

        {

             clientProps.setProperty(“com.ibm.ssl.trustStoreType”, “JKS”);

             clientProps.setProperty(“javax.net.ssl.trustStoreType”, “JKS”);

        }

// Get an AdminClient based on the connector properties

try

{

adminClient = AdminClientFactory.createAdminClient(clientProps);

}

catch (ConnectorException e)

{

System.out.println(“Exception creating Admin Client Connection: ” + e);

System.exit(-1);

}

System.out.println(“Connected to Application Server”);

getServerMBean(“Server01”);

}

private void getServerMBean(String serverName)

{

// Query for the object name of the node agent MBean for the given server

try {

String query = “WebSphere:type=Server,*”;

ObjectName queryName = new ObjectName(query);

Set s = adminClient.queryNames(queryName, null);

if (!s.isEmpty()) {

server = (ObjectName)s.iterator().next();

System.out.println(“Server mbean found “+ server.toString());

getServerAttributes(server);

} else {

System.out.println(“Server MBean was not found”);

System.exit(-1);

}

} catch (Exception e) {

System.out.println(e);

System.exit(-1);

}

}

private void getServerAttributes(ObjectName attribObjName)

{

// Query for the object name of the node agent MBean for the given server

try {

String name = (String) adminClient.getAttribute(attribObjName,”name”);

String state = (String) adminClient.getAttribute(attribObjName, “state”);

System.out.println(“Server name: ” + name + “. Server state: ” + state);

} catch (Exception e) {

System.out.println(e);

System.exit(-1);

}

}

}

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply