com.google.code.play2.provider.play26.Play26Runner Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of play2-provider-play26 Show documentation
Show all versions of play2-provider-play26 Show documentation
Play! 2.x Provider for Play! 2.6.x
/*
* Copyright 2013-2017 Grzegorz Slowikowski (gslowikowski at gmail dot com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.google.code.play2.provider.play26;
import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarFile;
import play.core.Build;
import play.core.BuildDocHandler;
import play.core.BuildLink;
import play.core.server.ServerWithStop;
import com.google.code.play2.provider.api.Play2DevServer;
import com.google.code.play2.provider.api.Play2Runner;
import com.google.code.play2.provider.api.Play2RunnerConfiguration;
import com.google.code.play2.provider.play26.run.AssetsClassLoader;
import com.google.code.play2.provider.play26.run.NamedURLClassLoader;
import com.google.code.play2.provider.play26.run.Reloader;
import com.google.code.play2.provider.play26.run.ReloaderApplicationClassLoaderProvider;
import com.google.code.play2.provider.play26.run.ReloaderPlayDevServer;
import com.google.code.play2.provider.play26.run.ServerStartException;
import play.runsupport.classloader.DelegatingClassLoader;
public class Play26Runner
implements Play2Runner
{
private static final String DEV_SERVER_MAIN_CLASS = "play.core.server.DevServerStart";
@Override
public String getServerMainClass()
{
return "play.core.server.ProdServerStart";
}
@Override
public boolean supportsRunInDevMode()
{
return true;
}
@Override
public String getPlayDocsModuleId( String scalaBinaryVersion, String playVersion )
{
String docsArtifactName = playVersion.endsWith( "-SNAPSHOT" ) ? "play-docs" : "play-omnidoc";
return String.format( "com.typesafe.play:%s_%s:%s", docsArtifactName, scalaBinaryVersion, playVersion );
}
@Override
public Play2DevServer runInDevMode( Play2RunnerConfiguration configuration )
throws Throwable
{
ClassLoader buildLoader = Reloader.class.getClassLoader();
ClassLoader commonClassLoader = commonClassLoader( configuration.getDependencyClasspath() );
ReloaderApplicationClassLoaderProvider applicationClassLoaderProvider =
new ReloaderApplicationClassLoaderProvider();
ClassLoader delegatingLoader =
new DelegatingClassLoader( commonClassLoader, Build.sharedClasses, buildLoader,
applicationClassLoaderProvider );
ClassLoader applicationLoader =
new NamedURLClassLoader( "PlayDependencyClassLoader",
Reloader.toUrls( configuration.getDependencyClasspath() ), delegatingLoader );
ClassLoader assetsLoader =
new AssetsClassLoader( applicationLoader, configuration.getAssetsPrefix(),
configuration.getAssetsDirectory() );
Reloader reloader =
new Reloader( configuration.getBuildLink(), assetsLoader, configuration.getBaseDirectory(),
configuration.getOutputDirectories(), configuration.getDevSettings() );
applicationClassLoaderProvider.setReloader( reloader );
try
{
ClassLoader docsLoader =
new URLClassLoader( Reloader.toUrls( configuration.getDocsClasspath() ), applicationLoader );
JarFile docsJarFile =
configuration.getDocsFile() != null ? new JarFile( configuration.getDocsFile() ) : null;
Class> docHandlerFactoryClass = docsLoader.loadClass( "play.docs.BuildDocHandlerFactory" );
BuildDocHandler buildDocHandler = null;
if ( docsJarFile != null )
{
Method factoryMethod = docHandlerFactoryClass.getMethod( "fromJar", JarFile.class, String.class );
buildDocHandler = (BuildDocHandler) factoryMethod.invoke( null, docsJarFile, "play/docs/content" );
}
else
{
Method factoryMethod = docHandlerFactoryClass.getMethod( "empty" );
buildDocHandler = (BuildDocHandler) factoryMethod.invoke( null );
}
Class> mainClass = applicationLoader.loadClass( DEV_SERVER_MAIN_CLASS );
String mainMethod = configuration.getHttpPort() != null ? "mainDevHttpMode" : "mainDevOnlyHttpsMode";
int port =
configuration.getHttpPort() != null ? configuration.getHttpPort().intValue()
: configuration.getHttpsPort().intValue();
String httpAddress = configuration.getHttpAddress();
Method mainDev =
mainClass.getMethod( mainMethod, BuildLink.class, BuildDocHandler.class, Integer.TYPE, String.class );
ServerWithStop server =
(ServerWithStop) mainDev.invoke( null, reloader, buildDocHandler, port, httpAddress );
return new ReloaderPlayDevServer( server, docsJarFile, reloader );
}
catch ( Throwable t )
{
if ( "play.core.server.ServerListenException".equals( getRootCause( t ).getClass().getName() ) )
{
throw new ServerStartException( t );
}
throw t;
}
}
private Throwable getRootCause( Throwable t )
{
return t.getCause() == null ? t : getRootCause( t.getCause() );
}
private ClassLoader commonClassLoader( List classpath )
throws MalformedURLException
{
List commonClasspath = new ArrayList( 1 );
for ( File depFile : classpath )
{
String name = depFile.getName();
if ( name.startsWith( "h2-" ) )
{
commonClasspath.add( depFile.toURI().toURL() );
}
}
// sun.misc.Launcher$ExtClassLoader (see: https://github.com/playframework/playframework/pull/3420)
ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
return new URLClassLoader( commonClasspath.toArray( new URL[commonClasspath.size()] ), parent );
}
}