Writing Plugged-in Java EE Apps: Jason Lee
Upcoming SlideShare
Loading in...5
×
 

Writing Plugged-in Java EE Apps: Jason Lee

on

  • 658 views

From continuous integration servers to blogging systems, we've all seen and used pluggable applications. Writing our own though can be an elusive task. That need not be the case, though, as the Java ...

From continuous integration servers to blogging systems, we've all seen and used pluggable applications. Writing our own though can be an elusive task. That need not be the case, though, as the Java EE spec contains all you need to do just that. In this session, we'll see how we can leverage the power of CDI to write, for example, easily extensible JSF applications. When the session is over, you'll have all you need to write the next killer app, and, thanks to Java EE, you'll be surprised to see how little work it really is.

Statistics

Views

Total Views
658
Views on SlideShare
657
Embed Views
1

Actions

Likes
1
Downloads
8
Comments
0

1 Embed 1

http://oracle.sociview.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Writing Plugged-in Java EE Apps: Jason Lee Writing Plugged-in Java EE Apps: Jason Lee Presentation Transcript

    • <Insert Picture Here>Writing Plugged-In Java EE AppsJason LeeJuly 9, 2012
    • Who Am I? • Principal MTS for Oracle Corporation (by way of Sun Microsystems) • Member of GlassFish team – RESTful Management APIs – Administration Console • JSF user/developer • Live in Oklahoma City, OKOracle Confidential 2
    • Introduction • Plugins are not a new concept – Means of providing extensibility or decomposing and decoupling functionality – The concept has been around for years • NetBeans/Eclipse/IDEA • Wordpress • Hudson • The what and why are easy. The how is the hard part. – How do I get access to the plugin code? – How do I identify the plugins deployed with the system – How do I expose core system functionality to the pluginsOracle Confidential 3
    • Introduction – cont. • Some background – GlassFish 3.x Administration Console • Core application does very little • All actual functionality delivered as plugins • Based on proprietary technologies – HK2/OSGi – JSFTemplating – For GlassFish 4.x, the basic stack had to change • Reevaluate whole system • Investigate HK2/OSGi, CDI, existing systems, etc. • Design a system based on modern technologies, preferably standardsOracle Confidential 4
    • Problem #1 – Class Loading • The hard part – Where do I put the jar files? – How do I load them? • Three (probably of many) choices – Repackaging – Manual ClassLoading – OSGiOracle Confidential 5
    • Problem #1 - Class Loading - Repackaging • Simple and portable – Guaranteed to support every Java EE technology supported in .war files • Ant-/Maven-/etc-based – Base distribution war – Collection of plugins – War rebuilt to include plugin jars • Liferay uses this. Works well. • Redeploys/upgrades take a bit more time/workOracle Confidential 6
    • Problem #1 - Class Loading - Repackaging #!/bin/bash DIST=$1 if [ "$DIST" == "" ] ; then echo "You must specify the distribution .war" exit 1 fi BASE=`echo $DIST | sed -e s/.war//` rm -rf work mkdir work cd work jar xf ../$DIST cp ../plugins/*jar WEB-INF/lib jar cf ../$BASE-repackaged.war * cd .. rm -rf workOracle Confidential 7
    • Problem #1 - Class Loading – Manual ClassLoading • Filesystem-based – Much like Wordpress • wordpress/wp-content/plugins/* – ~/.plugins • War is deployed unchanged • Fairly portable, in theory – Demo works on GlassFish – Currently breaks on JBoss – Should be easily solvable • Demo - PlummerOracle Confidential 8
    • Problem #1 - Class Loading – Manual ClassLoading public class PluginLoader implements Extension { // ... public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) { for (PluginFinder pluginFinder : getPluginFinders()) { try { for (Class<?> clazz : pluginFinder.getClasses()) { final AnnotatedType<?> annotatedType = beanManager.createAnnotatedType(clazz); logger.log(Level.INFO, "Adding AnnotatedType for {0}", annotatedType.toString()); bbd.addAnnotatedType(annotatedType); } } catch (Exception ex) { Logger.getLogger(PluginLoader.class.getName()).log(Level.SEVERE, null, ex); } } } // ... }Oracle Confidential 9
    • Problem #1 – Class Loading - OSGi • Well-defined and understood solution • Web Application Bundles not quite what we need – Requires repackaging • Container must support OSGi • Deployment will likely vary between containersOracle Confidential 10
    • Problem #1 – Class Loading - OSGi public class PluginActivator implements BundleActivator { @Override public void start(BundleContext context) throws Exception { ServiceTracker tracker = new ServiceTracker(context, PluginTracker.class.getName(), null); tracker.open(); PluginTracker pt = (PluginTracker)tracker.getService(); if (pt != null) { pt.registerPluginBundle(context.getBundle()); } tracker.close(); } @Override public void stop(BundleContext context) throws Exception { } }Oracle Confidential 11
    • Problem #1 – Class Loading - OSGi public class PluginTrackerImpl implements PluginTracker { @Override public void registerPluginBundle(Bundle bundle) { if (bundle.getEntry("META-INF/beans.xml") != null) { Enumeration<URL> e = bundle.findEntries("/", "*.class", true); while (e.hasMoreElements()) { String className = e.nextElement().getPath().substring(1).replace("/", "."); className = className.substring(0, className.length()-6); classes.add(className); } } } public Set<String> getClasses() { return classes; } }Oracle Confidential 12
    • Problem #1 – Class Loading - OSGi public class PlummerActivator implements BundleActivator { @Override public void start(BundleContext context) throws Exception { context.registerService(PluginTracker.class.getName(), PluginTrackerImpl.instance(), new Properties()); } @Override public void stop(BundleContext context) throws Exception { context.ungetService(context.getServiceReference(PluginTracker.class.getName())); } }Oracle Confidential 13
    • Problem #2 – Application Design • Largely application-specific • General strategies and techniques can be defined • Once plugins are loaded, how are they integrated into the application? – Java EE to the rescue • JSF • CDI • RESTOracle Confidential 14
    • JSF Extensibility • Views decomposed into fragments • Custom component used to insert fragments – pl:viewFragment • Current solution is Mojarra-specific – MyFaces solution needed – Can also be implemented in Swing/JavaFXOracle Confidential 15
    • CDI – The Real Work Horse • CDI Events – Pub/Sub – Loose coupling – Multiple Receivers • Programmatic Bean Lookup – Instance<Foo> – Iterate over over instancesOracle Confidential 16
    • JAX-RS Resources • Plugins can provide REST resources • Configure using Application rather than a package – javax.ws.rs.core.Application – <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class> com.sun.jersey.spi.container.servlet.ServletContainer </servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value> org.glassfish.plummer.kernel.rest.RestApplication </param-value> </init-param> </servlet>Oracle Confidential 17
    • JAX-RS Resources – Part 2 • Use CDI to find JAX-RS resources – Use a marker interface, e.g. RestResource – Look up BeanManager in JNDI • BeanManager beanManager = (BeanManager) initialContext.lookup("java:comp/BeanManager"); – Ask CDI for the RestResource instances • beanManager.getBeans(RestResource.class); – Return set of Classes • Application.getClasses()Oracle Confidential 18