ANSIS IT Solutions

Software Development

Eclipse RCP Standalone Client with Glassfish v3

This code fragment shows how an Eclipse RCP application can connect to Glassfish v3.1 as a stand-alone client (including full security). It consists of the following parts:

  • Eclipse plugin containing project-specific server classes, such remote interfaces for session beans and entity beans. It also contains all the necessary GFv3.1 Jars for the client app to run on a remote JVM. We call this: com.ansis.timetracker.client.lib.gf.
  • Eclipse client plugin(s). These plugins contain all the client-specific code and UI functionality. Each such plugin (here we provide one sample plugin) all depend on com.ansis.timetracker.client.lib.gf. It's name in our example is com.ansis.timetracker.client.

The Bundle-ClassPath section contains two project specific Jars (aef-util.jar, timetracker.jar), which contain all necessary server classes (remote interfaces, etc.). All other Jars are identical to the Classpath section in the gf-client-module.jar found in the Glassfish/modules directory. Some of these Jars are not necessary and can be eliminated through trial-and-error.

===========================================

Manifest-Version: 1.0

Bundle-ManifestVersion: 2

Bundle-Name: iREMS Server Plug-in

Bundle-SymbolicName: com.ansis.timetracker.client.lib.gf

Bundle-Version: 2.2.1.20110308

Bundle-Vendor: ANSIS

Bundle-Localization: plugin

Bundle-ClassPath: .,

 lib/aef-util.jar,

 lib/timetracker.jar,

 gf-lib/hibernate/hibernate3.jar,

 gf-lib/modules/security.jar,

 gf-lib/modules/autostart/,

 gf-lib/modules/endorsed/,

 gf-lib/modules/acc-config.jar,

 gf-lib/modules/admin-cli.jar,

 gf-lib/modules/admin-core.jar,

 gf-lib/modules/admin-util.jar,

 gf-lib/modules/amx-all.jar,

 gf-lib/modules/annotation-framework.jar,

 gf-lib/modules/antlr-repackaged.jar,

 gf-lib/modules/api-exporter.jar,

 gf-lib/modules/appclient-connector.jar,

 gf-lib/modules/appclient-server-core.jar,

 gf-lib/modules/appclient.security.jar,

 gf-lib/modules/asm-all-repackaged.jar,

 gf-lib/modules/auto-depends.jar,

 gf-lib/modules/backup.jar,

 gf-lib/modules/bean-validator.jar,

 gf-lib/modules/branding.jar,

 gf-lib/modules/class-model.jar,

 gf-lib/modules/cmp-ejb-mapping.jar,

 gf-lib/modules/cmp-enhancer.jar,

 gf-lib/modules/cmp-generator-database.jar,

 gf-lib/modules/cmp-internal-api.jar,

 gf-lib/modules/cmp-model.jar,

 gf-lib/modules/cmp-support-ejb.jar,

 gf-lib/modules/cmp-support-sqlstore.jar,

 gf-lib/modules/cmp-utility.jar,

 gf-lib/modules/common-util.jar,

 gf-lib/modules/commons-codec-repackaged.jar,

 gf-lib/modules/config-api.jar,

 gf-lib/modules/config-types.jar,

 gf-lib/modules/config.jar,

 gf-lib/modules/connectors-admin.jar,

 gf-lib/modules/connectors-inbound-runtime.jar,

 gf-lib/modules/connectors-internal-api.jar,

 gf-lib/modules/connectors-runtime.jar,

 gf-lib/modules/container-common.jar,

 gf-lib/modules/dataprovider.jar,

 gf-lib/modules/dbschema-repackaged.jar,

 gf-lib/modules/deployment-admin.jar,

 gf-lib/modules/deployment-autodeploy.jar,

 gf-lib/modules/deployment-client.jar,

 gf-lib/modules/deployment-common.jar,

 gf-lib/modules/deployment-javaee-core.jar,

 gf-lib/modules/deployment-javaee-full.jar,

 gf-lib/modules/dol.jar,

 gf-lib/modules/ejb-container.jar,

 gf-lib/modules/ejb-internal-api.jar,

 gf-lib/modules/ejb.security.jar,

 gf-lib/modules/el-impl.jar,

 gf-lib/modules/flashlight-agent.jar,

 gf-lib/modules/flashlight-extra-jdk-packages.jar,

 gf-lib/modules/flashlight-framework.jar,

 gf-lib/modules/gf-client-module.jar,

 gf-lib/modules/gf-connectors-connector.jar,

 gf-lib/modules/gf-ejb-connector.jar,

 gf-lib/modules/gf-web-connector.jar,

 gf-lib/modules/glassfish-api.jar,

 gf-lib/modules/glassfish-corba-asm.jar,

 gf-lib/modules/glassfish-corba-codegen.jar,

 gf-lib/modules/glassfish-corba-csiv2-idl.jar,

 gf-lib/modules/glassfish-corba-internal-api.jar,

 gf-lib/modules/glassfish-corba-newtimer.jar,

 gf-lib/modules/glassfish-corba-omgapi.jar,

 gf-lib/modules/glassfish-corba-orb.jar,

 gf-lib/modules/glassfish-corba-orbgeneric.jar,

 gf-lib/modules/glassfish-ee-api.jar,

 gf-lib/modules/glassfish-extra-jre-packages.jar,

 gf-lib/modules/glassfish-mbeanserver.jar,

 gf-lib/modules/glassfish-naming.jar,

 gf-lib/modules/glassfish-oracle-jdbc-driver-packages.jar,

 gf-lib/modules/glassfish-registration.jar,

 gf-lib/modules/glassfish.jar,

 gf-lib/modules/gmbal.jar,

 gf-lib/modules/gms-adapter.jar,

 gf-lib/modules/gms-bootstrap.jar,

 gf-lib/modules/ha-api.jar,

 gf-lib/modules/ha-file-store.jar,

 gf-lib/modules/ha-shoal-cache-bootstrap.jar,

 gf-lib/modules/ha-shoal-cache-store.jar,

 gf-lib/modules/hk2-core.jar,

 gf-lib/modules/hk2.jar,

 gf-lib/modules/inmemory.jacc.provider.jar,

 gf-lib/modules/internal-api.jar,

 gf-lib/modules/jackson-core-asl.jar,

 gf-lib/modules/jackson-jaxrs.jar,

 gf-lib/modules/jackson-mapper-asl.jar,

 gf-lib/modules/jackson-xc.jar,

 gf-lib/modules/jaspic.provider.framework.jar,

 gf-lib/modules/javaee-kernel.jar,

 gf-lib/modules/javax.ejb.jar,

 gf-lib/modules/javax.enterprise.deploy.jar,

 gf-lib/modules/javax.jms.jar,

 gf-lib/modules/javax.mail.jar,

 gf-lib/modules/javax.management.j2ee.jar,

 gf-lib/modules/javax.persistence.jar,

 gf-lib/modules/javax.resource.jar,

 gf-lib/modules/javax.security.auth.message.jar,

 gf-lib/modules/javax.security.jacc.jar,

 gf-lib/modules/javax.servlet.jar,

 gf-lib/modules/javax.servlet.jsp.jar,

 gf-lib/modules/javax.servlet.jsp.jstl.jar,

 gf-lib/modules/javax.transaction.jar,

 gf-lib/modules/jaxrpc-api-osgi.jar,

 gf-lib/modules/jdbc-admin.jar,

 gf-lib/modules/jersey-client.jar,

 gf-lib/modules/jersey-core.jar,

 gf-lib/modules/jersey-gf-server.jar,

 gf-lib/modules/jersey-gf-statsproviders.jar,

 gf-lib/modules/jersey-json.jar,

 gf-lib/modules/jersey-multipart.jar,

 gf-lib/modules/jettison.jar,

 gf-lib/modules/jms-admin.jar,

 gf-lib/modules/jms-core.jar,

 gf-lib/modules/jmxremote_optional-repackaged.jar,

 gf-lib/modules/jpa-connector.jar,

 gf-lib/modules/jsr109-impl.jar,

 gf-lib/modules/jstl-connector.jar,

 gf-lib/modules/jstl-impl.jar,

 gf-lib/modules/jta.jar,

 gf-lib/modules/jts.jar,

 gf-lib/modules/kernel.jar,

 gf-lib/modules/launcher.jar,

 gf-lib/modules/ldapbp-repackaged.jar,

 gf-lib/modules/libpam4j-repackaged.jar,

 gf-lib/modules/load-balancer-admin.jar,

 gf-lib/modules/logging.jar,

 gf-lib/modules/management-api.jar,

 gf-lib/modules/metro-glue.jar,

 gf-lib/modules/mimepull.jar,

 gf-lib/modules/monitoring-core.jar,

 gf-lib/modules/orb-connector.jar,

 gf-lib/modules/orb-enabler.jar,

 gf-lib/modules/orb-iiop.jar,

 gf-lib/modules/osgi-adapter.jar,

 gf-lib/modules/osgi-container.jar,

 gf-lib/modules/osgi-jpa-extension.jar,

 gf-lib/modules/osgi-main.jar,

 gf-lib/modules/osgi-resource-locator.jar,

 gf-lib/modules/persistence-common.jar,

 gf-lib/modules/pkg-client.jar,

 gf-lib/modules/registration-api.jar,

 gf-lib/modules/registration-impl.jar,

 gf-lib/modules/rest-service.jar,

 gf-lib/modules/scattered-archive-api.jar,

 gf-lib/modules/schema2beans-repackaged.jar,

 gf-lib/modules/server-mgmt.jar,

 gf-lib/modules/simple-glassfish-api.jar,

 gf-lib/modules/soap-tcp.jar,

 gf-lib/modules/ssl-impl.jar,

 gf-lib/modules/stats77.jar,

 gf-lib/modules/sysnet-registration-repackaged.jar,

 gf-lib/modules/transaction-internal-api.jar,

 gf-lib/modules/trilead-ssh2-repackaged.jar,

 gf-lib/modules/woodstox-osgi.jar,

 gf-lib/modules/work-management.jar

Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.0"

Bundle-ActivationPolicy: lazy

Export-Package: com.ansis.aef.util,

 com.ansis.aef.util.audit.exception,

 com.ansis.aef.util.audit.feedback,

 com.ansis.aef.util.audit.logger,

 com.ansis.aef.util.audit.profiling,

 com.ansis.aef.util.io,

 com.ansis.aef.util.io.csv,

 com.ansis.aef.util.io.excel,

 com.ansis.aef.util.io.html,

 com.ansis.aef.util.io.stream,

 com.ansis.aef.util.manipulation,

 com.ansis.aef.util.manipulation.collection,

 com.ansis.aef.util.manipulation.number2words,

 com.ansis.aef.util.manipulation.security,

 com.ansis.aef.util.pattern.customsortable,

 com.ansis.aef.util.pattern.sortedtree,

 com.ansis.aef.util.pattern.treeitem,

 com.ansis.aef.util.ui.presentation,

 com.ansis.timetracker.client.lib.gf,

 com.ansis.timetracker.client.lib.gf.exception,

 com.ansis.timetracker.client.lib.gf.rest,

 com.ansis.timetracker.server,

 com.ansis.timetracker.server.exception,

 com.ansis.timetracker.server.model.helper,

 com.ansis.timetracker.server.model.helper.rest,

 com.ansis.timetracker.server.model.person,

 com.ansis.timetracker.server.model.project,

 com.ansis.timetracker.server.session.remote,

 com.ansis.timetracker.server.util,

 com.sun.appserv.security,

 

As you can see, it lists all necessary GFv3.1 Jars, but only exports two necessary packages.

Fragment 2: Lookup Code In Com.Ansis.Timetracker.Client.Lib.Gf

 

The class called EclipseConnectionDetails is the Eclipse-specific wrapper class for ConnectionDetails.java (see below). It contains the code to resolve the class loader issues, when run within an Eclipse bundle.

 

======== Listing EclipseConnectionDetails.java ============

 

 

/**

 * Contains all the details necessary to connect to the iREMS server.

 * 

 * EJB FAQ: https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html

 * 

 * GF CORBA home page: https://glassfish-corba.dev.java.net/

 * 

 * RMI JVM settings: java.sun.com/j2se/1.4.2/docs/guide/rmi/sunrmiproperties.html

 * 

 * Performance tuning RMI/J2EE: www.javaperformancetuning.com/tips/j2ee_rmi.shtml

 * 

 * 

 * Connecting standalone client to GFv3:

 * https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html#StandaloneRemoteEJB

 * forums1.java.net/jive/message.jspa

 * forums.java.net/jive/message.jspa

 * 

 * @author akozma

 * Copyright ANSIS, 2012: please reference ANSIS.com when reusing. 

 */

@SuppressWarnings("nls")

public class EclipseConnectionDetails extends ConnectionDetails {

 

// ==================== 1. Static Fields ========================

 

private static final long serialVersionUID = -4710045391762303501L;

 

// ==================== 4. Constructors ====================

 

/**

 * Server is localhost with default port.

 */

public EclipseConnectionDetails(final String user, final String password) {

super(user, password);

}

 

/**

 * Creates the initial context and sets the Security Context. 

 * Please note that if a host address without is port is supplied, then the appropriate port

 * number is appended automatically.

 * 

 * @param user

 * @param server

 * @param port

 * @param MD5 encoded password

 */

public EclipseConnectionDetails(final String user, final String password, finalString server, final String port) {

super(user, password, server, port);

}

 

 

// ==================== 8. Business Methods ====================

 

@Override

@SuppressWarnings("unchecked")

public  T lookup(final Class remoteInterface, final String jndiName) {

 

final ClassLoader contextFinder = Thread.currentThread().getContextClassLoader(); 

final ClassLoader ejbUtilsClassLoader = getClass().getClassLoader(); 

//System.out.println("### EJBUtils loader: " + ejbUtilsClassLoader); 

//System.out.println("### Context loader:" + contextFinder); 

 

Thread.currentThread().setContextClassLoader(ejbUtilsClassLoader); 

 

try { 

 

return (T) getInitialContext().lookup(jndiName);

 

} catch (final NamingException e) { 

throw new RuntimeException("Error looking up " + jndiName, e); 

} finally { 

Thread.currentThread().setContextClassLoader(contextFinder); 

 

}

 

 

 

The class called ConnectionDetails does all the work of looking up a requested session bean stub.

 

======== Listing ConnectionDetails.java ============

 

/**

 * Contains all the details necessary to connect to the iREMS server.

 * 

 * EJB FAQ: https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html

 * 

 * GF CORBA home page: https://glassfish-corba.dev.java.net/

 * 

 * RMI JVM settings: java.sun.com/j2se/1.4.2/docs/guide/rmi/sunrmiproperties.html

 * 

 * Performance tuning RMI/J2EE: www.javaperformancetuning.com/tips/j2ee_rmi.shtml

 * 

 * 

 * Connecting standalone client to GFv3:

 * https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html#StandaloneRemoteEJB

 * forums1.java.net/jive/message.jspa

 * forums.java.net/jive/message.jspa

 * 

 * @author akozma

 * Copyright ANSIS, 2010: please reference ANSIS when reusing. 

 */

@SuppressWarnings("nls")

public class ConnectionDetails implements Serializable {

 

// ==================== 1. Static Fields ========================

 

private static final long serialVersionUID = -4710045391762303501L;

 

private static AEFLog log = AEFLogger.getLogger(ConnectionDetails.class);

 

private static final String PROD_PORT_ALIASES = "p, prod, production";

private static final String SANDBOX_PORT_ALIASES = "s, , sb, test, sandb, sandbox";

 

 

// ====================== 2. Instance Fields =============================

 

final private String user;

final private String password;

final private String server;

 

final private String port;

 

private InitialContext context;

 

/**

 * Remote server bean object.

 */

private ActivityTrackerBeanRemote activityTrackerBean = null;

 

private DashboardFacadeBeanRemote dashboardFacade = null;

 

private AdminFacade adminFacade = null;

 

// ==================== 4. Constructors ====================

 

/**

 * Server is localhost with default port.

 */

public ConnectionDetails(final String user, final String password) {

this(user, password, null, null);

}

 

/**

 * Creates the initial context and sets the Security Context. 

 * Please note that if a host address without is port is supplied, then the appropriate port

 * number is appended automatically.

 * 

 * @param user

 * @param server

 * @param port

 * @param port

 * @param MD5 encoded password

 */

public ConnectionDetails(final String user, final String password, final String server, final String port) {

this.user = user;

this.password = password;

this.server = server;

this.port = port;

}

 

 

// ==================== 8. Business Methods ====================

 

@SuppressWarnings("unchecked")

public  T lookup(final Class remoteInterface, final String jndiName) {

 

try { 

 

T bean = null;

bean = (T) getInitialContext().lookup(jndiName);

 

return bean; 

 

} catch (final NamingException e) { 

throw new RuntimeException("Error looking up " + jndiName, e); 

 

}

 

/**

 * Creates an initial context to login to the server.

 */

public Context getInitialContext() {

 

if (context != null)

return context;

 

return createInitialContextGF();

}

 

private Context createInitialContextGF() {

 

// --------------------- -----------------------

 

Configuration.setConfiguration(new Configuration() {

 

@Override

public AppConfigurationEntry[] getAppConfigurationEntry(final String name) {

 

final Map options = new HashMap();

options.put("debug", new Boolean(false));

 

if ("default".equals(name))

return new AppConfigurationEntry[] {newAppConfigurationEntry("com.sun.enterprise.security.auth.login.ClientPasswordLoginModule", LoginModuleControlFlag.REQUIRED, options)};

if ("certificate".equals(name))

return new AppConfigurationEntry[] {newAppConfigurationEntry("com.sun.enterprise.security.auth.login.ClientCertificateLoginModule", LoginModuleControlFlag.REQUIRED, options)};

 

throw new TTRuntimeException("New Configuration was asked for: " + name + ", but it should have been default or certificate!");

}

 

@Override

public void refresh() {

// we don't need to refresh anything!

}

 

});

 

final ProgrammaticLogin pm = new ProgrammaticLogin();

final boolean success = pm.login(user, password); 

if (!success)

log.warn("Setup of login unsuccessful!");

 

    try {

context = new InitialContext(createPropertiesExistingGF());

} catch (final NamingException e) {

throw new TTRuntimeException("Error while logging in", e);

}

 

return context;

}

 

/**

 * That's the default initial naming factory that works with Dynamic RMI/IIOP stub generation.

 * 

 * @return

 */

private Properties createPropertiesExistingGF() {

 

final Properties props = new Properties(); 

    props.setProperty("java.naming.factory.initial","com.sun.enterprise.naming.SerialInitContextFactory");

    props.setProperty("java.naming.factory.state","com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl"); 

    

    // Only needed if server is running on a different host than localhost:

    if (!StringUtils.isEmpty(server))

    props.setProperty("org.omg.CORBA.ORBInitialHost", server); 

    // Optional.  Defaults to 3700.  Only needed if target orb port is not 3700.

    if (!StringUtils.isEmpty(port))

    props.setProperty("org.omg.CORBA.ORBInitialPort", port); 

    

//props.setProperty("com.sun.appserv.iiop.orbconnections","5");

//

////Increase ORB Response Timeout to 5 min instead of 30 min:

//props.setProperty("com.sun.corba.ee.transport.ORBTCPTimeouts", "500:90000:20"); 

props.setProperty("com.sun.corba.ee.transport.ORBWaitForResponseTimeout","300000"); 

    

    return props;

}

 

public ActivityTrackerBeanRemote getActivityTrackerBean() {

 

if (activityTrackerBean == null)

activityTrackerBean = lookup(ActivityTrackerBeanRemote.class, ActivityTrackerBeanRemote.JNDIName);

 

return activityTrackerBean;

}

 

/**

 * @return the bean object on the remote server.

 */

public DashboardFacadeBeanRemote getDashboardFacadeBean() {

 

if (dashboardFacade == null)

dashboardFacade = lookup(DashboardFacadeBeanRemote.class, DashboardFacadeBeanRemote.JNDIName);

 

return dashboardFacade;

}

 

/**

 * @return the bean object on the remote server.

 */

public AdminFacade getAdminFacadeBean() {

 

if (adminFacade == null)

adminFacade = lookup(AdminFacade.class, AdminFacade.JNDIName);

 

return adminFacade;

}

 

/**

 * Clears out all bean references.

 */

public void resetBeans() {

activityTrackerBean = null;

dashboardFacade = null;

adminFacade = null;

 

context = null;

}

 

// ==================== 12. Presentation ====================

 

@Override

public String toString() {

return user + "@" + server + ":" + port;

}

 

 

 

 

 

 

Fragment 3: MANIFEST.MF Of Client Code Plugin

 

Manifest-Version: 1.0

Bundle-ManifestVersion: 2

Bundle-Name: Time Tracker

Bundle-SymbolicName: com.ansis.timetracker.client; singleton:=true

Bundle-Version: 2.0.0

Bundle-Activator: com.ansis.timetracker.client.ClientActivator

Bundle-Vendor: ANSIS

Bundle-Localization: plugin

Require-Bundle: org.eclipse.ui;visibility:=reexport,

 org.eclipse.core.runtime;visibility:=reexport,

 org.eclipse.ui.forms;visibility:=reexport,

 org.eclipse.jface.text,

 org.eclipse.core.resources,

 org.eclipse.ui.editors,

 org.eclipse.ui.ide,

 com.ansis.timetracker.client.lib.gf;visibility:=reexport

Eclipse-LazyStart: true

Bundle-ClassPath: .,

 lib/nebula_cdatetime_0.9.0.jar

Export-Package: com.ansis.timetracker.client,

 com.ansis.timetracker.client.core,

 com.ansis.timetracker.client.dialogs,

 com.ansis.timetracker.client.views,

 com.ansis.timetracker.client.views.components,

 com.ansis.timetracker.client.wizards,

 org.eclipse.swt.nebula.widgets.cdatet

Fragment 4: Code In Client Plugin Using Session Bean Stubs

 

This code simply uses the SessionBean Remote Interface and calls its methods:

 

DashboardFacadeBeanRemote dashboard = getConnection().getDashboardFacadeBean();

 

dashboard.run

Gump, 06-12-12 10:30:
I read your post and wished I was good eonguh to write it
Stefan, 07-12-12 10:18:
Thanks a lot. That was the information I searched for two days.
Add comment

* - required field

*





*
*