├── .gitignore ├── admingui ├── osgi.bundle ├── src │ ├── main │ │ ├── resources │ │ │ ├── images │ │ │ │ └── sample.png │ │ │ ├── playConfigNode.jsf │ │ │ ├── playConfigLink.jsf │ │ │ ├── META-INF │ │ │ │ └── admingui │ │ │ │ │ └── console-config.xml │ │ │ ├── playContainer.jsf │ │ │ ├── playApp.jsf │ │ │ └── playDeployment.jsf │ │ └── java │ │ │ └── org │ │ │ └── glassfish │ │ │ └── play │ │ │ └── admingui │ │ │ └── plugin │ │ │ └── PlayConsolePlugin.java │ └── test │ │ └── java │ │ └── org │ │ └── glassfish │ │ └── admingui │ │ └── AppTest.java └── pom.xml ├── container ├── src │ └── main │ │ ├── resources │ │ └── init.xml │ │ └── java │ │ └── org │ │ └── glassfish │ │ └── play │ │ └── extension │ │ ├── PlayContainerConfig.java │ │ ├── PlayContainer.java │ │ ├── PlayDeployer.java │ │ ├── PlayConfigCommand.java │ │ ├── PlaySniffer.java │ │ └── PlayAppContainer.java └── pom.xml └── README.textile /.gitignore: -------------------------------------------------------------------------------- 1 | target -------------------------------------------------------------------------------- /admingui/osgi.bundle: -------------------------------------------------------------------------------- 1 | -exportcontents: org.glassfish.sample.admingui 2 | -------------------------------------------------------------------------------- /container/src/main/resources/init.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admingui/src/main/resources/images/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/playframework/play-glassfish/master/admingui/src/main/resources/images/sample.png -------------------------------------------------------------------------------- /admingui/src/main/resources/playConfigNode.jsf: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /admingui/src/main/resources/playConfigLink.jsf: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /admingui/src/main/java/org/glassfish/play/admingui/plugin/PlayConsolePlugin.java: -------------------------------------------------------------------------------- 1 | package org.glassfish.play.admingui.plugin; 2 | 3 | import org.glassfish.api.admingui.ConsoleProvider; 4 | import org.jvnet.hk2.annotations.Service; 5 | 6 | import java.net.URL; 7 | 8 | @Service 9 | public class PlayConsolePlugin implements ConsoleProvider { 10 | 11 | @Override 12 | public URL getConfiguration() { 13 | return null; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /container/src/main/java/org/glassfish/play/extension/PlayContainerConfig.java: -------------------------------------------------------------------------------- 1 | package org.glassfish.play.extension; 2 | 3 | import java.beans.PropertyVetoException; 4 | import org.glassfish.api.admin.config.Container; 5 | import org.jvnet.hk2.config.Attribute; 6 | import org.jvnet.hk2.config.Configured; 7 | 8 | @Configured 9 | public interface PlayContainerConfig extends Container { 10 | 11 | @Attribute 12 | public String getFrameworkPath(); 13 | public void setFrameworkPath(String path) throws PropertyVetoException; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /container/src/main/java/org/glassfish/play/extension/PlayContainer.java: -------------------------------------------------------------------------------- 1 | package org.glassfish.play.extension; 2 | 3 | import org.glassfish.api.container.Container; 4 | import org.glassfish.api.deployment.Deployer; 5 | import org.jvnet.hk2.annotations.Service; 6 | 7 | /** 8 | * @author Guillaume Bort 9 | */ 10 | @Service(name="org.glassfish.play.extension.PlayContainer") 11 | public class PlayContainer implements Container { 12 | 13 | @Override 14 | public Class getDeployer() { 15 | return PlayDeployer.class; 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return "play"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /admingui/src/main/resources/META-INF/admingui/console-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 17 | 18 | 24 | 25 | 31 | 32 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /container/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.glassfish 5 | glassfish-parent 6 | 3.1.1 7 | 8 | org.glassfish.play 9 | 4.0.0 10 | play-container 11 | 12 | hk2-jar 13 | GlassFish container for Play application 14 | 15 | 16 | 17 | glassfish-repo-archive 18 | Nexus repository collection for Glassfish 19 | http://maven.glassfish.org/content/groups/glassfish 20 | 21 | never 22 | 23 | 24 | 25 | 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-compiler-plugin 30 | 31 | 1.6 32 | 1.6 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.glassfish.common 40 | glassfish-api 41 | 3.1.1 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /container/src/main/java/org/glassfish/play/extension/PlayDeployer.java: -------------------------------------------------------------------------------- 1 | package org.glassfish.play.extension; 2 | 3 | import java.io.File; 4 | import org.glassfish.api.deployment.Deployer; 5 | import org.glassfish.api.deployment.MetaData; 6 | import org.glassfish.api.deployment.DeploymentContext; 7 | import org.glassfish.api.container.RequestDispatcher; 8 | import org.jvnet.hk2.annotations.Service; 9 | import org.jvnet.hk2.annotations.Inject; 10 | 11 | 12 | /** 13 | * @author Guillaume Bort 14 | */ 15 | @Service 16 | public class PlayDeployer implements Deployer { 17 | 18 | @Inject 19 | RequestDispatcher dispatcher; 20 | 21 | @Inject 22 | PlayContainerConfig config; 23 | 24 | @Override 25 | public MetaData getMetaData() { 26 | return null; 27 | } 28 | 29 | @Override 30 | public V loadMetaData(Class type, DeploymentContext context) { 31 | return null; 32 | } 33 | 34 | @Override 35 | public boolean prepare(DeploymentContext context) { 36 | return false; 37 | } 38 | 39 | @Override 40 | public PlayAppContainer load(PlayContainer container, DeploymentContext context) { 41 | String contextRoot = context.getModuleProps().getProperty("context-root", context.getSourceDir().getName()); 42 | if(!contextRoot.startsWith("/")) { 43 | contextRoot = "/" + contextRoot; 44 | } 45 | context.getModuleProps().setProperty("context-root", contextRoot); 46 | String playHome = context.getModuleProps().getProperty("play.home", config.getFrameworkPath()); 47 | PlayAppContainer appCtr = new PlayAppContainer(container, dispatcher, context.getSourceDir(), contextRoot, new File(playHome)); 48 | return appCtr; 49 | } 50 | 51 | @Override 52 | public void unload(PlayAppContainer appContainer, DeploymentContext context) { 53 | } 54 | 55 | @Override 56 | public void clean(DeploymentContext context) { 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. This is a Play container for Glassfish 2 | 3 | It allows to deploy any Play application directly in the Glassfish application server (without to have to package it as WAR archive before). 4 | 5 | bq. Try the following steps with Glassfish 3.0.1 and "play-1.1-unstable-r1095":http://download.playframework.org/1.1-nightly/play-1.1-unstable-r1095.zip. Also I've my Play installation at /Users/guillaume/Desktop/play/1.1; be sure to change the following commands to match your real installation path 6 | 7 | h2. Build the play-container.jar for glassfish 8 | 9 | Enter the *container* directory and run: 10 | 11 | bc. mvn package 12 | 13 | Then copy the *target/play-container.jar* library to *$GLASSFISH_HOME/glassfish/modules*. That's all, the container is installed. It will be available in the glassfish repository once officially released. 14 | 15 | h2. Configure the Play container 16 | 17 | Start glassfish, and run the **asadmin** command. At the prompt run the following command: 18 | 19 | bc. asadmin> play-config --frameworkPath /Users/guillaume/Desktop/play/1.1 20 | 21 | It should result with 'Command play-config executed successfully.' 22 | 23 | h2. Deploy a Play application 24 | 25 | You can try to deploy one of the sample application provided with the framework. Let's try to deloy 'zencontact'; at the *asadmin* prompt enter: 26 | 27 | bc. asadmin> deploy --contextroot zen /Users/guillaume/Desktop/play/1.1/samples-and-tests/zencontact 28 | 29 | It should result with 'Application deployed successfully with name zencontact.' 30 | 31 | You can now try to launch the app at "http://localhost:8080/zen":http://localhost:8080/zen, and the application should appear in the glassfish GUI admin. We will add the GUI screens for Play container soon. 32 | 33 | h2. Build the admin GUI plugin 34 | 35 | Enter the *admingui* directory and run: 36 | 37 | bc. mvn package 38 | 39 | Then copy the *target/console-play-plugin.jar* library to *$GLASSFISH_HOME/glassfish/modules*. Restart the glassfish server and open the administration console at "http://localhost:4848":http://localhost:4848. There is now a *Play Container* configuration page under the *Configuration* node. And you can choose *Play Application* in the drop down list of the deployment page. -------------------------------------------------------------------------------- /container/src/main/java/org/glassfish/play/extension/PlayConfigCommand.java: -------------------------------------------------------------------------------- 1 | package org.glassfish.play.extension; 2 | 3 | import java.beans.PropertyVetoException; 4 | import java.io.IOException; 5 | import java.net.URL; 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | import org.glassfish.api.Param; 9 | import org.glassfish.api.admin.AdminCommand; 10 | import org.glassfish.api.admin.AdminCommandContext; 11 | import org.glassfish.api.admin.config.ConfigParser; 12 | import org.jvnet.hk2.annotations.Inject; 13 | import org.jvnet.hk2.annotations.Service; 14 | import org.jvnet.hk2.component.Habitat; 15 | import org.jvnet.hk2.config.ConfigSupport; 16 | import org.jvnet.hk2.config.SingleConfigCode; 17 | import org.jvnet.hk2.config.TransactionFailure; 18 | import org.jvnet.hk2.component.PerLookup; 19 | import org.jvnet.hk2.annotations.Scoped; 20 | 21 | @Service(name = "play-config") 22 | @Scoped(PerLookup.class) 23 | public class PlayConfigCommand implements AdminCommand { 24 | 25 | @Param 26 | String frameworkPath; 27 | 28 | @Inject(optional = true) 29 | PlayContainerConfig config; 30 | 31 | @Inject 32 | ConfigParser configParser; 33 | 34 | @Inject 35 | Habitat habitat; 36 | 37 | public void execute(AdminCommandContext adminCommandContext) { 38 | try { 39 | if (config == null) { 40 | URL url = this.getClass().getClassLoader().getResource("init.xml"); 41 | if (url != null) { 42 | try { 43 | config = configParser.parseContainerConfig(habitat, url, PlayContainerConfig.class); 44 | } catch (IOException e) { 45 | throw new RuntimeException(e); 46 | } 47 | } else { 48 | Logger.getAnonymousLogger().log(Level.SEVERE, "Cannot init Play container configuration"); 49 | } 50 | } 51 | ConfigSupport.apply(new SingleConfigCode() { 52 | 53 | public Object run(PlayContainerConfig playContainerConfig) throws PropertyVetoException, TransactionFailure { 54 | playContainerConfig.setFrameworkPath(frameworkPath); 55 | return null; 56 | } 57 | }, config); 58 | } catch (TransactionFailure e) { 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /admingui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.glassfish.admingui 7 | admingui 8 | 3.0-SNAPSHOT 9 | 10 | console-play-plugin 11 | hk2-jar 12 | Admin Console for Play container 13 | Play Plugin bundle for Glassfish V3 Admin Console 14 | 15 | 16 | 17 | 18 | src/main/resources 19 | 20 | **/*.jar 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | glassfish-repository-wsinterop 30 | Java.net Repository for Glassfish 31 | http://maven.dyndns.org/glassfish/ 32 | 33 | never 34 | 35 | 36 | 37 | glassfish-repository 38 | Java.net Repository for Glassfish 39 | http://download.java.net/maven/glassfish 40 | 41 | never 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.glassfish.common 51 | glassfish-api 52 | ${project.version} 53 | 54 | 55 | org.glassfish.admingui 56 | console-plugin-service 57 | ${project.version} 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /admingui/src/main/resources/playContainer.jsf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 30 | 31 | 32 | 33 | #include "/common/shared/alertMsg.inc" 34 | 35 | #include "/common/shared/editPageButtons.inc" 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /admingui/src/test/java/org/glassfish/admingui/AppTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 4 | * 5 | * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 6 | * 7 | * The contents of this file are subject to the terms of either the GNU 8 | * General Public License Version 2 only ("GPL") or the Common Development 9 | * and Distribution License("CDDL") (collectively, the "License"). You 10 | * may not use this file except in compliance with the License. You can obtain 11 | * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html 12 | * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific 13 | * language governing permissions and limitations under the License. 14 | * 15 | * When distributing the software, include this License Header Notice in each 16 | * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. 17 | * Sun designates this particular file as subject to the "Classpath" exception 18 | * as provided by Sun in the GPL Version 2 section of the License file that 19 | * accompanied this code. If applicable, add the following below the License 20 | * Header, with the fields enclosed by brackets [] replaced by your own 21 | * identifying information: "Portions Copyrighted [year] 22 | * [name of copyright owner]" 23 | * 24 | * Contributor(s): 25 | * 26 | * If you wish your version of this file to be governed by only the CDDL or 27 | * only the GPL Version 2, indicate your decision by adding "[Contributor] 28 | * elects to include this software in this distribution under the [CDDL or GPL 29 | * Version 2] license." If you don't indicate a single choice of license, a 30 | * recipient has the option to distribute your version of this file under 31 | * either the CDDL, the GPL Version 2 or to extend the choice of license to 32 | * its licensees as provided above. However, if you add GPL Version 2 code 33 | * and therefore, elected the GPL Version 2 license, then the option applies 34 | * only if the new code is made subject to such option by the copyright 35 | * holder. 36 | */ 37 | package org.glassfish.admingui; 38 | 39 | import junit.framework.Test; 40 | import junit.framework.TestCase; 41 | import junit.framework.TestSuite; 42 | 43 | /** 44 | * Unit test for simple App. 45 | */ 46 | public class AppTest 47 | extends TestCase 48 | { 49 | /** 50 | * Create the test case 51 | * 52 | * @param testName name of the test case 53 | */ 54 | public AppTest( String testName ) 55 | { 56 | super( testName ); 57 | } 58 | 59 | /** 60 | * @return the suite of tests being tested 61 | */ 62 | public static Test suite() 63 | { 64 | return new TestSuite( AppTest.class ); 65 | } 66 | 67 | /** 68 | * Rigourous Test :-) 69 | */ 70 | public void testApp() 71 | { 72 | assertTrue( true ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /container/src/main/java/org/glassfish/play/extension/PlaySniffer.java: -------------------------------------------------------------------------------- 1 | package org.glassfish.play.extension; 2 | 3 | import org.glassfish.api.container.Sniffer; 4 | import org.glassfish.api.deployment.archive.ReadableArchive; 5 | import org.glassfish.api.admin.config.ConfigParser; 6 | import org.jvnet.hk2.annotations.Service; 7 | import org.jvnet.hk2.annotations.Inject; 8 | import org.jvnet.hk2.component.Habitat; 9 | import com.sun.enterprise.module.Module; 10 | 11 | import java.util.logging.Logger; 12 | import java.util.Map; 13 | import java.io.IOException; 14 | import java.lang.annotation.Annotation; 15 | import java.lang.reflect.Array; 16 | import java.net.URL; 17 | import java.util.logging.Level; 18 | 19 | /** 20 | * @author Guillaume Bort 21 | */ 22 | @Service(name = "play") 23 | public class PlaySniffer implements Sniffer { 24 | 25 | @Inject(optional = true) 26 | PlayContainerConfig config; 27 | 28 | @Inject 29 | ConfigParser configParser; 30 | 31 | @Inject 32 | Habitat habitat; 33 | 34 | @Override 35 | public boolean handles(ReadableArchive source, ClassLoader loader) { 36 | try { 37 | return source.exists("app") && source.exists("conf/application.conf"); 38 | } catch (IOException e) { 39 | return false; 40 | } 41 | } 42 | 43 | @Override 44 | public String[] getURLPatterns() { 45 | return new String[0]; 46 | } 47 | 48 | @Override 49 | public Class[] getAnnotationTypes() { 50 | Class[] a = (Class[]) Array.newInstance(Class.class, 0); 51 | return a; 52 | } 53 | 54 | @Override 55 | public String getModuleType() { 56 | return "play"; 57 | } 58 | 59 | @Override 60 | public Module[] setup(String containerHome, Logger logger) throws IOException { 61 | if (config == null) { 62 | URL url = this.getClass().getClassLoader().getResource("init.xml"); 63 | if (url != null) { 64 | configParser.parseContainerConfig(habitat, url, PlayContainerConfig.class); 65 | } else { 66 | Logger.getAnonymousLogger().log(Level.SEVERE, "Cannot init Play container configuration"); 67 | } 68 | } 69 | return null; 70 | } 71 | 72 | @Override 73 | public void tearDown() { 74 | } 75 | 76 | @Override 77 | public String[] getContainersNames() { 78 | String[] c = {PlayContainer.class.getName()}; 79 | return c; 80 | } 81 | 82 | @Override 83 | public boolean isUserVisible() { 84 | return true; 85 | } 86 | 87 | @Override 88 | public Map getDeploymentConfigurations(ReadableArchive source) throws IOException { 89 | return null; 90 | } 91 | 92 | @Override 93 | public String[] getIncompatibleSnifferTypes() { 94 | return new String[0]; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /admingui/src/main/resources/playApp.jsf: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /admingui/src/main/resources/playDeployment.jsf: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 20 | $page{playId}); 22 | /> 23 | 24 | 25 | 26 | 28 | $page{appNameId}); 30 | /> 31 | 32 | 33 | 34 | 35 | 36 | $page{contextRootId}); 38 | /> 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 63 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /container/src/main/java/org/glassfish/play/extension/PlayAppContainer.java: -------------------------------------------------------------------------------- 1 | package org.glassfish.play.extension; 2 | 3 | import org.glassfish.api.deployment.ApplicationContainer; 4 | import org.glassfish.api.deployment.ApplicationContext; 5 | import org.glassfish.api.container.RequestDispatcher; 6 | import org.glassfish.api.container.EndpointRegistrationException; 7 | import com.sun.grizzly.tcp.http11.GrizzlyAdapter; 8 | 9 | import java.io.File; 10 | import java.io.FileInputStream; 11 | import java.net.URL; 12 | import java.net.URLClassLoader; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.Properties; 16 | import java.util.logging.Level; 17 | import java.util.logging.Logger; 18 | 19 | /** 20 | * @author Guillaume Bort 21 | */ 22 | public class PlayAppContainer implements ApplicationContainer { 23 | 24 | static final Logger logger = Logger.getLogger(PlayAppContainer.class.getName()); 25 | 26 | final PlayContainer ctr; 27 | final RequestDispatcher dispatcher; 28 | final File appDir; 29 | final String contextPath; 30 | final File framework; 31 | ClassLoader applicationClassLoader; 32 | 33 | public PlayAppContainer(PlayContainer ctr, RequestDispatcher dispatcher, File appDir, String contextRoot, File frameworkPath) { 34 | this.ctr = ctr; 35 | this.dispatcher = dispatcher; 36 | this.appDir = appDir; 37 | this.contextPath = contextRoot; 38 | this.framework = frameworkPath; 39 | } 40 | 41 | @Override 42 | public Object getDescriptor() { 43 | return null; 44 | } 45 | 46 | // Finds eighter play.jar or play-x.y.z.jar 47 | private File resolvePlayJarFile(File playFrameworkFolder) { 48 | // just find the first play*.jar file 49 | for ( File file : playFrameworkFolder.listFiles()) { 50 | String name = file.getName(); 51 | if ( name.startsWith("play") && name.endsWith(".jar")) { 52 | return file; 53 | } 54 | } 55 | return null; 56 | } 57 | 58 | @Override 59 | public boolean start(ApplicationContext startupContext) throws Exception { 60 | if(!this.framework.exists() || !new File(this.framework, "play").exists()) { 61 | logger.log(Level.SEVERE, "Invalid path for Play framework: " + framework.getAbsolutePath()); 62 | return false; 63 | } 64 | // Build the classpath 65 | List classpath = new ArrayList(); 66 | 67 | // The default 68 | classpath.add(new File(this.appDir, "conf").toURI().toURL()); 69 | 70 | // find the correct play.jar file 71 | File frameworkFolder = new File(this.framework, "framework/"); 72 | File playJarFile = resolvePlayJarFile( frameworkFolder); 73 | if ( playJarFile == null ) { 74 | logger.log(Level.SEVERE, "Cannot find any play*.jar file inside " + frameworkFolder.getAbsolutePath()); 75 | return false; 76 | } 77 | classpath.add(playJarFile.toURI().toURL()); 78 | 79 | // The application 80 | if(new File(this.appDir, "lib").exists()) { 81 | for(File jar : new File(this.appDir, "lib").listFiles()) { 82 | if(jar.getName().endsWith(".jar")) { 83 | classpath.add(jar.toURI().toURL()); 84 | } 85 | } 86 | } 87 | 88 | // The modules 89 | classpath.add(new File(this.framework, "modules/grizzly/lib/play-grizzly.jar").toURI().toURL()); 90 | Properties applicationConf = new Properties(); 91 | { 92 | FileInputStream fis = new FileInputStream(new File(this.appDir, "conf/application.conf")); 93 | applicationConf.load(fis); 94 | fis.close(); 95 | } 96 | for(Object key : applicationConf.keySet()) { 97 | if(key.toString().startsWith("module.") || key.toString().startsWith("%glassfish.module.")) { 98 | String path = (String)applicationConf.get(key); 99 | File moduleRoot = new File(path.replace("${play.path}", this.framework.getAbsolutePath())); 100 | if(new File(moduleRoot, "lib").exists()) { 101 | for(File jar : new File(moduleRoot, "lib").listFiles()) { 102 | if(jar.getName().endsWith(".jar")) { 103 | classpath.add(jar.toURI().toURL()); 104 | } 105 | } 106 | } 107 | } 108 | } 109 | 110 | // The framework 111 | for(File jar : new File(this.framework, "framework/lib").listFiles()) { 112 | if(jar.getName().endsWith(".jar")) { 113 | classpath.add(jar.toURI().toURL()); 114 | } 115 | } 116 | 117 | URL[] computedClasspath = classpath.toArray(new URL[classpath.size()]); 118 | applicationClassLoader = new URLClassLoader(computedClasspath, startupContext.getClassLoader()); 119 | 120 | logger.info("Starting Play application from " + appDir + " to " + contextPath); 121 | 122 | GrizzlyAdapter adapter; 123 | ClassLoader originalCtxClassLoader = Thread.currentThread().getContextClassLoader(); 124 | try { 125 | Thread.currentThread().setContextClassLoader(applicationClassLoader); 126 | Class adapterClass = applicationClassLoader.loadClass("play.modules.grizzly.PlayGrizzlyAdapter"); 127 | adapter = GrizzlyAdapter.class.cast( 128 | adapterClass.getConstructor(File.class, String.class, String.class).newInstance(appDir, "glassfish", contextPath) 129 | ); 130 | } finally { 131 | Thread.currentThread().setContextClassLoader(originalCtxClassLoader); 132 | } 133 | 134 | if(adapter != null) { 135 | adapter.start(); 136 | dispatcher.registerEndpoint(contextPath, adapter, this); 137 | return true; 138 | } 139 | 140 | return false; 141 | } 142 | 143 | @Override 144 | public boolean stop(ApplicationContext stopContext) { 145 | try { 146 | dispatcher.unregisterEndpoint(contextPath); 147 | applicationClassLoader = null; 148 | } catch (EndpointRegistrationException e) { 149 | return false; 150 | } 151 | return true; 152 | } 153 | 154 | @Override 155 | public boolean suspend() { 156 | return false; 157 | } 158 | 159 | @Override 160 | public boolean resume() throws Exception { 161 | return false; 162 | } 163 | 164 | @Override 165 | public ClassLoader getClassLoader() { 166 | return applicationClassLoader; 167 | } 168 | } 169 | --------------------------------------------------------------------------------