Skip to content

Commit

Permalink
migrated all recent features and bugfixes from javafx-maven-plugin to…
Browse files Browse the repository at this point in the history
… this gradle-plugin

(except classpathExcludes)
  • Loading branch information
FibreFoX committed Mar 10, 2016
1 parent 7a40340 commit 7a354e2
Show file tree
Hide file tree
Showing 6 changed files with 414 additions and 51 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies {

group = 'de.dynamicfiles.projects.gradle.plugins'
archivesBaseName = 'javafx-gradle-plugin'
version = '8.3.1-SNAPSHOT'
version = '8.4.0-SNAPSHOT'

ext.isReleaseVersion = !version.endsWith("SNAPSHOT")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
*/
package de.dynamicfiles.projects.gradle.plugins.javafx;

import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxGenerateKeystoreTask;
import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxNativeTask;
import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxJarTask;
import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxRunTask;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand All @@ -43,6 +45,8 @@ public void apply(Project project) {
// gradle is lame, so replace existing tasks with MY NAMES ! *battle-cry*
JfxJarTask jarTask = project.getTasks().replace("jfxJar", JfxJarTask.class);
JfxNativeTask nativeTask = project.getTasks().replace("jfxNative", JfxNativeTask.class);
JfxGenerateKeystoreTask generateKeystoreTask = project.getTasks().replace("jfxGenerateKeyStore", JfxGenerateKeystoreTask.class);
JfxRunTask runTask = project.getTasks().replace("jfxRun", JfxRunTask.class);

String taskGroupName = "JavaFX";

Expand All @@ -53,6 +57,12 @@ public void apply(Project project) {
nativeTask.setGroup(taskGroupName);
nativeTask.setDescription("Create native JavaFX-bundle");

generateKeystoreTask.setGroup(taskGroupName);
generateKeystoreTask.setDescription("Create a Java keystore");

runTask.setGroup(taskGroupName);
runTask.setDescription("Start generated JavaFX-jar");

// create jfx-jar only after jar-file was created (is this the right way?!?)
if( project.getTasks().findByName("jar") == null ){
throw new GradleException("Could not find jar-task. Please make sure you are applying the 'java'-plugin.");
Expand All @@ -63,6 +73,9 @@ public void apply(Project project) {
// (in maven I had to implement a lifecycle for this ... mehhh)
nativeTask.dependsOn(jarTask);

// to run our jfx-jar, we have to create it first ;)
runTask.dependsOn(jarTask);

// extend project-model to get our settings/configuration via nice configuration
project.getExtensions().create("jfx", JavaFXGradlePluginExtension.class);
}
Expand All @@ -84,7 +97,7 @@ private void addJavaFXAntJARToGradleBuildpath(Project project) {

ClassLoader buildscriptClassloader = project.getBuildscript().getClassLoader();
// when running tests, this should be handled ;)
if("org.gradle.internal.classloader.CachingClassLoader".equals(buildscriptClassloader.getClass().getName())){
if( "org.gradle.internal.classloader.CachingClassLoader".equals(buildscriptClassloader.getClass().getName()) ){
return;
}
URLClassLoader sysloader = (URLClassLoader) buildscriptClassloader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class JavaFXGradlePluginExtension {
private boolean skipNativeLauncherWorkaround167 = false;
private List<Map<String, Object>> secondaryLaunchers = null;
private List<Map<String, Object>> fileAssociations = null;

private boolean skipJNLPRessourcePathWorkaround182 = false;
private String keyStore = "src/main/deploy/keystore.jks";
private String keyStoreAlias = "myalias";
Expand All @@ -69,6 +69,15 @@ public class JavaFXGradlePluginExtension {
private String keyStoreType = "jks";
private boolean skipSigningJarFilesJNLP185 = false;
private boolean skipSizeRecalculationForJNLP185 = false;
private boolean noBlobSigning = false;

// GenerateKeyStoreMojo
private boolean overwriteKeyStore = false;
private String certDomain = null;
private String certOrgUnit = null;
private String certOrg = null;
private String certState = null;
private String certCountry = null;

/*
generated methods below
Expand Down Expand Up @@ -368,5 +377,61 @@ public boolean isSkipSizeRecalculationForJNLP185() {
public void setSkipSizeRecalculationForJNLP185(boolean skipSizeRecalculationForJNLP185) {
this.skipSizeRecalculationForJNLP185 = skipSizeRecalculationForJNLP185;
}


public boolean isNoBlobSigning() {
return noBlobSigning;
}

public void setNoBlobSigning(boolean noBlobSigning) {
this.noBlobSigning = noBlobSigning;
}

public boolean isOverwriteKeyStore() {
return overwriteKeyStore;
}

public void setOverwriteKeyStore(boolean overwriteKeyStore) {
this.overwriteKeyStore = overwriteKeyStore;
}

public String getCertDomain() {
return certDomain;
}

public void setCertDomain(String certDomain) {
this.certDomain = certDomain;
}

public String getCertOrgUnit() {
return certOrgUnit;
}

public void setCertOrgUnit(String certOrgUnit) {
this.certOrgUnit = certOrgUnit;
}

public String getCertOrg() {
return certOrg;
}

public void setCertOrg(String certOrg) {
this.certOrg = certOrg;
}

public String getCertState() {
return certState;
}

public void setCertState(String certState) {
this.certState = certState;
}

public String getCertCountry() {
return certCountry;
}

public void setCertCountry(String certCountry) {
this.certCountry = certCountry;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* Copyright 2016 Danny Althoff
*
* 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 de.dynamicfiles.projects.gradle.plugins.javafx.tasks;

import com.oracle.tools.packager.Log;
import de.dynamicfiles.projects.gradle.plugins.javafx.JavaFXGradlePluginExtension;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;

/**
*
* @author Danny Althoff
*/
public class JfxGenerateKeystoreTask extends JfxTask {

@FunctionalInterface
private interface RequiredFieldAlternativeCallback {

String getValue();
}

@TaskAction
public void jfxgeneratekeystore() {
Project project = this.getProject();
// get our configuration
JavaFXGradlePluginExtension ext = project.getExtensions().getByType(JavaFXGradlePluginExtension.class);
addDeployDirToSystemClassloader(project, ext.getDeployDir());

// set logger-level
Log.setLogger(new Log.Logger(ext.isVerbose()));

File keyStore = new File(project.getProjectDir(), ext.getKeyStore());

if( keyStore.exists() ){
if( ext.isOverwriteKeyStore() ){
if( !keyStore.delete() ){
throw new GradleException("Unable to delete existing keystore at: " + keyStore);
}
} else {
throw new GradleException("Keystore already exists (set 'overwriteKeyStore' to force) at: " + keyStore);
}
}

checkKeystoreRequiredParameter(ext.getKeyStoreAlias(), "keyStoreAlias");
checkKeystoreRequiredParameter(ext.getKeyStorePassword(), "keyStorePassword");

if( ext.getKeyPassword() == null ){
ext.setKeyPassword(ext.getKeyStorePassword());
}

List<String> distinguishedNameParts = new ArrayList<>();

checkAndAddRequiredField(distinguishedNameParts, "certDomain", ext.getCertDomain(), "cn");
checkAndAddRequiredField(distinguishedNameParts, "certOrgUnit", ext.getCertOrgUnit(), "ou", () -> {
return "none";
});
checkAndAddRequiredField(distinguishedNameParts, "certOrg", ext.getCertOrg(), "o");
checkAndAddRequiredField(distinguishedNameParts, "certState", ext.getCertState(), "st");
checkAndAddRequiredField(distinguishedNameParts, "certCountry", ext.getCertCountry(), "c");

generateKeyStore(
keyStore, ext.getKeyStoreAlias(), ext.getKeyStorePassword(), ext.getKeyPassword(), String.join(", ", distinguishedNameParts), ext.isVerbose()
);
}

protected void generateKeyStore(File keyStore, String keyStoreAlias, String keyStorePassword, String keyPassword, String distinguishedName, boolean verbose) {
Project project = this.getProject();
project.getLogger().info("Generating keystore in: " + keyStore);

try{
// generated folder if it does not exist
Files.createDirectories(keyStore.getParentFile().toPath());

List<String> command = new ArrayList<>();

command.add("keytool");
command.add("-genkeypair");
command.add("-keystore");
command.add(keyStore.getPath());
command.add("-alias");
command.add(keyStoreAlias);
command.add("-storepass");
command.add(keyStorePassword);
command.add("-keypass");
command.add(keyPassword);
command.add("-dname");
command.add(distinguishedName);
command.add("-sigalg");
command.add("SHA256withRSA");
command.add("-validity");
command.add("100");
command.add("-keyalg");
command.add("RSA");
command.add("-keysize");
command.add("2048");
if( verbose ){
command.add("-v");
}

ProcessBuilder pb = new ProcessBuilder().inheritIO().command(command);
Process p = pb.start();
p.waitFor();
} catch(IOException | InterruptedException ex){
throw new GradleException("There was an exception while generating keystore.", ex);
}
}

private void checkKeystoreRequiredParameter(String value, String valueName) {
if( value == null || value.trim().isEmpty() ){
throw new GradleException("The property '" + valueName + "' is required to generate a new KeyStore.");
}
}

private void checkAndAddRequiredField(List<String> distinguishedNameParts, String propertyName, String value, String fieldName) {
checkAndAddRequiredField(distinguishedNameParts, propertyName, value, fieldName, null);
}

private void checkAndAddRequiredField(List<String> distinguishedNameParts, String propertyName, String value, String fieldName, RequiredFieldAlternativeCallback alternative) {
if( value != null && !value.trim().isEmpty() ){
distinguishedNameParts.add(fieldName + "=" + value);
} else if( alternative == null || alternative.getValue() == null || alternative.getValue().trim().isEmpty() ){
throw new GradleException("The property '" + propertyName + "' must be provided to generate a new certificate.");
} else {
distinguishedNameParts.add(fieldName + "=" + alternative.getValue());
}
}

}
Loading

0 comments on commit 7a354e2

Please sign in to comment.