You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ta...@apache.org on 2016/07/04 15:22:47 UTC

svn commit: r1751309 - in /ofbiz/trunk: ./ framework/common/src/org/ofbiz/common/email/ framework/start/src/org/ofbiz/base/start/ gradle/ gradle/wrapper/

Author: taher
Date: Mon Jul  4 15:22:47 2016
New Revision: 1751309

URL: http://svn.apache.org/viewvc?rev=1751309&view=rev
Log:
First commit in replacing Apache ant with Gradle - OFBIZ-7534

This commit represents a pivotal change in the history of the
project in which the build system is being replaced from Apache
Ant to Gradle of which the discussion mail thread link is below.

Thanks to everyone who helped with testing and feedback

This commit delivers the following:

- add the gradle wrapper directory in gradle/* which holds
  all items necessary for gradle to run
- add the build.gradle master script
- add the settings.gradle script which declares all the subprojects
- add documentation for how to use everything in a new file called
  README.md (written in markdown)

The new script is capable of the functionality that used to exist
in Ant with some additional features including automation of eclipse
files generation and many other functions.

To complete this new feature, we need to apply the following _after_
this commit:
- change the buildbot to utilize gradle instead of ant
- delete all ant & maven scripts
- replace all local jars with remote ones from jcenter

Reference thread: http://ofbiz.markmail.org/message/vstt3wxuubmjgmqj?q=Important+Changes+to+Trunk+and+Use+of+Ant+%26+Gradle

Reference JIRA: https://issues.apache.org/jira/browse/OFBIZ-7534


Added:
    ofbiz/trunk/README.md
    ofbiz/trunk/build.gradle
    ofbiz/trunk/gradle/
    ofbiz/trunk/gradle/wrapper/
    ofbiz/trunk/gradle/wrapper/gradle-wrapper.jar   (with props)
    ofbiz/trunk/gradle/wrapper/gradle-wrapper.properties   (with props)
    ofbiz/trunk/gradlew   (with props)
    ofbiz/trunk/gradlew.bat   (with props)
    ofbiz/trunk/settings.gradle
Removed:
    ofbiz/trunk/README
Modified:
    ofbiz/trunk/NOTICE
    ofbiz/trunk/framework/common/src/org/ofbiz/common/email/EmailServices.java
    ofbiz/trunk/framework/start/src/org/ofbiz/base/start/StartupCommandUtil.java

Modified: ofbiz/trunk/NOTICE
URL: http://svn.apache.org/viewvc/ofbiz/trunk/NOTICE?rev=1751309&r1=1751308&r2=1751309&view=diff
==============================================================================
--- ofbiz/trunk/NOTICE (original)
+++ ofbiz/trunk/NOTICE Mon Jul  4 15:22:47 2016
@@ -293,3 +293,36 @@ NotSoSerial
 Copyright 2015 Kantega AS
 
 This product includes the software from the ASM project developed at France Télécom: http://asm.objectweb.org
+
+=========================================================================
+==  BIS Crypto TSU exception notice                                    ==
+=========================================================================
+   This distribution includes cryptographic software.  The country in
+   which you currently reside may have restrictions on the import,
+   possession, use, and/or re-export to another country, of
+   encryption software.  BEFORE using any encryption software, please
+   check your country's laws, regulations and policies concerning the
+   import, possession, or use, and re-export of encryption software, to
+   see if this is permitted.  See <http://www.wassenaar.org/> for more
+   information.
+
+   The U.S. Government Department of Commerce, Bureau of Industry and
+   Security (BIS), has classified this software as Export Commodity
+   Control Number (ECCN) 5D002.C.1, which includes information security
+   software using or performing cryptographic functions with asymmetric
+   algorithms.  The form and manner of this Apache Software Foundation
+   distribution makes it eligible for export under the License Exception
+   ENC Technology Software Unrestricted (TSU) exception (see the BIS
+   Export Administration Regulations, Section 740.13) for both object
+   code and source code.
+
+   The following provides more details on the included cryptographic
+   software:
+
+   * Various classes in OFBiz, including DesCrypt, HashCrypt, and
+     BlowFishCrypt use libraries from the Sun Java JDK API including
+     java.security.* and javax.crypto.* (the JCE, Java Cryptography
+     Extensions API)
+   * Other classes such as HttpClient and various related ones use
+     the JSSE (Java Secure Sockets Extension) API
+=========================================================================
\ No newline at end of file

Added: ofbiz/trunk/README.md
URL: http://svn.apache.org/viewvc/ofbiz/trunk/README.md?rev=1751309&view=auto
==============================================================================
--- ofbiz/trunk/README.md (added)
+++ ofbiz/trunk/README.md Mon Jul  4 15:22:47 2016
@@ -0,0 +1,436 @@
+Apache OFBiz
+============
+
+Welcome to __Apache OFBiz__! A powerful top level Apache software project.
+OFBiz is an Enterprise Resource Planning (ERP) System written in Java and
+houses a large set of libraries, entities, services and features to run 
+all aspects of your business.
+
+For more details about OFBiz please visit the OFBiz Documentation page:
+
+[OFBiz documentation](http://ofbiz.apache.org/documentation.html)
+
+[OFBiz License](http://www.apache.org/licenses/LICENSE-2.0)
+
+System requirements
+-------------------
+
+The only requirement to run OFBiz is to have the Java Development Kit (JDK) 
+version 8 installed on your system (not just the JRE, but the full JDK) which
+you can download from the below link.
+
+[JDK download](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
+
+>_Note_: if you are using eclipse, make sure of running the appropriate eclipse
+command `gradlew eclipse`. This command will prepare OFBiz for eclipse with
+the correct classpath and settings.
+
+Quick start
+-----------
+
+To quickly install and fire-up OFBiz, please follow the below instructions
+from the command line at the OFBiz top level directory (folder)
+
+### Prepare OFBiz:
+
+MS Windows:
+`gradlew cleanAll loadDefault`
+
+Unix-like OS:
+`./gradlew cleanAll loadDefault`
+
+### Start OFBiz:
+
+MS Windows:
+`gradlew ofbiz`
+
+Unix-like OS:
+`./gradlew ofbiz`
+
+### Visit OFBiz through your browser:
+
+[Order Back Office](https://localhost:8443/ordermgr)
+
+[Accounting Back Office](https://localhost:8443/accounting)
+
+[Administrator interface](https://localhost:8443/webtools)
+
+You can log in with the user __admin__ and password __ofbiz__.
+
+>_Note_: the default configuration uses an embedded Java database
+(Apache Derby) and embedded application server components such as
+Tomcat, Geronimo (transaction manager), etc.
+
+* * * * * * * * * * * *
+
+Build system syntax
+-------------------
+
+All build tasks are executed using the __Gradle__ build system which
+is embedded in OFBiz. To execute build tasks go to OFBiz top-level
+directory (folder) and execute tasks from there.
+
+### Operating System Syntax
+
+The syntax for tasks differ slightly between windows and Unix-like systems
+
+- __Windows__: `gradlew <tasks-in-here>`
+
+- __Unix-like__: `./gradlew <tasks-in-here>`
+
+For the rest of this document, we will use the windows syntax, if you are on
+a Unix-like system, you need to add the `./` to gradlew
+
+### Types of tasks in Gradle
+
+There are two types of tasks designed for OFBiz in Gradle:
+
+- __Standard tasks__: To execute general standard Gradle tasks
+
+- __OFBiz server tasks__: To execute OFBiz startup commands. These
+  tasks start with one of the following words:
+  - __ofbiz__ : standard server commands
+  - __ofbizDebug__ : server commands running in remote debug mode
+  - __ofbizSecure__ : server commands running in secure mode using notsoserial API
+  - __ofbizBackground__ ; server commands running in a background forked process
+  - __ofbizBackgroundSecure__ : server commands running in a background forked
+    process in secure mode using the notsoserial API
+
+Tips: 
+
+- OFBiz __server commands__ require __"quoting"__ the 
+  commands. For example: `gradlew "ofbiz --help"`
+
+- Shortcuts to task names can be used by writing the
+  first letter of every word in a task name. However, you
+  cannot use the shortcut form for OFBiz server tasks.
+  Example: `gradlew loadAdminUserLogin -PuserLoginId=myadmin` = `gradlew lAUL -PuserLoginId=myadmin`
+
+#### Example standard tasks
+
+`gradlew build`
+
+`gradlew cleanAll loadDefault testIntegration`
+
+#### Example OFBiz server tasks
+
+`gradlew "ofbiz --help"`
+
+`gradlew "ofbizSecure --start --portoffset 10000"`
+
+`gradlew "ofbizDebug --test"`
+
+`gradlew "ofbizBackground --start --portoffset 10000"`
+
+`gradlew "ofbiz --shutdown --portoffset 10000"`
+
+`gradlew ofbiz` (default is --start)
+
+#### Example mixed tasks (standard and OFBiz server)
+
+`gradlew cleanAll loadDefault "ofbiz --start"`
+
+* * * * * * * * * * * *
+
+Quick reference
+---------------
+
+You can use the below common list of tasks as a quick reference
+for controlling the system. This document uses the windows task
+syntax, if you are on a Unix-like system, you need to add the 
+`./` to gradlew i.e. `./gradlew`
+
+* * * * * * * * * * * *
+
+### Help tasks
+
+#### List OFBiz server commands
+
+List all available commands to control the OFBiz server
+
+`gradlew "ofbiz --help"`
+
+#### List build tasks
+
+List all available tasks from the build system
+
+`gradlew tasks`
+
+#### List build projects
+
+List all available projects in the build system
+
+`gradlew projects`
+
+#### Gradle build system help
+
+Show usage and options for the Gradle build system
+
+`gradlew --help`
+
+* * * * * * * * * * * *
+
+### Server command tasks
+
+#### Start OFBiz
+
+`gradlew "ofbiz --start"`
+
+start is the default server task so this also works:
+
+`gradlew ofbiz`
+
+#### Shutdown OFBiz
+
+`gradlew "ofbiz --shutdown"`
+
+#### Get OFBiz status
+
+`gradlew "ofbiz --status"`
+
+#### Start OFBiz in remote debug mode
+
+Starts OFBiz in remote debug mode and waits for debugger
+or IDEs to connect on port __5005__
+
+`gradlew "ofbizDebug --start"`
+
+OR
+
+`gradlew ofbizDebug`
+
+#### Start OFBiz in secure mode
+
+Starts OFBiz in secure mode using the notsoserial API to prevent
+Java serialization security issues
+
+`gradlew "ofbizSecure --start"`
+
+OR
+
+`gradlew ofbizSecure`
+
+#### Start OFBiz on a different port
+
+Start OFBiz of the network port offsetted by the range
+provided in the argument to --portoffset
+
+`gradlew "ofbiz --start --portoffset 10000"`
+
+#### Start OFBiz in the background
+
+Start OFBiz in the background by forking it to a new
+process and redirecting the output to __runtime/logs/console.log__
+
+`gradlew "ofbizBackground --start"`
+
+OR
+
+`gradlew ofbizBackground`
+
+You can also offset the port, for example:
+
+`gradlew "ofbizBackground --start --portoffset 10000"`
+
+#### Start OFBiz in the background in secure mode
+
+Start OFBiz in secure mode in the background by forking it to a new
+process and redirecting the output to __runtime/logs/console.log__
+
+`gradlew "ofbizBackgroundSecure --start"`
+
+OR
+
+`gradlew ofbizBackgroundSecure`
+
+* * * * * * * * * * * *
+
+### Data loading tasks
+
+OFBiz contains the following data reader types:
+
+- __seed__: OFBiz and External Seed Data - to be maintained along with source and
+  updated whenever a system deployment is updated
+- __seed-initial__: OFBiz and External Seed Data - to be maintained along with 
+  source like other seed data, but only loaded initially and not updated
+  when a system is updated except manually reviewing each line
+- __demo__: OFBiz Only Demo Data
+- __ext__: External General Data (custom)
+- __ext-test__: External Test Data (custom)
+- __ext-demo__: External Demo Data (custom)
+
+you can choose which data readers to pass in the following syntax:
+
+`gradlew "ofbiz --load-data readers=<readers-here-comma-separated>"`
+
+Example:
+
+`gradlew "ofbiz --load-data readers=seed,seed-initial,ext,ext-demo"`
+
+#### Load default OFBiz data
+
+Load default data; meant for generic OFBiz development, 
+testing, demonstration, etc purposes
+
+`gradlew loadDefault`
+
+OR
+
+`gradlew "ofbiz --load-data"`
+
+#### Load seed data
+
+Load ONLY the seed data (not seed-initial, demo, ext* or anything else);
+meant for use after an update of the code to reload the seed data
+as it is generally maintained along with the code and needs to be
+in sync for operation
+
+`gradlew "ofbiz --load-data readers=seed"`
+
+#### load ext data
+
+Load seed, seed-initial and ext data; meant for manual/generic
+testing, development, or going into production with a derived
+system based on stock OFBiz where the ext data basically
+replaces the demo data
+
+`gradlew "ofbiz --load-data readers=seed,seed-initial,ext"`
+
+#### load ext test data
+
+Load seed, seed-initial, ext and ext-test data; meant for
+automated testing with a derived system based on stock OFBiz
+
+`gradlew "ofbiz --load-data readers=seed,seed-initial,ext,ext-test"`
+
+#### load data from an entity file
+
+Load data from an XML file holding entity data.
+
+`gradlew "ofbiz --load-data file=foo/bar/FileNameHere.xml"`
+
+#### create a new tenant
+
+Create a new tenant in your environment, create the delegator, load
+initial data with admin-user and password (needs multitenant=Y in 
+general.properties). The following project parameters are passed:
+
+- tenantId: mandatory
+- tenantName: mandatory, name of the tenant
+- domainName: optional, default is org.ofbiz
+- tenantReaders: optional, default value is seed,seed-initial,demo
+- dbPlatform: optional, D(Derby), M(MySQL), O(Oracle), P(PostgreSQL) (default D) 
+- dbIp: optional, ip address of the database
+- dbUser: optional, username of the database
+- dbPassword: optional, password of the database
+
+`gradlew createTenant -PtenantId=mytenant -PtenantName="My Name"`
+
+`gradlew createTenant -PtenantId=mytenant -PtenantName="My Name" -PdomainName=com.example -PtenantReaders=seed,seed-initial,ext -PdbPlatform=M -PdbIp=127.0.0.1 -PdbUser=mydbuser -PdbPassword=mydbpass`
+
+If run successfully, the system creates a new tenant having:
+
+- delegator: default#${tenandId} (e.g. default#mytenant)
+- admin user: ${tenantId}-admin (e.g. mytenant-admin)
+- admin user password: ofbiz
+
+#### load data for a specific tenant
+
+Load data for one specific tenant in a multitenant environment. Note
+that you must set multitenant=Y in general.properties and the
+following project parameters are passed:
+
+- tenantId (mandatory)
+- tenantReaders (optional)
+- tenantComponent (optional)
+
+`gradlew loadTenant -PtenantId=mytenant`
+
+`gradlew loadTenant -PtenantId=mytenant -PtenantReaders=seed,seed-initial,demo -PtenantComponent=base`
+
+* * * * * * * * * * * *
+
+### Testing tasks
+
+#### Execute all unit tests
+
+`gradlew test`
+
+#### Execute all integration tests
+
+`gradlew testIntegration`
+
+OR
+
+`gradlew 'ofbiz --test'`
+
+#### Execute an integration test case
+
+run a test case, in this example the componnet is "entity" and the case
+name is "entity-tests"
+
+`gradlew "ofbiz --test component=entity --test case=entity-tests"`
+
+#### Execute an integration test case in debug mode
+
+listens on port __5005__
+
+`gradlew "ofbizDebug --test component=entity --test case=entity-tests"`
+
+#### Execute an integration test suite
+
+listens on port __5005__
+
+`gradlew "ofbiz --test component=widget --test suitename=org.ofbiz.widget.test.WidgetMacroLibraryTests"`
+
+#### Execute an integration test suite in debug mode
+
+listens on port __5005__
+
+`gradlew "ofbizDebug --test component=widget --test suitename=org.ofbiz.widget.test.WidgetMacroLibraryTests"`
+
+* * * * * * * * * * * *
+
+### Miscellaneous tasks
+
+#### Launch a graphical user interface of Gradle
+
+This is a very convenient feature of Gradle which
+allows the user to interact with Gradle through a
+swing GUI. You can save frequently used commands
+in a list of favorites for frequent reuse.
+
+`gradlew --gui`
+
+#### Run all tests on a clean system
+
+`gradlew cleanAll loadDefault testIntegration`
+
+#### Clean all generated artifacts
+
+`gradlew cleanAll`
+
+#### Refresh the generated artifacts
+
+`gradlew clean build`
+
+#### Create a custom component in hot-deploy
+
+`gradlew createComponent -PcomponentName=Custom -PcomponentResourceName=Custom -PwebappName=customweb -PbasePermission=OFBTOOLS,CUSTOM_SECURITY`
+
+#### Create an admin user account
+
+Create an admin user with login name MyUserName and default password
+with value "ofbiz". Upon first login OFBiz will request changing the
+default password
+
+`gradlew loadAdminUserLogin -PuserLoginId=MyUserName`
+
+#### Setup eclipse project for OFBiz
+
+Thanks to some gradle magic, setting up OFBiz on eclipse is very
+easy. All you need is to execute one command and then you can
+import the project to eclipse. This command will generate
+the necessary __.classpath__ and __.project__ files for eclipse.
+
+`gradlew eclipse`
\ No newline at end of file

Added: ofbiz/trunk/build.gradle
URL: http://svn.apache.org/viewvc/ofbiz/trunk/build.gradle?rev=1751309&view=auto
==============================================================================
--- ofbiz/trunk/build.gradle (added)
+++ ofbiz/trunk/build.gradle Mon Jul  4 15:22:47 2016
@@ -0,0 +1,669 @@
+/*
+ * 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.
+ */
+import org.apache.tools.ant.filters.ReplaceTokens
+
+/* ========================================================
+ * Project setup
+ * ======================================================== */
+
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+evaluationDependsOnChildren()
+
+allprojects {
+    repositories{
+        jcenter()
+    }
+}
+subprojects {
+    configurations {
+        ofbizPluginLibs
+    }
+}
+
+defaultTasks 'build'
+
+sourceCompatibility = '1.8'
+targetCompatibility = '1.8'
+
+configurations {
+    junitLibs
+}
+dependencies {
+
+    // general framework libs
+    compile 'commons-cli:commons-cli:1.3.1'
+
+    // plugin libs
+    subprojects.each { subProject ->
+        compile project(path: subProject.path, configuration: 'ofbizPluginLibs')
+    }
+
+    // libs needed for junitreport
+    junitLibs 'junit:junit:4.12'
+    junitLibs 'org.apache.ant:ant-junit:1.9.7'
+    junitLibs 'org.apache.ant:ant-junit4:1.9.7'
+
+    // local libs
+    getDirectoryInActiveComponentsIfExists('lib').each { libDir ->
+        compile fileTree(dir: libDir, include: '**/*.jar')
+    }
+    compile fileTree(dir: 'lib', include: '**/*.jar')
+    runtime files("${projectDir}/build/libs/ofbiz-base-test.jar")
+}
+
+def excludedJavaSources = []
+excludedJavaSources.add 'org/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java'
+excludedJavaSources.add 'org/ofbiz/accounting/thirdparty/ideal/IdealEvents.java'
+excludedJavaSources.add 'org/ofbiz/accounting/thirdparty/ideal/IdealPaymentServiceTest.java'
+excludedJavaSources.add 'org/ofbiz/accounting/thirdparty/orbital/OrbitalPaymentServices.java'
+excludedJavaSources.add 'org/ofbiz/accounting/thirdparty/paypal/PayPalServices.java'
+excludedJavaSources.add 'org/ofbiz/accounting/thirdparty/securepay/SecurePayPaymentServices.java'
+excludedJavaSources.add 'org/ofbiz/accounting/thirdparty/securepay/SecurePayServiceTest.java'
+excludedJavaSources.add 'org/ofbiz/accounting/thirdparty/verisign/PayflowPro.java'
+excludedJavaSources.add 'org/ofbiz/content/openoffice/OpenOfficeByteArrayInputStream.java'
+excludedJavaSources.add 'org/ofbiz/content/openoffice/OpenOfficeByteArrayOutputStream.java'
+excludedJavaSources.add 'org/ofbiz/content/openoffice/OpenOfficeServices.java'
+excludedJavaSources.add 'org/ofbiz/content/openoffice/OpenOfficeWorker.java'
+excludedJavaSources.add 'org/ofbiz/content/report/JREntityListIteratorDataSource.java'
+excludedJavaSources.add 'org/ofbiz/content/report/JRMapCollectionDataSource.java'
+excludedJavaSources.add 'org/ofbiz/order/thirdparty/taxware/TaxwareException.java'
+excludedJavaSources.add 'org/ofbiz/order/thirdparty/taxware/TaxwareServices.java'
+excludedJavaSources.add 'org/ofbiz/order/thirdparty/taxware/TaxwareUTL.java'
+excludedJavaSources.add 'ShipmentScaleApplet.java'
+excludedJavaSources.add 'org/ofbiz/securityext/thirdparty/truition/TruitionCoReg.java'
+excludedJavaSources.add 'org/ofbiz/webapp/view/JasperReportsJXlsViewHandler.java'
+excludedJavaSources.add 'org/ofbiz/webapp/view/JasperReportsPdfViewHandler.java'
+excludedJavaSources.add 'org/ofbiz/webapp/view/JasperReportsPoiXlsViewHandler.java'
+excludedJavaSources.add 'org/ofbiz/webapp/view/JasperReportsXmlViewHandler.java'
+
+sourceSets {
+    main {
+        java {
+            srcDirs = getDirectoryInActiveComponentsIfExists('src')
+            exclude excludedJavaSources
+        }
+        resources {
+            srcDirs = getDirectoryInActiveComponentsIfExists('src')
+            srcDirs += getDirectoryInActiveComponentsIfExists('config')
+            exclude excludedJavaSources
+        }
+    }
+}
+
+def jvmArguments = ['-Xms128M', '-Xmx512M']
+ext.ofbizMainClass = 'org.ofbiz.base.start.Start'
+
+/* ========================================================
+ * Tasks
+ * ======================================================== */
+
+// ========== Task group labels ==========
+def cleanupGroup = 'Cleaning'
+def ofbizServer = 'OFBiz Server'
+def sysadminGroup = 'System Administration'
+def committerGroup = 'OFBiz committers'
+
+// ========== OFBiz Server tasks ==========
+
+task loadDefault(group: ofbizServer) {
+    dependsOn 'ofbiz --load-data'
+    description 'Load all data; meant for OFBiz development, testing, and demo purposes'
+}
+
+task testIntegration(group: ofbizServer) {
+    dependsOn 'ofbiz --test'
+    description 'Run OFBiz integration tests; You must run loadDefault before running this task'
+}
+
+task loadAdminUserLogin(group: ofbizServer) {
+    description 'Create admin user with temporary password equal to ofbiz. You must provide userLoginId'
+    createOfbizCommandTask('executeLoadAdminUser',
+        ['--load-data', 'file=/runtime/tmp/AdminUserLoginData.xml'],
+        jvmArguments, false)
+    executeLoadAdminUser.doFirst {
+        copy {
+            from ("${projectDir}/framework/resources/templates/AdminUserLoginData.xml") {
+                filter(ReplaceTokens, tokens: [userLoginId: userLoginId])
+            }
+            into "${projectDir}/runtime/tmp/"
+        }
+    }
+    dependsOn executeLoadAdminUser
+    doLast {
+        delete("${projectDir}/runtime/tmpe/AdminUserLoginData.xml")
+    }
+}
+
+task loadTenant(group: ofbizServer, description: 'Load data using tenantId') {
+
+    createOfbizCommandTask('executeLoadTenant', [], jvmArguments, false)
+
+    if(project.hasProperty('tenantId')) {
+        executeLoadTenant.args '--load-data'
+        executeLoadTenant.args "delegator=default#${tenantId}"
+    }
+    if(project.hasProperty('tenantReaders')) {
+        executeLoadTenant.args '--load-data'
+        executeLoadTenant.args "readers=${tenantReaders}"
+    }
+    if(project.hasProperty('tenantComponent')) {
+        executeLoadTenant.args '--load-data'
+        executeLoadTenant.args "component=${tenantComponent}"
+    }
+
+    doLast {
+        if(!project.hasProperty('tenantId')) {
+            throw new GradleException('Missing project property tenantId')
+        }
+    }
+    dependsOn executeLoadTenant
+}
+
+task createTenant(group: ofbizServer, description: 'Create a new tenant in your environment') {
+
+    def databaseTemplateFile = "${projectDir}/framework/resources/templates/AdminNewTenantData-Derby.xml"
+
+    task prepareAndValidateTenantArguments << {
+        if(!project.hasProperty('tenantId')) {
+            throw new GradleException('Project property tenantId is missing')
+        }
+        if(!project.hasProperty('tenantName')) {
+            throw new GradleException('Project property tenantName is missing')
+        }
+        // dbPlatform values: D(Derby), M(MySQL), O(Oracle), P(PostgreSQL) (default D)
+        if(project.hasProperty('dbPlatform')) {
+            if(dbPlatform == 'D') {
+                databaseTemplateFile = "${projectDir}/framework/resources/templates/AdminNewTenantData-Derby.xml"
+            } else if(dbPlatform == 'M') {
+                databaseTemplateFile = "${projectDir}/framework/resources/templates/AdminNewTenantData-MySQL.xml"
+            } else if(dbPlatform == 'O') {
+                databaseTemplateFile = "${projectDir}/framework/resources/templates/AdminNewTenantData-Oracle.xml"
+            } else if(dbPlatform == 'P') {
+                databaseTemplateFile = "${projectDir}/framework/resources/templates/AdminNewTenantData-PostgreSQL.xml"
+            } else {
+                throw new GradleException('Invalid value for property dbPlatform: ' + "${dbPlatform}")
+            }
+        }
+    }
+
+    task generateDatabaseTemplateFile(dependsOn: prepareAndValidateTenantArguments) << {
+        def filterTokens = ['tenantId': tenantId,
+            'tenantName': tenantName,
+            'domainName': project.hasProperty('domainName')? "${domainName}":'org.ofbiz',
+            'db-IP': project.hasProperty('dbIp')? "${dbIp}":'',
+            'db-User': project.hasProperty('dbUser')? "${dbUser}":'',
+            'db-Password': project.hasProperty('dbPassword')? "${dbPassword}":'']
+
+        generateFileFromTemplate(databaseTemplateFile, 'runtime/tmp',
+            filterTokens, 'tmpFilteredTenantData.xml')
+    }
+
+    task generateAdminUserTemplateFile(dependsOn: prepareAndValidateTenantArguments) << {
+        generateFileFromTemplate(
+            "${projectDir}/framework/resources/templates/AdminUserLoginData.xml",
+            'runtime/tmp',
+            ['userLoginId': "${tenantId}-admin".toString()],
+            'tmpFilteredUserLogin.xml')
+    }
+
+    // Load the tenants master database
+    createOfbizCommandTask('loadTenantOnDefaultDelegator',
+        ['--load-data', 'file=/runtime/tmp/tmpFilteredTenantData.xml'],
+        jvmArguments, false)
+    loadTenantOnDefaultDelegator.dependsOn(generateDatabaseTemplateFile, generateAdminUserTemplateFile)
+    
+    // Load the actual tenant data
+    createOfbizCommandTask('loadTenantData', [], jvmArguments, false)
+    loadTenantData.dependsOn(loadTenantOnDefaultDelegator)
+    
+    // Load the tenant admin user account
+    createOfbizCommandTask('loadTenantAdminUserLogin', [], jvmArguments, false)
+    loadTenantAdminUserLogin.dependsOn(loadTenantData)
+    
+    /* pass arguments to tasks, must be done this way
+     * because we are in the configuration phase. We cannot
+     * set the parameters at the execution phase. */
+    if(project.hasProperty('tenantId')) {
+        loadTenantData.args '--load-data'
+        loadTenantData.args "delegator=default#${tenantId}"
+        
+        loadTenantAdminUserLogin.args '--load-data'
+        loadTenantAdminUserLogin.args "delegator=default#${tenantId}"
+        loadTenantAdminUserLogin.args '--load-data'
+        loadTenantAdminUserLogin.args 'file=runtime/tmp/tmpFilteredUserLogin.xml'
+    }
+    if(project.hasProperty('tenantReaders')) {
+        loadTenantData.args '--load-data'
+        loadTenantData.args "readers=${tenantReaders}"
+    }
+    
+    dependsOn(loadTenantAdminUserLogin)
+
+    // cleanup
+    doLast {
+        delete("${projectDir}/runtime/tmp/tmpFilteredTenantData.xml")
+        delete("${projectDir}/runtime/tmp/tmpFilteredUserLogin.xml")
+    }
+}
+
+// ========== System Administration tasks ==========
+task createComponent(group: sysadminGroup, description: 'Create the layout of an OFBiz component in the hot-deploy folder.') << {
+
+    def filterTokens = ['component-name': componentName,
+        'component-resource-name': componentResourceName,
+        'webapp-name': webappName,
+        'base-permission': basePermission]
+    def templateDir = "${projectDir}/framework/resources/templates"
+    def componentDir = "${projectDir}/hot-deploy/${componentName}"
+
+    logger.info('Creating a component with the following properties: ')
+    logger.info(" - componentName: ${componentName}")
+    logger.info(" - componentResourceName: ${componentResourceName}")
+    logger.info(" - webappName: ${webappName}")
+    logger.info(" - basePermission: ${basePermission}")
+
+    mkdir componentDir
+    mkdir componentDir+"/config"
+    mkdir componentDir+"/data"
+    mkdir componentDir+"/data/helpdata"
+    mkdir componentDir+"/dtd"
+    mkdir componentDir+"/documents"
+    mkdir componentDir+"/entitydef"
+    mkdir componentDir+"/lib"
+    mkdir componentDir+"/patches"
+    mkdir componentDir+"/patches/test"
+    mkdir componentDir+"/patches/qa"
+    mkdir componentDir+"/patches/production"
+    mkdir componentDir+"/script"
+    mkdir componentDir+"/servicedef"
+    mkdir componentDir+"/src"
+    mkdir componentDir+"/testdef"
+    mkdir componentDir+"/webapp"
+    mkdir componentDir+"/webapp/${webappName}"
+    mkdir componentDir+"/webapp/${webappName}/error"
+    mkdir componentDir+"/webapp/${webappName}/WEB-INF"
+    mkdir componentDir+"/webapp/${webappName}/WEB-INF/actions"
+    mkdir componentDir+"/widget/"
+
+    generateFileFromTemplate(templateDir+"/ofbiz-component.xml", componentDir,
+        filterTokens, "ofbiz-component.xml")
+    generateFileFromTemplate(templateDir+"/TypeData.xml", componentDir+"/data",
+        filterTokens, "${componentResourceName}TypeData.xml")
+    generateFileFromTemplate(templateDir+"/SecurityPermissionSeedData.xml", componentDir+"/data",
+        filterTokens, "${componentResourceName}SecurityPermissionSeedData.xml")
+    generateFileFromTemplate(templateDir+"/SecurityGroupDemoData.xml", componentDir+"/data",
+        filterTokens, "${componentResourceName}SecurityGroupDemoData.xml")
+    generateFileFromTemplate(templateDir+"/DemoData.xml", componentDir+"/data",
+        filterTokens, "${componentResourceName}DemoData.xml")
+    generateFileFromTemplate(templateDir+"/HELP.xml", componentDir+"/data/helpdata",
+        filterTokens, "HELP_${componentResourceName}.xml")
+    generateFileFromTemplate(templateDir+"/document.xml", componentDir+"/documents",
+        filterTokens, "${componentResourceName}.xml")
+    generateFileFromTemplate(templateDir+"/entitymodel.xml", componentDir+"/entitydef",
+        filterTokens, "entitymodel.xml")
+    generateFileFromTemplate(templateDir+"/services.xml", componentDir+"/servicedef",
+        filterTokens, "services.xml")
+    generateFileFromTemplate(templateDir+"/Tests.xml", componentDir+"/testdef",
+        filterTokens, "${componentResourceName}Tests.xml")
+    generateFileFromTemplate(templateDir+"/UiLabels.xml", componentDir+"/config",
+        filterTokens, "${componentResourceName}UiLabels.xml")
+    generateFileFromTemplate(templateDir+"/index.jsp", componentDir+"/webapp/${webappName}",
+        filterTokens, "index.jsp")
+    generateFileFromTemplate(templateDir+"/error.jsp", componentDir+"/webapp/${webappName}/error",
+        filterTokens, "error.jsp")
+    generateFileFromTemplate(templateDir+"/controller.xml", componentDir+"/webapp/${webappName}/WEB-INF",
+        filterTokens, "controller.xml")
+    generateFileFromTemplate(templateDir+"/web.xml", componentDir+"/webapp/${webappName}/WEB-INF",
+        filterTokens, "web.xml")
+    generateFileFromTemplate(templateDir+"/CommonScreens.xml", componentDir+"/widget",
+        filterTokens, "CommonScreens.xml")
+    generateFileFromTemplate(templateDir+"/Screens.xml", componentDir+"/widget",
+        filterTokens, "${componentResourceName}Screens.xml")
+    generateFileFromTemplate(templateDir+"/Menus.xml", componentDir+"/widget",
+        filterTokens, "${componentResourceName}Menus.xml")
+    generateFileFromTemplate(templateDir+"/Forms.xml", componentDir+"/widget",
+        filterTokens, "${componentResourceName}Forms.xml")
+
+    logger.info("Component successfully created in folder ${projectDir}/hot-deploy/${componentName}.")
+    logger.info("Restart OFBiz and then visit the URL: https://localhost:8443/${webappName}")
+}
+
+task createTestReports(group: sysadminGroup, description: 'Generate HTML reports from junit XML output') << {
+    ant.taskdef(name: 'junitreport',
+        classname: 'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator',
+        classpath: configurations.junitLibs.asPath)
+    ant.junitreport(todir: './runtime/logs/test-results') {
+        fileset(dir: './runtime/logs/test-results') {
+            include(name: '*.xml')
+        }
+        report(format:'frames', todir:'./runtime/logs/test-results/html')
+    }
+}
+/* 
+ * TODO replace this code with something more declarative.
+ * We are using it so that if tests fail we still get HTML reports
+ */
+gradle.taskGraph.afterTask { Task task, TaskState state ->
+    if (task.name ==~ /^ofbiz.*--test.*/
+        || task.name ==~ /^ofbiz.*-t.*/) {
+        tasks.createTestReports.execute()
+    }
+}
+
+// remove sources from subprojects
+eclipse.classpath.file.whenMerged { classpath ->
+    iterateOverActiveComponents { component ->
+        classpath.entries.removeAll { entry ->
+            entry.kind == 'src' && entry.path == '/' + component.toString().tokenize('/').last()
+        }
+    }
+}
+// remove eclipse files before regenerating them
+tasks.eclipse.dependsOn(cleanEclipse)
+
+// ========== Clean up tasks ==========
+task cleanCache(group: cleanupGroup, description: 'Clean the UtilCache file') << {
+    def props = retrievePropsFromFile('framework/base/config/cache.properties')
+    if(props['cache.file.store']) {
+        delete props['cache.file.store']+'.db'
+    }
+}
+task cleanCatalina(group: cleanupGroup, description: 'Clean Catalina data in runtime/catalina/work') << {
+    delete './runtime/catalina/work'
+}
+task cleanData(group: cleanupGroup, description: 'Clean all DB data (Derby) under runtime/data') << {
+    deleteAllInDirWithExclusions('runtime/data/', ['README', 'derby.properties'])
+}
+task cleanDownloads(group: cleanupGroup, description: 'Clean all downloaded files') << {
+    delete fileTree(dir: './framework/base/lib', includes: ['activemq-*.jar'])
+    delete fileTree(dir: './framework/entity/lib/jdbc', includes: ['postgresql-*.jar'])
+    delete fileTree(dir: './framework/entity/lib/jdbc', includes: ['mysql-*.jar'])
+}
+task cleanLogs(group: cleanupGroup, description: 'Clean all logs in runtime/logs') << {
+    deleteAllInDirWithExclusions('runtime/logs/', ['README'])
+}
+task cleanOutput(group: cleanupGroup, description: 'Clean runtime/output directory') << {
+    deleteAllInDirWithExclusions('runtime/output/', ['README'])
+}
+task cleanIndexes(group: cleanupGroup, description: 'Remove search indexes (e.g. Lucene) from runtime/indexes') << {
+    deleteAllInDirWithExclusions('runtime/indexes/', ['README', 'index.properties'])
+}
+task cleanTempfiles(group: cleanupGroup, description: 'Remove file in runtime/tempfiles') << {
+    deleteAllInDirWithExclusions('runtime/tempfiles/', ['README'])
+    deleteAllInDirWithExclusions('runtime/tmp/', ['README'])
+}
+task cleanUploads(group: cleanupGroup, description: 'Remove uploaded files.') << {
+    deleteAllInDirWithExclusions('runtime/uploads/', [])
+}
+task cleanXtra(group: cleanupGroup, description: 'Clean extra generated files like .rej, .DS_Store, etc.') << {
+    delete fileTree(dir: '.', includes: ['**/.nbattrs', '**/*~','**/.#*', '**/.DS_Store', '**/*.rej', '**/*.orig'])
+}
+task cleanGradle(group: cleanupGroup, description: 'clean generated files from gradle') << {
+    delete file('.gradle')
+    delete file('build/libs/ofbiz-base-test.jar')
+}
+
+def cleanTasks = getTasksMatchingRegex(/^clean.+/)
+task cleanAll(group: cleanupGroup, dependsOn: [cleanTasks, clean]) {
+    description 'Execute all cleaning tasks.'
+}
+
+// ========== Tasks for OFBiz committers ==========
+def websiteDir = "${projectDir}/../site"
+task copyDtds(group: committerGroup, description: 'Copy all DTDs from OFBiz instance to website') << {
+    mkdir websiteDir+'/dtds'
+    copy {
+        from(fileTree("${projectDir}").files) {
+            include '**/*.xsd'
+            exclude '**/002*.xsd'
+            exclude '**/068*.xsd'
+            exclude '**/161*.xsd'
+            exclude '**/196*.xsd'
+            exclude '**/197*.xsd'
+        }
+        into websiteDir+'/dtds'
+    }
+}
+
+task gitInfoFooter(group: committerGroup, description: 'Update the Git Branch-revision info in the footer') << {
+    def branch
+    def revision
+    def timestamp = new Date().format 'yyyy-MM-dd HH:mm:ss'
+    File gitFooterFile = new File("${projectDir}/runtime/GitInfo.ftl")  
+
+    def branchOutput = new ByteArrayOutputStream()
+    exec{
+        commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
+        standardOutput = branchOutput
+    }
+    branch = branchOutput.toString()
+    def revisionOutput = new ByteArrayOutputStream()
+    exec{
+        commandLine 'git', 'rev-parse', 'HEAD'
+        standardOutput = revisionOutput
+    }
+    revision = revisionOutput.toString()
+    gitFooterFile.delete()
+    gitFooterFile.createNewFile()
+    gitFooterFile << "Branch: ${branch}"
+    gitFooterFile << "Revision: ${revision}"
+    gitFooterFile << "Built on: ${timestamp}" + System.lineSeparator()
+    gitFooterFile << "Java Version: ${org.gradle.internal.jvm.Jvm.current()}"
+}
+
+task svnInfoFooter(group: committerGroup, description: 'Update the Subversion revision info in the footer') << {
+    def timestamp = new Date().format 'yyyy-MM-dd HH:mm:ss'
+    File svnFooterFile = new File("${projectDir}/runtime/SvnInfo.ftl")
+    def svnOutput = new ByteArrayOutputStream()
+    exec{
+        commandLine 'svn', 'info', '--xml'
+        standardOutput = svnOutput
+    }
+    def info = new XmlParser().parseText(svnOutput.toString())
+    svnFooterFile.delete()
+    svnFooterFile.createNewFile()
+    svnFooterFile << "Branch: ${info.entry.url.text()}" + System.lineSeparator()
+    svnFooterFile << "Revision: ${info.entry.commit.@revision}" + System.lineSeparator()
+    svnFooterFile << "Built on: ${timestamp}" + System.lineSeparator()
+    svnFooterFile << "Java Version: ${org.gradle.internal.jvm.Jvm.current()}"
+}
+
+// ========== hidden support tasks ==========
+
+/* without executing this task, a test would fail that is named
+ * org.ofbiz.base.util.test.UtilObjectTests.testGetObjectFromFactory()
+ * 
+ * The test fails because it requires defining a service provider, read more below.
+ * http://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Service_Provider
+ */
+task createBaseTestServiceProviderJar << {
+    ant.jar(destfile: "${projectDir}/build/libs/ofbiz-base-test.jar") {
+        service(type: 'org.ofbiz.base.util.test.UtilObjectTests$TestFactoryIntf') {
+            provider(classname: 'org.ofbiz.base.util.test.UtilObjectTests$FirstTestFactory')
+            provider(classname: 'org.ofbiz.base.util.test.UtilObjectTests$SecondTestFactory')
+        }
+    }
+}
+classes.dependsOn createBaseTestServiceProviderJar
+
+/* ========================================================
+ * Rules-based OFBiz server commands
+ * ======================================================== */
+
+tasks.addRule('Pattern: ofbiz <Commands>: Execute OFBiz startup commands') { String taskName ->
+    if(taskName ==~ /^ofbiz\s.*/ || taskName == 'ofbiz') {
+        def arguments = (taskName - 'ofbiz').toLowerCase().tokenize(' ')
+        createOfbizCommandTask(taskName, arguments, jvmArguments, false)
+    }
+}
+
+tasks.addRule('Pattern: ofbizDebug <Commands>: Execute OFBiz startup commands in remote debug mode') { String taskName ->
+    if(taskName ==~ /^ofbizDebug\s.*/ || taskName == 'ofbizDebug') {
+        def arguments = (taskName - 'ofbizDebug').toLowerCase().tokenize(' ')
+        createOfbizCommandTask(taskName, arguments, jvmArguments, true)
+    }
+}
+
+tasks.addRule('Pattern: ofbizSecure <Commands>: Execute OFBiz startup commands pre-loading the notsoserial Java agent') { String taskName ->
+    if(taskName ==~ /^ofbizSecure\s.*/ || taskName == 'ofbizSecure') {
+        def arguments = (taskName - 'ofbizSecure').toLowerCase().tokenize(' ')
+        jvmArguments.add('-server')
+        jvmArguments.add("-javaagent:${projectDir}/tools/security/notsoserial/notsoserial-1.0-SNAPSHOT.jar")
+        jvmArguments.add("-Dnotsoserial.whitelist=${projectDir}/tools/security/notsoserial/empty.txt")
+        jvmArguments.add("-Dnotsoserial.dryrun=${projectDir}/tools/security/notsoserial/is-deserialized.txt")
+        jvmArguments.add("-Dnotsoserial.trace=${projectDir}/tools/security/notsoserial/deserialize-trace.txt")
+        createOfbizCommandTask(taskName, arguments, jvmArguments, false)
+    }
+}
+
+tasks.addRule('Pattern: ofbizBackground <Commands>: Execute OFBiz startup commands in background and output to console.log') { String taskName ->
+    if(taskName ==~ /^ofbizBackground\s.*/ || taskName == 'ofbizBackground') {
+        createOfbizBackgroundCommandTask(taskName)
+    }
+}
+
+tasks.addRule('Pattern: ofbizBackgroundSecure <Commands>: Execute OFBiz startup commands in background (secure mode) and output to console.log') { String taskName ->
+    if(taskName ==~ /^ofbizBackgroundSecure\s.*/ || taskName == 'ofbizBackgroundSecure') {
+        createOfbizBackgroundCommandTask(taskName)
+    }
+}
+
+/* ========================================================
+ * Helper Functions
+ * ======================================================== */
+
+def createOfbizCommandTask(taskName, arguments, jvmArguments, isDebugMode) {
+    task(type: JavaExec, taskName) {
+        jvmArgs(jvmArguments)
+        classpath = sourceSets.main.runtimeClasspath
+        main = ofbizMainClass 
+        debug = isDebugMode
+        arguments.each { argument ->
+            args argument
+        }
+    }
+}
+
+def createOfbizBackgroundCommandTask(taskName) {   
+    def os = System.getProperty("os.name").toLowerCase()
+    def sourceTask = taskName.tokenize().first()
+    def arguments = (taskName - sourceTask)
+
+    def targetTask
+    def gradleRunner
+
+    if(sourceTask == 'ofbizBackground') {
+        targetTask = 'ofbiz'
+    } else if(sourceTask == 'ofbizBackgroundSecure') {
+        targetTask = 'ofbizSecure'
+    }
+
+    if (os.contains("windows")) {
+        gradleRunner = 'gradlew'
+    } else {
+        gradleRunner = './gradlew'
+    }
+
+    task (taskName) {
+        doLast {
+            spawnProcess(gradleRunner, "${targetTask} ${arguments}")
+        }
+    }
+}
+
+def spawnProcess(command, arguments) {
+    ProcessBuilder pb = new ProcessBuilder(command, arguments)
+    File consoleLog = file("${projectDir}/runtime/logs/console.log");
+    
+    pb.directory(file("${projectDir}"))
+    pb.redirectErrorStream(true)
+    pb.redirectOutput(ProcessBuilder.Redirect.appendTo(consoleLog))
+    pb.start()
+}
+
+def getDirectoryInActiveComponentsIfExists(String dirName) {
+    def dirInComponents = []
+    iterateOverActiveComponents { component ->
+        def subDir = file(component.toString() + '/' + dirName)
+        if(subDir.exists()) {
+            dirInComponents.add subDir
+        }
+    }
+    return dirInComponents
+}
+
+def iterateOverActiveComponents(applyFunction) {
+    def frameworkComponents = new XmlParser().parse('framework/component-load.xml')
+    def applicationsComponents = new XmlParser().parse('applications/component-load.xml')
+    def specialpurposeComponents = new XmlParser().parse('specialpurpose/component-load.xml')
+
+    applyFunction file('framework/start')
+
+    frameworkComponents.children().each { component ->
+        applyFunction file("framework/"+component.@"component-location")
+    }
+    applicationsComponents.children().each { component ->
+        applyFunction file("applications/"+component.@"component-location")
+    }
+    specialpurposeComponents.children().each { component ->
+        applyFunction file("specialpurpose/"+component.@"component-location")
+    }
+
+    file('hot-deploy').eachDir { component ->
+        applyFunction(component)
+    }
+}
+
+def deleteAllInDirWithExclusions(dirName, exclusions) {
+    ant.delete (includeEmptyDirs: 'true', verbose: 'on') {
+        fileset(dir: dirName, includes: '**/*', erroronmissingdir: "false") {
+            exclusions.each { exclusion ->
+                exclude name: exclusion
+            }
+        }
+    }
+}
+
+def getTasksMatchingRegex(theRegex) {
+    def filteredTasks = []
+    tasks.each { task ->
+        if(task.name ==~ theRegex) {
+            filteredTasks.add(task)
+        }
+    }
+    return filteredTasks
+}
+
+def retrievePropsFromFile(propsFile) {
+    def props = new Properties()
+    file(propsFile).withReader { props.load(it) }
+    return props
+}
+
+def generateFileFromTemplate(templateFileInFullPath, targetDirectory, filterTokens, newFileName) {
+    copy {
+        from (templateFileInFullPath) {
+            filter ReplaceTokens, tokens: filterTokens
+            rename templateFileInFullPath.tokenize('/').last(), newFileName
+        }
+        into targetDirectory
+    }
+}

Modified: ofbiz/trunk/framework/common/src/org/ofbiz/common/email/EmailServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/email/EmailServices.java?rev=1751309&r1=1751308&r2=1751309&view=diff
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/email/EmailServices.java (original)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/email/EmailServices.java Mon Jul  4 15:22:47 2016
@@ -222,7 +222,6 @@ public class EmailServices {
             }
             if (UtilValidate.isNotEmpty(socketFactoryClass)) {
                 props.put("mail.smtp.socketFactory.class", socketFactoryClass);
-                Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
             }
             if (UtilValidate.isNotEmpty(socketFactoryFallback)) {
                 props.put("mail.smtp.socketFactory.fallback", socketFactoryFallback);

Modified: ofbiz/trunk/framework/start/src/org/ofbiz/base/start/StartupCommandUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/org/ofbiz/base/start/StartupCommandUtil.java?rev=1751309&r1=1751308&r2=1751309&view=diff
==============================================================================
--- ofbiz/trunk/framework/start/src/org/ofbiz/base/start/StartupCommandUtil.java (original)
+++ ofbiz/trunk/framework/start/src/org/ofbiz/base/start/StartupCommandUtil.java Mon Jul  4 15:22:47 2016
@@ -128,7 +128,7 @@ final class StartupCommandUtil {
             .build();
     private static final Option START = Option.builder("u")
             .longOpt(StartupOption.START.getName())
-            .desc("Start OFBiz (beware of possible needed JVM arguments...)")
+            .desc("Start OFBiz")
             .hasArg(false)
             .build();
     private static final Option STATUS = Option.builder("s")
@@ -187,7 +187,7 @@ final class StartupCommandUtil {
         formatter.printHelp(
                 new PrintWriter(printStream, true),
                 HelpFormatter.DEFAULT_WIDTH + 6,
-                "java -jar ofbiz.jar",
+                "ofbiz|ofbizDebug|ofbizSecure|ofbizBackground|ofbizBackgroundSecure",
                 System.lineSeparator() + "Executes OFBiz command e.g. start, shutdown, check status, etc",
                 getOfbizStartupOptions(),
                 HelpFormatter.DEFAULT_LEFT_PAD,
@@ -196,7 +196,7 @@ final class StartupCommandUtil {
                     + System.lineSeparator()
                     + "Also a command must be invoked separately for each argument e.g."
                     + System.lineSeparator()
-                    + "java -jar ofbiz.jar --test component=somecomp --test case=somecase",
+                    + "gradlew \"ofbiz --test component=somecomp --test case=somecase\"",
                 true);
     }
 

Added: ofbiz/trunk/gradle/wrapper/gradle-wrapper.jar
URL: http://svn.apache.org/viewvc/ofbiz/trunk/gradle/wrapper/gradle-wrapper.jar?rev=1751309&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ofbiz/trunk/gradle/wrapper/gradle-wrapper.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: ofbiz/trunk/gradle/wrapper/gradle-wrapper.properties
URL: http://svn.apache.org/viewvc/ofbiz/trunk/gradle/wrapper/gradle-wrapper.properties?rev=1751309&view=auto
==============================================================================
--- ofbiz/trunk/gradle/wrapper/gradle-wrapper.properties (added)
+++ ofbiz/trunk/gradle/wrapper/gradle-wrapper.properties Mon Jul  4 15:22:47 2016
@@ -0,0 +1,6 @@
+#Tue Jun 28 11:26:40 AST 2016
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip

Propchange: ofbiz/trunk/gradle/wrapper/gradle-wrapper.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/gradle/wrapper/gradle-wrapper.properties
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/gradle/wrapper/gradle-wrapper.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/gradlew
URL: http://svn.apache.org/viewvc/ofbiz/trunk/gradlew?rev=1751309&view=auto
==============================================================================
--- ofbiz/trunk/gradlew (added)
+++ ofbiz/trunk/gradlew Mon Jul  4 15:22:47 2016
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

Propchange: ofbiz/trunk/gradlew
------------------------------------------------------------------------------
    svn:executable = *

Added: ofbiz/trunk/gradlew.bat
URL: http://svn.apache.org/viewvc/ofbiz/trunk/gradlew.bat?rev=1751309&view=auto
==============================================================================
--- ofbiz/trunk/gradlew.bat (added)
+++ ofbiz/trunk/gradlew.bat Mon Jul  4 15:22:47 2016
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

Propchange: ofbiz/trunk/gradlew.bat
------------------------------------------------------------------------------
    svn:eol-style = CRLF

Added: ofbiz/trunk/settings.gradle
URL: http://svn.apache.org/viewvc/ofbiz/trunk/settings.gradle?rev=1751309&view=auto
==============================================================================
--- ofbiz/trunk/settings.gradle (added)
+++ ofbiz/trunk/settings.gradle Mon Jul  4 15:22:47 2016
@@ -0,0 +1,26 @@
+def iterateOverActiveComponents(applyFunction) {
+    def frameworkComponents = new XmlParser().parse('framework/component-load.xml')
+    def applicationsComponents = new XmlParser().parse('applications/component-load.xml')
+    def specialpurposeComponents = new XmlParser().parse('specialpurpose/component-load.xml')
+
+    applyFunction file('framework/start')
+
+    frameworkComponents.children().each { component ->
+        applyFunction file("framework/"+component.@"component-location")
+    }
+    applicationsComponents.children().each { component ->
+        applyFunction file("applications/"+component.@"component-location")
+    }
+    specialpurposeComponents.children().each { component ->
+        applyFunction file("specialpurpose/"+component.@"component-location")
+    }
+
+    file('hot-deploy').eachDir { component ->
+        applyFunction(component)
+    }
+}
+
+iterateOverActiveComponents { File component ->
+    def subProject = (component.toString() - rootDir)
+    include subProject.replaceAll('/', ':')
+}