Author: rmannibucau Date: Wed Oct 19 09:37:35 2016 New Revision: 1765563 URL: http://svn.apache.org/viewvc?rev=1765563&view=rev Log: bootstraping gradle plugin
Added: openwebbeans/microwave/trunk/microwave-gradle-plugin/ openwebbeans/microwave/trunk/microwave-gradle-plugin/pom.xml openwebbeans/microwave/trunk/microwave-gradle-plugin/src/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveExtension.java openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowavePlugin.java openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveTask.java openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/classloader/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/classloader/FilterGradleClassLoader.java openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/resources/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/resources/META-INF/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties openwebbeans/microwave/trunk/microwave-gradle-plugin/src/test/ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/test/java/ Modified: openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/microwave/maven/MicrowaveRunMojo.java openwebbeans/microwave/trunk/pom.xml Added: openwebbeans/microwave/trunk/microwave-gradle-plugin/pom.xml URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-gradle-plugin/pom.xml?rev=1765563&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-gradle-plugin/pom.xml (added) +++ openwebbeans/microwave/trunk/microwave-gradle-plugin/pom.xml Wed Oct 19 09:37:35 2016 @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>microwave</artifactId> + <groupId>org.apache.microwave</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>microwave-gradle-plugin</artifactId> + <name>Microwave :: Gradle</name> + + <dependencies> + <dependency> + <groupId>org.gradle</groupId> + <artifactId>gradle-core</artifactId> + <version>3.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-all</artifactId> + <version>2.4.3</version> + <scope>provided</scope> + </dependency> + + <!-- you surely don't want to do that, check the code ;) --> + </dependencies> + + <repositories> + <repository> + <id>gradle-libs-releases-local</id> + <url>http://repo.gradle.org/gradle/libs-releases-local/</url> + </repository> + </repositories> +</project> Added: openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveExtension.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveExtension.java?rev=1765563&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveExtension.java (added) +++ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveExtension.java Wed Oct 19 09:37:35 2016 @@ -0,0 +1,334 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.microwave.gradle; + +import java.io.File; +import java.util.Collection; +import java.util.LinkedList; +import java.util.Map; + +public class MicrowaveExtension { + private boolean skipMavenCentral; + private String context; + private File webapp; + + private int httpPort; + private int httpsPort; + private int stopPort; + private String host; + protected String dir; + private File serverXml; + private boolean keepServerXmlAsThis; + private Map<String, String> properties; + private boolean quickSession; + private boolean skipHttp; + private boolean ssl; + private String keystoreFile; + private String keystorePass; + private String keystoreType; + private String clientAuth; + private String keyAlias; + private String sslProtocol; + private String webXml; + private String loginConfig; + private Collection<String> securityConstraints = new LinkedList<>(); + private Map<String, String> users; + private Map<String, String> roles; + private boolean http2; + private String tempDir; + private boolean webResourceCached; + private String conf; + private boolean deleteBaseOnStartup; + private String jaxrsMapping; + private boolean cdiConversation; + private boolean skip; + private boolean skipJaspicProperty; + + public String getContext() { + return context; + } + + public void setContext(final String context) { + this.context = context; + } + + public File getWebapp() { + return webapp; + } + + public void setWebapp(final File webapp) { + this.webapp = webapp; + } + + public boolean isSkipMavenCentral() { + return skipMavenCentral; + } + + public void setSkipMavenCentral(final boolean skipMavenCentral) { + this.skipMavenCentral = skipMavenCentral; + } + + public int getHttpPort() { + return httpPort; + } + + public void setHttpPort(final int httpPort) { + this.httpPort = httpPort; + } + + public int getHttpsPort() { + return httpsPort; + } + + public void setHttpsPort(final int httpsPort) { + this.httpsPort = httpsPort; + } + + public int getStopPort() { + return stopPort; + } + + public void setStopPort(final int stopPort) { + this.stopPort = stopPort; + } + + public String getHost() { + return host; + } + + public void setHost(final String host) { + this.host = host; + } + + public String getDir() { + return dir; + } + + public void setDir(final String dir) { + this.dir = dir; + } + + public File getServerXml() { + return serverXml; + } + + public void setServerXml(final File serverXml) { + this.serverXml = serverXml; + } + + public boolean isKeepServerXmlAsThis() { + return keepServerXmlAsThis; + } + + public void setKeepServerXmlAsThis(final boolean keepServerXmlAsThis) { + this.keepServerXmlAsThis = keepServerXmlAsThis; + } + + public Map<String, String> getProperties() { + return properties; + } + + public void setProperties(final Map<String, String> properties) { + this.properties = properties; + } + + public boolean isQuickSession() { + return quickSession; + } + + public void setQuickSession(final boolean quickSession) { + this.quickSession = quickSession; + } + + public boolean isSkipHttp() { + return skipHttp; + } + + public void setSkipHttp(final boolean skipHttp) { + this.skipHttp = skipHttp; + } + + public boolean isSsl() { + return ssl; + } + + public void setSsl(final boolean ssl) { + this.ssl = ssl; + } + + public String getKeystoreFile() { + return keystoreFile; + } + + public void setKeystoreFile(final String keystoreFile) { + this.keystoreFile = keystoreFile; + } + + public String getKeystorePass() { + return keystorePass; + } + + public void setKeystorePass(final String keystorePass) { + this.keystorePass = keystorePass; + } + + public String getKeystoreType() { + return keystoreType; + } + + public void setKeystoreType(final String keystoreType) { + this.keystoreType = keystoreType; + } + + public String getClientAuth() { + return clientAuth; + } + + public void setClientAuth(final String clientAuth) { + this.clientAuth = clientAuth; + } + + public String getKeyAlias() { + return keyAlias; + } + + public void setKeyAlias(final String keyAlias) { + this.keyAlias = keyAlias; + } + + public String getSslProtocol() { + return sslProtocol; + } + + public void setSslProtocol(final String sslProtocol) { + this.sslProtocol = sslProtocol; + } + + public String getWebXml() { + return webXml; + } + + public void setWebXml(final String webXml) { + this.webXml = webXml; + } + + public String getLoginConfig() { + return loginConfig; + } + + public void setLoginConfig(final String loginConfig) { + this.loginConfig = loginConfig; + } + + public Collection<String> getSecurityConstraints() { + return securityConstraints; + } + + public void setSecurityConstraints(final Collection<String> securityConstraints) { + this.securityConstraints = securityConstraints; + } + + public Map<String, String> getUsers() { + return users; + } + + public void setUsers(final Map<String, String> users) { + this.users = users; + } + + public Map<String, String> getRoles() { + return roles; + } + + public void setRoles(final Map<String, String> roles) { + this.roles = roles; + } + + public boolean isHttp2() { + return http2; + } + + public void setHttp2(final boolean http2) { + this.http2 = http2; + } + + public String getTempDir() { + return tempDir; + } + + public void setTempDir(final String tempDir) { + this.tempDir = tempDir; + } + + public boolean isWebResourceCached() { + return webResourceCached; + } + + public void setWebResourceCached(final boolean webResourceCached) { + this.webResourceCached = webResourceCached; + } + + public String getConf() { + return conf; + } + + public void setConf(final String conf) { + this.conf = conf; + } + + public boolean isDeleteBaseOnStartup() { + return deleteBaseOnStartup; + } + + public void setDeleteBaseOnStartup(final boolean deleteBaseOnStartup) { + this.deleteBaseOnStartup = deleteBaseOnStartup; + } + + public String getJaxrsMapping() { + return jaxrsMapping; + } + + public void setJaxrsMapping(final String jaxrsMapping) { + this.jaxrsMapping = jaxrsMapping; + } + + public boolean isCdiConversation() { + return cdiConversation; + } + + public void setCdiConversation(final boolean cdiConversation) { + this.cdiConversation = cdiConversation; + } + + public boolean isSkip() { + return skip; + } + + public void setSkip(final boolean skip) { + this.skip = skip; + } + + public boolean isSkipJaspicProperty() { + return skipJaspicProperty; + } + + public void setSkipJaspicProperty(final boolean skipJaspicProperty) { + this.skipJaspicProperty = skipJaspicProperty; + } +} Added: openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowavePlugin.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowavePlugin.java?rev=1765563&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowavePlugin.java (added) +++ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowavePlugin.java Wed Oct 19 09:37:35 2016 @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.microwave.gradle; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.DependencySet; +import org.gradle.api.artifacts.dsl.DependencyHandler; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Properties; + +public class MicrowavePlugin implements Plugin<Project> { + public static final String NAME = "microwave"; + + @Override + public void apply(final Project project) { + project.getExtensions().create(NAME, MicrowaveExtension.class); + + project.afterEvaluate(actionProject -> { + final MicrowaveExtension extension = MicrowaveExtension.class.cast(actionProject.getExtensions().findByName(NAME)); + if (extension != null && extension.isSkipMavenCentral()) { + return; + } + actionProject.getRepositories().mavenCentral(); + }); + + final Configuration configuration = project.getConfigurations().getByName(NAME); + configuration.getIncoming().beforeResolve(resolvableDependencies -> { + String version; + try { + try (final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/maven/org.apache.microwave/microwave-core/pom.properties")) { + final Properties p = new Properties(); + p.load(is); + version = p.getProperty("version"); + } + } catch (final IOException e) { + throw new IllegalStateException(e); + } + + final DependencyHandler dependencyHandler = project.getDependencies(); + final DependencySet dependencies = configuration.getDependencies(); + dependencies.add(dependencyHandler.create("org.apache.microwave:microwave:" + version)); + }); + + project.task(new HashMap<String, Object>() {{ + put("type", MicrowaveTask.class); + put("group", "Embedded Application Server"); + put("description", "Starts a microwave!"); + }}, NAME); + } +} Added: openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveTask.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveTask.java?rev=1765563&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveTask.java (added) +++ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/MicrowaveTask.java Wed Oct 19 09:37:35 2016 @@ -0,0 +1,397 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.microwave.gradle; + +import org.apache.microwave.gradle.classloader.FilterGradleClassLoader; +import org.gradle.api.DefaultTask; +import org.gradle.api.GradleException; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.Optional; +import org.gradle.api.tasks.TaskAction; + +import java.io.File; +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Scanner; +import java.util.concurrent.atomic.AtomicBoolean; + +import static java.util.Arrays.asList; +import static java.util.Optional.ofNullable; + +public class MicrowaveTask extends DefaultTask { + private Configuration classpath; + + @Input + @Optional + private int httpPort; + + @Input + @Optional + private int httpsPort; + + @Input + @Optional + private int stopPort; + + @Input + @Optional + private String host; + + @Input + @Optional + protected String dir; + + @Input + @Optional + private File serverXml; + + @Input + @Optional + private boolean keepServerXmlAsThis; + + @Input + @Optional + private Map<String, String> properties; + + @Input + @Optional + private boolean quickSession; + + @Input + @Optional + private boolean skipHttp; + + @Input + @Optional + private boolean ssl; + + @Input + @Optional + private String keystoreFile; + + @Input + @Optional + private String keystorePass; + + @Input + @Optional + private String keystoreType; + + @Input + @Optional + private String clientAuth; + + @Input + @Optional + private String keyAlias; + + @Input + @Optional + private String sslProtocol; + + @Input + @Optional + private String webXml; + + @Input + @Optional + private String loginConfig; + + @Input + @Optional + private Collection<String> securityConstraints = new LinkedList<>(); + + @Input + @Optional + private Map<String, String> users; + + @Input + @Optional + private Map<String, String> roles; + + @Input + @Optional + private boolean http2; + + @Input + @Optional + private String tempDir; + + @Input + @Optional + private boolean webResourceCached; + + @Input + @Optional + private String conf; + + @Input + @Optional + private boolean deleteBaseOnStartup; + + @Input + @Optional + private String jaxrsMapping; + + @Input + @Optional + private boolean cdiConversation; + + @Input + @Optional + private boolean skip; + + @Input + @Optional + private boolean skipJaspicProperty; + + @Input + @Optional + private List<File> modules; + + @Input + @Optional + private Collection<String> applicationScopes = new HashSet<>(asList("compile", "runtime")); + + @Input + @Optional + private Collection<String> classloaderFilteredPackages; + + @Input + @Optional + private String context; + + @Input + @Optional + private File webapp; + + @TaskAction + public void bake() { + fixConfig(); + + final Thread thread = Thread.currentThread(); + final ClassLoader tccl = thread.getContextClassLoader(); + thread.setContextClassLoader(createLoader(tccl)); + try { + doRun(); + } finally { + thread.setContextClassLoader(tccl); + } + } + + private void doRun() { + final Thread thread = Thread.currentThread(); + final ClassLoader loader = thread.getContextClassLoader(); + + final AtomicBoolean running = new AtomicBoolean(false); + Thread hook = null; + AutoCloseable container; + try { + final Class<?> containerClass = loader.loadClass("org.apache.microwave.Microwave"); + final Class<?> configClass = loader.loadClass("org.apache.microwave.Microwave$Builder"); + + final Object config = getConfig(configClass); + + running.set(true); + container = AutoCloseable.class.cast(containerClass.getConstructor(configClass).newInstance(config)); + + final AutoCloseable finalContainer = container; + hook = new Thread() { + @Override + public void run() { + if (running.compareAndSet(true, false)) { + final Thread thread = Thread.currentThread(); + final ClassLoader old = thread.getContextClassLoader(); + thread.setContextClassLoader(loader); + try { + finalContainer.close(); + } catch (final NoClassDefFoundError noClassDefFoundError) { + // debug cause it is too late to shutdown properly so don't pollute logs + getLogger().debug("can't stop Microwave", noClassDefFoundError); + } catch (final Exception e) { + getLogger().error("can't stop Microwave", e); + } finally { + thread.setContextClassLoader(old); + } + } + } + }; + hook.setName("Microwave-Embedded-ShutdownHook"); + Runtime.getRuntime().addShutdownHook(hook); + + containerClass.getMethod("start").invoke(container); + final String fixedContext = ofNullable(context).orElse(""); + if (webapp == null) { + configClass.getMethod("deployClasspath", String.class).invoke(container, fixedContext); + } else { + configClass.getMethod("deployWebapp", String.class, File.class).invoke(container, fixedContext, webapp); + } + + getLogger().info("Microwave started on " + configClass.getMethod("host").invoke(config) + ":" + configClass.getMethod("httpPort").invoke(config)); + } catch (final Exception e) { + ofNullable(hook).ifPresent(h -> { + try { + h.run(); + } finally { + Runtime.getRuntime().removeShutdownHook(h); + } + }); + throw new GradleException(e.getMessage(), e); + } + + try { + String line; + final Scanner scanner = new Scanner(System.in); + while ((line = scanner.nextLine()) != null) { + final String cmd = line.trim().toLowerCase(Locale.ENGLISH); + switch (cmd) { + case "exit": + case "quit": + running.set(false); + try { + hook.run(); + } finally { + Runtime.getRuntime().removeShutdownHook(hook); + } + return; + default: + getLogger().warn("Unknown: '" + cmd + "', use 'exit' or 'quit'"); + } + } + } catch (final Exception e) { + Thread.interrupted(); + } finally { + thread.setContextClassLoader(loader); + } + } + + private Object getConfig(final Class<?> configClass) throws Exception { + final Object config = configClass.newInstance(); + for (final Field field : MicrowaveExtension.class.getDeclaredFields()) { + try { + final Field configField = configClass.getDeclaredField(field.getName()); + if (!configField.getType().equals(field.getType())) { + getLogger().debug("Skipping " + field.getName() + " since type doesnt match"); + continue; + } + if (!field.isAccessible()) { + field.setAccessible(true); + } + + final Object value = field.get(this); + if (value != null) { + if (!configField.isAccessible()) { + configField.setAccessible(true); + } + configField.set(config, value); + getLogger().debug("using " + field.getName() + " = " + value); + } + } catch (final NoSuchFieldException nsfe) { + // ignored + } catch (final Exception e) { + getLogger().warn("can't initialize attribute " + field.getName()); + } + } + // TODO: securityConstraints, loginConfig + return config; + } + + private ClassLoader createLoader(final ClassLoader parent) { + final Collection<URL> urls = new LinkedHashSet<>(64); + + addFiles(modules, urls); + + for (final Configuration cc : getProject().getConfigurations()) { + if (applicationScopes.contains(cc.getName())) { + addFiles(cc.getFiles(), urls); + } + } + + addFiles(classpath.getFiles(), urls); + + // use JVM loader to avoid the noise of gradle and its plugins + return new URLClassLoader(urls.toArray(new URL[urls.size()]), new FilterGradleClassLoader(parent, classloaderFilteredPackages)); + } + + private void addFiles(final Collection<File> files, final Collection<URL> urls) { + if (files == null || files.isEmpty()) { + return; + } + for (final File f : files) { + final String name = f.getName(); + if (name.startsWith("slf4j-api") || name.startsWith("slf4j-jdk14")) { + continue; // use gradle + } + try { + urls.add(f.toURI().toURL()); + } catch (final MalformedURLException e) { + throw new IllegalArgumentException(e); + } + } + } + + private void fixConfig() { + final Project project = getProject(); + + // defaults + if (classpath == null) { + classpath.add(project.getConfigurations().getByName(MicrowavePlugin.NAME).fileCollection()); + } + + if (dir == null) { + dir = new File(project.getBuildDir(), "microwave/run").getAbsolutePath(); + } + + // extension override + final MicrowaveExtension extension = MicrowaveExtension.class.cast(project.getExtensions().findByName(MicrowavePlugin.NAME)); + if (extension != null) { + for (final Field f : MicrowaveTask.class.getDeclaredFields()) { + if (f.isAnnotationPresent(Input.class)) { + try { + final Field extField = MicrowaveExtension.class.getDeclaredField(f.getName()); + if (!extField.isAccessible()) { + extField.setAccessible(true); + } + final Object val = extField.get(extension); + if (val != null) { + if (!f.isAccessible()) { + f.setAccessible(true); + } + f.set(this, val); + } + } catch (final IllegalAccessException | NoSuchFieldException e) { + getLogger().warn("No field " + f.getName() + " in " + extension, e); + } + } + } + } + } + +} Added: openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/classloader/FilterGradleClassLoader.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/classloader/FilterGradleClassLoader.java?rev=1765563&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/classloader/FilterGradleClassLoader.java (added) +++ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/java/org/apache/microwave/gradle/classloader/FilterGradleClassLoader.java Wed Oct 19 09:37:35 2016 @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.microwave.gradle.classloader; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collection; +import java.util.Enumeration; + +import static java.util.Collections.emptyEnumeration; + +public class FilterGradleClassLoader extends ClassLoader { + private final ClassLoader delegate; + private final Collection<String> filtered; + + public FilterGradleClassLoader(final ClassLoader gradle, final Collection<String> filtered) { + super(gradle.getParent()); + this.delegate = gradle; + this.filtered = filtered; + } + + @Override + public Class<?> loadClass(final String name) throws ClassNotFoundException { + checkClass(name); + return delegate.loadClass(name); + } + + @Override + public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException { + return loadClass(name); + } + + @Override + public URL getResource(final String name) { + if (!checkResource(name)) { + return null; + } + return delegate.getResource(name); + } + + @Override + public Enumeration<URL> getResources(final String name) throws IOException { + final Enumeration<URL> resources = delegate.getResources(name); + if (!checkResource(name)) { + return emptyEnumeration(); + } + return resources; + } + + @Override + public InputStream getResourceAsStream(final String name) { + if (!checkResource(name)) { + return null; + } + return delegate.getResourceAsStream(name); + } + + private void checkClass(final String name) throws ClassNotFoundException { // let slf4j+gradle go to reuse it + if (name != null && ( + name.startsWith("aQute") || + name.startsWith("bsh") || + name.startsWith("com.amazon") || + name.startsWith("com.beust") || + name.startsWith("com.esot") || + name.startsWith("com.google") || + name.startsWith("com.jackson") || + name.startsWith("com.jcraft") || + name.startsWith("com.tonixsystems") || + name.startsWith("javax.el") || + name.startsWith("javax.inject") || + name.startsWith("javax.servlet") || + name.startsWith("jcifs.") || + name.startsWith("junit.") || + name.startsWith("groovy") || + name.startsWith("mozilla.") || + name.startsWith("net.jcip.") || + name.startsWith("net.ruby") || + name.startsWith("org.apache.") || + name.startsWith("org.bouncycastle.") || + name.startsWith("org.codehaus.") || + name.startsWith("org.cyber") || + name.startsWith("org.dom4j.") || + name.startsWith("org.eclipse.") || + name.startsWith("org.fusesource.") || + name.startsWith("org.hamcrest.") || + name.startsWith("org.jaxen.") || + name.startsWith("org.mortbay.") || + name.startsWith("org.mozilla.") || + name.startsWith("org.objectweb.") || + name.startsWith("org.objenesis.") || + name.startsWith("org.osgi.") || + name.startsWith("org.simpleframework.") || + name.startsWith("org.sonar.") || + name.startsWith("org.sonatype.") || + name.startsWith("org.testng.") || + name.startsWith("org.yaml.") || + isForbiddenGradleClass(name) || + isFiltered(name) + )) { + throw new ClassNotFoundException(); + } + } + + private boolean isFiltered(final String name) { + if (filtered == null || name == null) { + return false; + } + for (final String pck : filtered) { + if (name.startsWith(pck)) { + return true; + } + } + return false; + } + + private boolean isForbiddenGradleClass(final String name) { // we need logging classes but we don't want to scan gradle + return name.startsWith("org.gradle.initialization") || name.startsWith("org.gradle.launcher") + || name.startsWith("org.gradle.execution") || name.startsWith("org.gradle.internal") + || name.startsWith("org.gradle.tooling") || name.startsWith("org.gradle.api.internal.tasks") + || name.startsWith("org.gradle.util") || name.startsWith("org.gradle.wrapper"); + } + + private boolean checkResource(final String name) { + return name != null && !name.startsWith("META-INF/services/com.fasterxml"); + } +} + Added: openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties?rev=1765563&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties (added) +++ openwebbeans/microwave/trunk/microwave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties Wed Oct 19 09:37:35 2016 @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# +implementation-class=org.apache.microwave.gradle.MicrowavePlugin Modified: openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/microwave/maven/MicrowaveRunMojo.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/microwave/maven/MicrowaveRunMojo.java?rev=1765563&r1=1765562&r2=1765563&view=diff ============================================================================== --- openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/microwave/maven/MicrowaveRunMojo.java (original) +++ openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/microwave/maven/MicrowaveRunMojo.java Wed Oct 19 09:37:35 2016 @@ -39,11 +39,14 @@ import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Scanner; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.toList; import static org.apache.maven.plugins.annotations.ResolutionScope.RUNTIME_PLUS_SYSTEM; @Mojo(name = "run", requiresDependencyResolution = RUNTIME_PLUS_SYSTEM) @@ -139,17 +142,26 @@ public class MicrowaveRunMojo extends Ab private boolean skip; @Parameter(name = "microwave.skip-jaspic-setup", defaultValue = "false") - public boolean skipJaspicProperty; + private boolean skipJaspicProperty; @Parameter - protected List<String> jsCustomizers; + private List<String> jsCustomizers; @Parameter private List<String> applicationScopes; + @Parameter + private List<File> modules; + @Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject project; + @Parameter(name = "microwave.context", defaultValue = "") + private String context; + + @Parameter(name = "microwave.webapp") + private File webapp; + @Override public void execute() throws MojoExecutionException, MojoFailureException { if (skip) { @@ -167,7 +179,14 @@ public class MicrowaveRunMojo extends Ab protected void beforeStart() { scriptCustomization(jsCustomizers, "js", base.getAbsolutePath()); } - }.bake()) { + }) { + microwave.start(); + final String fixedContext = ofNullable(context).orElse(""); + if (webapp == null) { + microwave.deployClasspath(fixedContext); + } else { + microwave.deployWebapp(fixedContext, webapp); + } new Scanner(System.in).next(); } } finally { @@ -196,18 +215,24 @@ public class MicrowaveRunMojo extends Ab private ClassLoader createClassLoader(final ClassLoader parent) { final List<URL> urls = new ArrayList<>(); - for (final Artifact artifact : project.getArtifacts()) { - final String scope = artifact.getScope(); - if ((applicationScopes == null && !(Artifact.SCOPE_COMPILE.equals(scope) || Artifact.SCOPE_RUNTIME.equals(scope))) - || (applicationScopes != null && !applicationScopes.contains(scope))) { - continue; - } + urls.addAll(project.getArtifacts().stream() + .filter(a -> !((applicationScopes == null && !(Artifact.SCOPE_COMPILE.equals(a.getScope()) || Artifact.SCOPE_RUNTIME.equals(a.getScope()))) + || (applicationScopes != null && !applicationScopes.contains(a.getScope())))) + .map(f -> { + try { + return f.getFile().toURI().toURL(); + } catch (final MalformedURLException e) { + throw new IllegalArgumentException(e); + } + }) + .collect(toList())); + urls.addAll(ofNullable(modules).orElse(Collections.emptyList()).stream().map(f -> { try { - urls.add(artifact.getFile().toURI().toURL()); + return f.toURI().toURL(); } catch (final MalformedURLException e) { - getLog().warn("can't use artifact " + artifact.toString()); + throw new IllegalArgumentException(e); } - } + }).collect(toList())); return urls.isEmpty() ? parent : new URLClassLoader(urls.toArray(new URL[urls.size()]), parent) { @Override public boolean equals(final Object obj) { Modified: openwebbeans/microwave/trunk/pom.xml URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/pom.xml?rev=1765563&r1=1765562&r2=1765563&view=diff ============================================================================== --- openwebbeans/microwave/trunk/pom.xml (original) +++ openwebbeans/microwave/trunk/pom.xml Wed Oct 19 09:37:35 2016 @@ -40,6 +40,7 @@ <modules> <module>microwave-core</module> <module>microwave-maven-plugin</module> + <module>microwave-gradle-plugin</module> </modules> <build>