ceylon.modules.bootstrap.CeylonRunTool Maven / Gradle / Ivy
/*
* Copyright 2012 Red Hat inc. and third party contributors as noted
* by the author tags.
* 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 ceylon.modules.bootstrap;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.jboss.modules.Module;
import org.jboss.modules.ModuleIdentifier;
import org.jboss.modules.ModuleLoader;
import com.redhat.ceylon.cmr.api.ModuleQuery;
import com.redhat.ceylon.cmr.ceylon.RepoUsingTool;
import com.redhat.ceylon.common.Constants;
import com.redhat.ceylon.common.ModuleUtil;
import com.redhat.ceylon.common.Versions;
import com.redhat.ceylon.common.config.DefaultToolOptions;
import com.redhat.ceylon.common.tool.Argument;
import com.redhat.ceylon.common.tool.Description;
import com.redhat.ceylon.common.tool.Option;
import com.redhat.ceylon.common.tool.OptionArgument;
import com.redhat.ceylon.common.tool.RemainingSections;
import com.redhat.ceylon.common.tool.Rest;
import com.redhat.ceylon.common.tool.Summary;
import com.redhat.ceylon.common.tools.CeylonTool;
import com.redhat.ceylon.compiler.java.runtime.tools.Backend;
import com.redhat.ceylon.compiler.java.runtime.tools.CeylonToolProvider;
import com.redhat.ceylon.compiler.java.runtime.tools.JavaRunnerOptions;
import com.redhat.ceylon.compiler.java.runtime.tools.ModuleNotFoundException;
import com.redhat.ceylon.compiler.java.runtime.tools.Runner;
import ceylon.modules.CeylonRuntimeException;
import ceylon.modules.bootstrap.loader.InitialModuleLoader;
@Summary("Executes a Ceylon program")
@Description(
"Executes the Ceylon program specified as the `` argument. " +
"The `` may optionally include a version."
)
@RemainingSections(
"## Compile flags" +
"\n\n" +
"The `--compile` option can take the following flags: " +
"\n\n" +
" - **never** - Never perform any compilation\n" +
" - **once** - Only compile when the compiled module is not available\n" +
" - **check** - Compile when the sources are newer than the compiled module\n" +
" - **force** - Always compile" +
"\n\n" +
"If the `--compile` flag is given without an argument it's the same as specifying `check`. " +
"If no flag is given at all it's the same as specifying `never`.\n" +
"\n\n" +
"## Configuration file" +
"\n\n" +
"The run tool accepts the following option from the Ceylon configuration file: " +
"`runtool.compile` " +
"(the equivalent option on the command line always has precedence)." +
"\n\n" +
"## EXAMPLE" +
"\n\n" +
"The following would execute the `com.example.foobar` module:" +
"\n\n" +
" ceylon run com.example.foobar/1.0.0" +
"\n\n" +
"The following would execute the `bob` function in the `com.example.foobar.gee` package of the same previous module:" +
"\n\n" +
" ceylon run --run com.example.foobar.gee::bob com.example.foobar/1.0.0"
)
public class CeylonRunTool extends RepoUsingTool {
private static final String CEYLON_RUNTIME = "ceylon.runtime";
private static volatile Module runtimeModule;
private String moduleNameOptVersion;
/** The (Ceylon) name of the functional to run, e.g. {@code foo.bar::baz} */
private String run;
private String compileFlags;
private boolean flatClasspath;
private List args = Collections.emptyList();
private boolean autoExportMavenDependencies;
private boolean upgradeDist = true;
public CeylonRunTool() {
super(CeylonMessages.RESOURCE_BUNDLE);
}
@Option(longName="flat-classpath")
@Description("Launches the Ceylon module using a flat classpath.")
public void setFlatClasspath(boolean flatClasspath) {
this.flatClasspath = flatClasspath;
}
@Argument(argumentName = "module", multiplicity = "1", order = 1)
public void setModule(String moduleNameOptVersion) {
this.moduleNameOptVersion = moduleNameOptVersion;
}
@Rest
public void setArgs(List args) {
this.args = args;
}
@Option(longName="auto-export-maven-dependencies")
@Description("When using JBoss Modules (the default), treats all module dependencies between " +
"Maven modules as shared.")
public void setAutoExportMavenDependencies(boolean autoExportMavenDependencies) {
this.autoExportMavenDependencies = autoExportMavenDependencies;
}
@OptionArgument(longName = "run", argumentName = "toplevel")
@Description("Specifies the fully qualified name of a toplevel method or class with no parameters. " +
"The format is: `qualified.package.name::classOrMethodName` with `::` acting as separator " +
"between the package name and the toplevel class or method name.")
public void setRun(String run) {
this.run = run;
}
@Option
@OptionArgument(argumentName = "flags")
@Description("Determines if and how compilation should be handled. " +
"Allowed flags include: `never`, `once`, `force`, `check`.")
public void setCompile(String compile) {
this.compileFlags = compile;
}
@Option(shortName='d')
@OptionArgument(argumentName = "flags")
@Description("Produce verbose output. " +
"If no `flags` are given then be verbose about everything, " +
"otherwise just be verbose about the flags which are present. " +
"Allowed flags include: `all`, `loader`, `cmr`.")
public void setVerbose(String verbose) {
super.setVerbose(verbose);
}
@Option
@Description("Link modules which were compiled with a more recent "
+ "version of the distribution to the version of that module "
+ "present in this distribution (" + Versions.CEYLON_VERSION_NUMBER + "). "
+ "This might fail with a linker error at runtime. For example "
+ "if the module depended on an API present in the more "
+ "recent version, but absent from " + Versions.CEYLON_VERSION_NUMBER +". "
+ "Allowed arguments are upgrade, downgrade or abort. Default: upgrade")
public void setLinkWithCurrentDistribution(boolean downgradeDist) {
this.upgradeDist = !downgradeDist;
}
@Override
public void initialize(CeylonTool mainTool) {
}
@Override
public void run() throws IOException {
if (compileFlags == null) {
compileFlags = DefaultToolOptions.getRunToolCompileFlags();
if (compileFlags.isEmpty()) {
compileFlags = COMPILE_NEVER;
}
} else if (compileFlags.isEmpty()) {
compileFlags = COMPILE_CHECK;
}
String module = ModuleUtil.moduleName(moduleNameOptVersion);
String version = checkModuleVersionsOrShowSuggestions(
getRepositoryManager(upgradeDist),
module,
ModuleUtil.moduleVersion(moduleNameOptVersion),
ModuleQuery.Type.JVM,
Versions.JVM_BINARY_MAJOR_VERSION,
Versions.JVM_BINARY_MINOR_VERSION,
// JS binary but don't care since JVM
null, null,
compileFlags);
if (version == null) {
return;
}
if (!version.isEmpty()) {
moduleNameOptVersion = ModuleUtil.makeModuleName(module, version);
}
if (flatClasspath) {
startInFlatClasspath(module, version);
return;
}
// else go on with JBoss modules
ArrayList argList = new ArrayList();
String ceylonVersion = System.getProperty(Constants.PROP_CEYLON_SYSTEM_VERSION);
if (ceylonVersion == null) {
ceylonVersion = Versions.CEYLON_VERSION_NUMBER;
}
String sysRep;
if (systemRepo != null) {
sysRep = systemRepo;
} else {
sysRep = System.getProperty(Constants.PROP_CEYLON_SYSTEM_REPO);
}
if (run != null) {
argList.add("-run");
argList.add(run);
}
if (offline) {
argList.add("-offline");
}
if (verbose != null) {
argList.add("-verbose");
if (verbose.isEmpty()) {
argList.add("all");
} else {
argList.add(verbose);
}
}
argList.add("-sysrep");
argList.add(sysRep);
if (!upgradeDist) {
argList.add("-downgrade-dist");
}
if (cacheRepo != null) {
argList.add("-cacherep");
argList.add(cacheRepo);
}
if (overrides != null) {
argList.add("-overrides");
argList.add(overrides);
}
if (noDefRepos) {
argList.add("-nodefreps");
}
if (autoExportMavenDependencies) {
argList.add("-auto-export-maven-dependencies");
}
if (repo != null) {
for (URI repo : this.repo) {
argList.add("-rep");
argList.add(repo.toString());
}
}
argList.add(moduleNameOptVersion);
argList.addAll(args);
try {
if (runtimeModule == null) {
synchronized (ModuleLoader.class) {
if (runtimeModule == null) {
org.jboss.modules.Module.setModuleLogger(new NoGreetingJDKModuleLogger());
System.setProperty("boot.module.loader", InitialModuleLoader.class.getName());
org.jboss.modules.Main.main(setupArguments(argList, sysRep, ceylonVersion));
// set runtime module
ModuleLoader ml = Module.getBootModuleLoader();
runtimeModule = ml.loadModule(ModuleIdentifier.create(CEYLON_RUNTIME, ceylonVersion));
} else {
runtimeModule.run(moduleArguments(argList));
}
}
} else {
runtimeModule.run(moduleArguments(argList));
}
} catch (Error err) {
throw err;
} catch (RuntimeException e) {
// get around a class loader issue
if(e instanceof CeylonRuntimeException == false
&& e.getClass().getName().equals("ceylon.modules.CeylonRuntimeException"))
throw new CeylonRuntimeException(e.getMessage());
throw e;
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
private void startInFlatClasspath(String module, String version) {
JavaRunnerOptions options = new JavaRunnerOptions();
if(repo != null) {
for (URI userRepository : repo) {
options.addUserRepository(userRepository.toASCIIString());
}
}
options.setOffline(offline);
options.setSystemRepository(systemRepo);
options.setVerboseCategory(verbose);
options.setRun(run);
options.setOverrides(overrides);
options.setDowngradeDist(!upgradeDist);
try {
Runner runner = CeylonToolProvider.getRunner(Backend.Java, options, module, version);
runner.run(args.toArray(new String[args.size()]));
} catch (ModuleNotFoundException e) {
throw new CeylonRuntimeException(e.getMessage());
}
}
private String[] setupArguments(List argList, String sysRep, String ceylonVersion) {
ArrayList setupArgs = new ArrayList();
setupArgs.addAll(Arrays.asList(
"-mp", sysRep,
CEYLON_RUNTIME + ":" + ceylonVersion,
"+executable", "ceylon.modules.jboss.runtime.JBossRuntime"));
setupArgs.addAll(argList);
String[] args = setupArgs.toArray(new String[setupArgs.size()]);
return args;
}
private String[] moduleArguments(List argList) {
ArrayList moduleArgs = new ArrayList();
moduleArgs.addAll(Arrays.asList(
"+executable", "ceylon.modules.jboss.runtime.JBossRuntime"));
moduleArgs.addAll(argList);
String[] args = moduleArgs.toArray(new String[moduleArgs.size()]);
return args;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy