use of io.quarkus.deployment.codegen.CodeGenData in project quarkus by quarkusio.
the class CodeGenerator method init.
public static List<CodeGenData> init(ClassLoader deploymentClassLoader, PathCollection sourceParentDirs, Path generatedSourcesDir, Path buildDir, Consumer<Path> sourceRegistrar) throws CodeGenException {
return callWithClassloader(deploymentClassLoader, () -> {
List<CodeGenData> result = new ArrayList<>();
Class<? extends CodeGenProvider> codeGenProviderClass;
try {
// noinspection unchecked
codeGenProviderClass = (Class<? extends CodeGenProvider>) deploymentClassLoader.loadClass(CodeGenProvider.class.getName());
} catch (ClassNotFoundException e) {
throw new CodeGenException("Failed to load CodeGenProvider class from deployment classloader", e);
}
for (CodeGenProvider provider : ServiceLoader.load(codeGenProviderClass, deploymentClassLoader)) {
Path outputDir = codeGenOutDir(generatedSourcesDir, provider, sourceRegistrar);
for (Path sourceParentDir : sourceParentDirs) {
result.add(new CodeGenData(provider, outputDir, sourceParentDir.resolve(provider.inputDirectory()), buildDir));
}
}
return result;
});
}
use of io.quarkus.deployment.codegen.CodeGenData in project quarkus by quarkusio.
the class IsolatedDevModeMain method accept.
// the main entry point, but loaded inside the augmentation class loader
@Override
public void accept(CuratedApplication o, Map<String, Object> params) {
// setup the dev mode thread pool for NIO
System.setProperty("java.nio.channels.DefaultThreadPool.threadFactory", "io.quarkus.dev.io.NioThreadPoolThreadFactory");
Timing.staticInitStarted(o.getBaseRuntimeClassLoader(), false);
// https://github.com/quarkusio/quarkus/issues/9748
// if you have an app with all daemon threads then the app thread
// may be the only thread keeping the JVM alive
// during the restart process when this thread is stopped then
// the JVM will die
// we start this thread to keep the JVM alive until the shutdown hook is run
// even for command mode we still want the JVM to live until it receives
// a signal to make the 'press enter to restart' function to work
new Thread(new Runnable() {
@Override
public void run() {
try {
shutdownLatch.await();
} catch (InterruptedException ignore) {
}
}
}, "Quarkus Devmode keep alive thread").start();
try {
curatedApplication = o;
Object potentialContext = params.get(DevModeContext.class.getName());
if (potentialContext instanceof DevModeContext) {
context = (DevModeContext) potentialContext;
} else {
// this was from the external class loader
// we need to copy it into this one
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(out);
oo.writeObject(potentialContext);
context = (DevModeContext) new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())).readObject();
}
augmentAction = new AugmentActionImpl(curatedApplication, Collections.singletonList(new Consumer<BuildChainBuilder>() {
@Override
public void accept(BuildChainBuilder buildChainBuilder) {
buildChainBuilder.addBuildStep(new BuildStep() {
@Override
public void execute(BuildContext context) {
// we need to make sure all hot reloadable classes are application classes
context.produce(new ApplicationClassPredicateBuildItem(new Predicate<String>() {
@Override
public boolean test(String s) {
QuarkusClassLoader cl = (QuarkusClassLoader) Thread.currentThread().getContextClassLoader();
// if the class file is present in this (and not the parent) CL then it is an application class
List<ClassPathElement> res = cl.getElementsWithResource(s.replace('.', '/') + ".class", true);
return !res.isEmpty();
}
}));
}
}).produces(ApplicationClassPredicateBuildItem.class).build();
}
}), Collections.emptyList());
List<CodeGenData> codeGens = new ArrayList<>();
QuarkusClassLoader deploymentClassLoader = curatedApplication.createDeploymentClassLoader();
for (DevModeContext.ModuleInfo module : context.getAllModules()) {
if (!module.getSourceParents().isEmpty() && module.getPreBuildOutputDir() != null) {
// it's null for remote dev
codeGens.addAll(CodeGenerator.init(deploymentClassLoader, module.getSourceParents(), Paths.get(module.getPreBuildOutputDir()), Paths.get(module.getTargetDir()), sourcePath -> module.addSourcePathFirst(sourcePath.toAbsolutePath().toString())));
}
}
RuntimeUpdatesProcessor.INSTANCE = setupRuntimeCompilation(context, (Path) params.get(APP_ROOT), (DevModeType) params.get(DevModeType.class.getName()));
if (RuntimeUpdatesProcessor.INSTANCE != null) {
RuntimeUpdatesProcessor.INSTANCE.checkForFileChange();
RuntimeUpdatesProcessor.INSTANCE.checkForChangedClasses(true);
}
firstStart(deploymentClassLoader, codeGens);
// doStart(false, Collections.emptySet());
if (deploymentProblem != null || RuntimeUpdatesProcessor.INSTANCE.getCompileProblem() != null) {
if (context.isAbortOnFailedStart()) {
throw new RuntimeException(deploymentProblem == null ? RuntimeUpdatesProcessor.INSTANCE.getCompileProblem() : deploymentProblem);
}
}
shutdownThread = new Thread(new Runnable() {
@Override
public void run() {
shutdownLatch.countDown();
synchronized (DevModeMain.class) {
if (runner != null) {
try {
close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}, "Quarkus Shutdown Thread");
Runtime.getRuntime().addShutdownHook(shutdownThread);
} catch (Exception e) {
close();
throw new RuntimeException(e);
}
}
use of io.quarkus.deployment.codegen.CodeGenData in project quarkus by quarkusio.
the class IsolatedDevModeMain method startCodeGenWatcher.
private void startCodeGenWatcher(QuarkusClassLoader classLoader, List<CodeGenData> codeGens, Map<String, String> propertyMap) {
Collection<FSWatchUtil.Watcher> watchers = new ArrayList<>();
Properties properties = new Properties();
properties.putAll(propertyMap);
for (CodeGenData codeGen : codeGens) {
watchers.add(new FSWatchUtil.Watcher(codeGen.sourceDir, codeGen.provider.inputExtension(), modifiedPaths -> {
try {
CodeGenerator.trigger(classLoader, codeGen, curatedApplication.getApplicationModel(), properties, LaunchMode.DEVELOPMENT, false);
} catch (Exception any) {
log.warn("Code generation failed", any);
}
}));
}
fsWatchUtil.observe(watchers, 500);
}
use of io.quarkus.deployment.codegen.CodeGenData in project quarkus by quarkusio.
the class CodeGenerator method initAndRun.
// used by Gradle and Maven
public static void initAndRun(ClassLoader classLoader, PathCollection sourceParentDirs, Path generatedSourcesDir, Path buildDir, Consumer<Path> sourceRegistrar, ApplicationModel appModel, Properties properties, String launchMode, boolean test) throws CodeGenException {
List<CodeGenData> generators = init(classLoader, sourceParentDirs, generatedSourcesDir, buildDir, sourceRegistrar);
for (CodeGenData generator : generators) {
generator.setRedirectIO(true);
trigger(classLoader, generator, appModel, properties, LaunchMode.valueOf(launchMode), test);
}
}
Aggregations