├── .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 extends Deployer> 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 extends Annotation>[] getAnnotationTypes() {
50 | Class extends Annotation>[] a = (Class extends Annotation>[]) 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 |
--------------------------------------------------------------------------------