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:
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
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
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.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