Using Gradle, I'd like to be able to disable transitivity on one group of dependencies, while still allowing on others. Something like this:
// transitivity enabled
compile(
[group: 'log4j', name: 'log4j', version: '1.2.16'],
[group: 'commons-beanutils', name: 'commons-beanutils', version: '1.7.0']
)
// transitivity disabled
compile(
[group: 'commons-collections', name: 'commons-collections', version: '3.2.1'],
[group: 'commons-lang', name: 'commons-lang', version: '2.6'],
) {
transitive = false
}
Gradle won't accept this syntax. I can get it to work if I do this:
compile(group: 'commons-collections', name: 'commons-collections', version: '3.2.1') { transitive = false }
compile(group: 'commons-lang', name: 'commons-lang', version: '2.6']) { transitive = false }
But that requires me to specify the property on each dependency, when I'd rather group them together.
Anyone have a suggestion for a syntax that will work on this?
First, there are ways to simplify (or at least shorten) your declarations. For example:
compile 'commons-collections:commons-collections:3.2.1#jar'
compile 'commons-lang:commons-lang:2.6#jar'
Or:
def nonTransitive = { transitive = false }
compile 'commons-collections:commons-collections:3.2.1', nonTransitive
compile 'commons-lang:commons-lang:2.6', nonTransitive
In order to create, configure, and add multiple dependencies at once, you'll have to introduce a little abstraction. Something like:
def deps(String... notations, Closure config) {
def deps = notations.collect { project.dependencies.create(it) }
project.configure(deps, config)
}
dependencies {
compile deps('commons-collections:commons-collections:3.2.1',
'commons-lang:commons-lang:2.6') {
transitive = false
}
}
Create separate configurations, and have transitive = false on the desired configuration.
In the dependencies, simply include configurations into compile or any other configuration they belong to
configurations {
apache
log {
transitive = false
visible = false //mark them private configuration if you need to
}
}
dependencies {
apache 'commons-collections:commons-collections:3.2.1'
log 'log4j:log4j:1.2.16'
compile configurations.apache
compile configurations.log
}
The above lets me disable the transitive dependencies for log related resources while I have the default transitive = true applied for apache configuration.
Edited Below as per tair's comment:
would this fix?
//just to show all configurations and setting transtivity to false
configurations.all.each { config->
config.transitive = true
println config.name + ' ' + config.transitive
}
and run
gradle dependencies
to view the dependencies. I am using Gradle-1.0 and it behaves ok as far as showing the dependencies is concerned, when using both transitive false and true.
I have an active project where when turning transitive to true using above method, I have 75 dependencies and I have 64 when transitive to false.
worth doing a similar check with and check the build artifacts.
Related
I'm running into an issue unsure if it's me.
I'm using Plop.js within a project to quickly code generate boilerplate (bp) for new packages.
I've got 4 different template folders that plop maps from when a user enters the generate command.
User is prompted with a list of package types to create:
choices: ['react', 'node', 'browser', 'isomorphic'],
Based on the users response to the prompts, plop chooses the folder to pull the template files from.
Template folder structure looks like this:
plop-template/
- react/
- node/
- browser/
- isomorphic/
The templateFiles: property is correctly identifying and creating the bp based on the user response.
templateFiles: 'plop_templates/{{project-type}}/**/*/',
the issue i'm running into is the project-type is being added to the file destination path
So what i would like to occur is the
/project-name/ ... boiler plate created
But what is happening is:
/project-name/project-type/ ... boiler plate created
So, is it possible to remove the /project-type/ from the destination path?
Plopfile.js (v. "plop": "3.1.1"):
const findEtensionFile = require("../lib/file-extention-locator");
module.exports = function (plop) {
plop.getDestBasePath;
plop.setGenerator("component", {
prompts: [
{
type: "input",
name: "project-name",
message: "What's the name your project? ",
},
{
type: "list",
name: "project-type",
message: "Project Type:",
choices: ["react", "node", "browser", "isomorphic"],
},
],
actions: function (data) {
var actions = [];
actions.push({
type: "addMany",
globOptions: { dot: true },
destination: "../../../{{project-name}}",
base: "/",
templateFiles: "plop_templates/{{project-type}}/**/*/",
});
return actions;
},
});
};
What I've tried:
filter: property ... This can be used to modify the file contents, seems like that only affects the
base: property (string).. documentation seems to indicate this is the route where I can filter out but can't find a value that doesn't break BP creation.
Any help would be greatly appreciated.
Discovered the error was mine.
Seems like the base: value must match the entire value for templateFiles.
In this case:
base: 'plop_templates/{{project-type}}',
templateFiles: "plop_templates/{{project-type}}/**/*/",
Even though the /plop_templates/ folder wasn't being created in the path.
I am using Amazon Face Rekognition API and getting this error at the time of sending image to aws after capturing from camera
java.lang.NoSuchFieldError: No static field INSTANCE of type
Lorg/apache/http/conn/ssl/AllowAllHostnameVerifier; in class
Lorg/apache/http/conn/ssl/AllowAllHostnameVerifier; or its
superclasses (declaration of
'org.apache.http.conn.ssl.AllowAllHostnameVerifier' appears in
/system/framework/framework.jar!classes2.dex)
This is my gradle file
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.sitetrack"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
bundle {
language {
enableSplit = false
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
//Retrofit
implementation "com.squareup.retrofit2:retrofit:2.6.1"
implementation "com.squareup.retrofit2:converter-gson:2.6.1"
//Glide
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
//Design
implementation 'com.google.android.material:material:1.0.0'
//Sugar
implementation 'com.github.satyan:sugar:1.5'
//Dimensions
implementation 'com.intuit.sdp:sdp-android:1.0.6'
//Library
implementation project(':loaderLibrary')
//Multidex
implementation 'com.android.support:multidex:1.0.3'
//GoogleServices
implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
//Custom Camera
implementation "androidx.camera:camera-core:$camerax_version"
implementation "androidx.camera:camera-camera2:$camerax_version"
//AWS
implementation group: 'com.amazonaws', name: 'aws-java-sdk-rekognition', version: '1.11.681'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
This is code I am using for sending image to AWS
val rekognitionClient: AmazonRekognition = AmazonRekognitionClientBuilder.defaultClient()
val objectMapper = ObjectMapper()
// Get an image object from S3 bucket.
val image: Image = Image()
.withS3Object(
S3Object()
.withBucket("bucket")
.withName(name)
)
// Search collection for faces similar to the largest face in the image.
val searchFacesByImageRequest = SearchFacesByImageRequest()
.withCollectionId("face-collection-staging")
.withImage(image)
.withFaceMatchThreshold(70f)
.withMaxFaces(2)
val searchFacesByImageResult =
rekognitionClient.searchFacesByImage(searchFacesByImageRequest)
System.out.println("Face matching faceId"+faceId)
val faceImageMatches =
searchFacesByImageResult.faceMatches
for (face in faceImageMatches) {
println(
objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(face)
)
println()
}
Try adding the below dependency -
compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1' in your gradle file.
you need to exclude also that is because you are getting exception of duplicate class
dependencies {
compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1'
compile (group: 'org.apache.httpcomponents' , name: 'httpmime' , version: '4.3.5') {
exclude module: 'org.apache.httpcomponents:httpclient'}
}
I suggest to use the AWS Java SDK V2. It will allow you to use an alternate HTTP runtime, and avoid some of the mess with the Apache client, when working on Android.
GitHub Issue #1180 in the AWS Java SDK V2 repo addresses this topic.
In your module-level build.gradle, add dependencies:
dependencies {
implementation 'software.amazon.awssdk:sqs:2.13.49'
implementation 'software.amazon.awssdk:url-connection-client:2.13.49'
}
Now, initialize the Rekognition client:
val rekognition = RekognitionClient.builder()
.httpClient(UrlConnectionHttpClient.create())
.credentialsProvider(yourCredentials())
.region(Region.US_EAST_1)
.build()
I am struggling to let a task only execute when a specific value is defined.
I'm using Gradle 3.5.
task signJar(type: SignJar, dependsOn: reobfJar) {
onlyIf {
project.hasProperty('mod_keystore')
}
keyStore = project.keyStore
alias = project.keyStoreAlias
storePass = project.keyStorePass
keyPass = project.keyStoreKeyPass
inputFile = jar.archivePath
outputFile = jar.archivePath
}
As you can see, I already tried the onlyIf statement, but the task still runs. This results into a crash:
Could not get unknown property 'keyStore' for root project 'JustAnotherEnergy' of type org.gradle.api.Project.
The property 'mod_keystore' is no where defined, but the code get's executed.
task signJar(type: SignJar, dependsOn: reobfJar) {
if(project.hasProperty('mod_keystore')) {
keyStore = project.keyStore
alias = project.keyStoreAlias
storePass = project.keyStorePass
keyPass = project.keyStoreKeyPass
inputFile = jar.archivePath
outputFile = jar.archivePath
}
}
This works. The code does not get executed, but I'm running into other problems:
If the property 'mod_keystore' is not defined, Gradle can't set a value for the for example 'keyStore' property, but the task SignJar requires this values to be set.
This means this task should only be executed when the property 'mod_keystore' is defined. If it is not defined, the task should be skipped.
As you can see, I already tried the onlyIf statement, but the task still runs.
No, the task does not run. You need to distinguish between the configuration phase and the execution phase. The task closure, where you are setting your task properties, is executed during the configuration phase, right after the task is created. Only task actions (defined by the task type) and closures added via doFirst or doLast are executed during the execution phase.
If you disable or skip a task via onlyIf or enabled, you only disable / skip the execution (phase) of the task, not its configuration (phase).
As a solution for your specific problem, you can rely on your first approach with the onlyIf condition, but add a fail-safe way to access your project properties:
task signJar(type: SignJar, dependsOn: reobfJar) {
onlyIf {
hasProperty('mod_keystore')
}
keyStore = findProperty('keyStore')
alias = findProperty('keyStoreAlias')
storePass = findProperty('keyStorePass')
keyPass = findProperty('keyStoreKeyPass')
inputFile = jar.archivePath
outputFile = jar.archivePath
}
I am attempting to create a layer for my project. I would like the layer to contain
myProject/controllers/MainApp and all of its dependencies that are in the myProject
package. I do not want to include any dojo, dijit or otherPackages in my layer.
This is what I have so far:
var profile = (function() {
var locationPrefix = "something";
return {
basePath: "../src",
releaseDir: "../dojoRelease",
releaseName: "lib",
action: "release",
packages: [
{
name: 'dojo',
location: locationPrefix + '/dojo/dojo'
}, {
name: 'dijit',
location: locationPrefix + '/dojo/dijit'
}, {
...
}, {
name: 'myProject',
location: 'myProject',
destLocation: 'myProject'
}
],
layers: {
"myProject": {
include: ["myProject/controllers/MainApp"],
// QUESTION: How can I use exclude to not include all dojo modules?
// tried several things but none seem to work. Can't find any doc
// on what exclude takes as input.
// exclude: ["dojo/dojo"],
boot: false,
customBase: true
}
}
};
})();
The problem is that when I look at my main.js.uncompressed.js it contins lots of things that are not
in myProject. These are the first few lines in the main.js.uncompressed.js file:
require({cache:{
'dojo/parser':function(){
define([
"require", "./_base/kernel", "./_base/lang", "./_base/array", "./_base/config", "./dom", "./_base/window",
"./_base/url", "./aspect", "./promise/all", "./date/stamp", "./Deferred", "./has", "./query", "./on", "./ready"
], function(require, dojo, dlang, darray, config, dom, dwindow, _Url, aspect, all, dates, Deferred, has, query, don, ready){
// module:
// dojo/parser
new Date("X"); // workaround for #11279, new Date("") == NaN
// data-dojo-props etc. is not restricted to JSON, it can be any javascript
function myEval(text){
return eval("(" + text + ")");
}
The source for:
dijit/_Widget
dojo/Stateful
dijit/Destroyable
dijit/_OnDijitClickMixin
dijit/a11yclick
and many other files also show up in the main.js.uncompressed.js file.
How can I limit the main.js.uncompressed.js file to be only the files
in my project? Thanks!
Update: I tried removing dojo, dijit, etc from the list of packages. This causes the main.js.uncompressed.js to generate more or less correctly, the compiler then hangs on generating the minified file. There are also many errors like this:
error(311) Missing dependency. module: myProject/controllers/someFile; dependency: dojo/_base/declare
error(311) Missing dependency. module: myProject/controllers/someFile; dependency: dojo/_base/lang
error(311) Missing dependency. module: myProject/controllers/someFile; dependency: dojo/Deferred
The problem is that when I look at my main.js.uncompressed.js it
contins lots of things that are not in myProject.
They might not be in myProject but are you sure you're not making use of any of them anywhere? For example in the output you include it shows that someFile is using dojo/_base/declare function. If you're using declare at the start of your someFile module then you'll need dojo in the layer to be able to run it.
error(311) Missing dependency. module: myProject/controllers/someFile; dependency: dojo/_base/declare
error(311) Missing dependency. module: myProject/controllers/someFile; dependency: dojo/_base/lang
error(311) Missing dependency. module: myProject/controllers/someFile; dependency: dojo/Deferred
Can't find any doc on what exclude takes as input.
It's the same format as the include - an array of string modules - see here:
http://dojotoolkit.org/documentation/tutorials/1.10/build/
http://dojotoolkit.org/reference-guide/1.10/build/
Using the boot property will also included some dojo code in your layer as you're telling the builder to make your layer bootable so it has to include the dojo code for module loading to let you load youre other modules.
I have multiple test suites configured (as shown below) in my gradle build
task group1(type: Test) {
useTestNG() {
includeGroups 'group1'
}
// ... some excluded tests
ext.useDefaultListeners = true
ext.workingDirectory = 'build/'
// ... some system properties required by this test
}
task group2(type: Test, dependsOn: group1) {
useTestNG() {
includeGroups 'group2'
}
// ... some excluded tests
ext.useDefaultListeners = true
ext.workingDirectory = 'build/'
// ... some system properties required by this test
}
test.dependsOn group2
When I run the gradle clean build --debug, I could see after every test task (group1, group2 etc), gradle deletes the test report and regenerates it. Hence, after the build is done, whatever report I get does not have any information. All blank!
How can I get a combined report?
Thanks,
NN
You should use a separate task of type TestReport
Check out section '23.12.7. Test reporting' in the user guide