I thought this would be a very simple thing. So far however I'm unable to access the String for my gradle job's Java.Home, the official name:
For example, see: org.gradle.java.home
Apparently I can set this value with gradle.properties settings file. I've done that and the gradle output confirms this.
For all that, none of these print statements work...
print "org.gradle.java.home = $org.gradle.java.home"
print "org.gradle.java.home = "+ project.properties['org.gradle.java.home']
print "org.gradle.java.home = $gradle.java.home"
print "${project.property('org.gradle.java.home')}"
Looking at back at this question, I would have thought one of the options tried would yield a result.
How can I access system level properties?
Only two options may work:
print "org.gradle.java.home = "+ project.properties['org.gradle.java.home']
print "${project.property('org.gradle.java.home')}"
and the second will fail since there's no checking if such property exists. Gradle throws an exception on access to non-existing property.
The last two will not work because there's no property org and gradle objects has no java property - more explanation can be found here - you need to understand how string interpolation works with groovy.
And finally, these properties are used to pass arguments to gradle. So the following will work:
print "org.gradle.java.home = "+
project.properties['org.gradle.java.home']
run with:
gradle -Dorg.gradle.java.home=random_dir
With some trial-and-much-error, I have found that one may print the java.home property on Windows with Gradle 2.4; when ...
Use your gradle.properties file, e.g.
For example
compile.options.fork = true
org.gradle.daemon = true
org.gradle.java.home = b:/lang/java/jdk/v1.8u45
The same settings in GRADLE_OPTS had no effect. The print command used, is:
print "org.gradle.java.home = "+ "${project.property('org.gradle.java.home')}"
I believe the compile.options.fork is also required. It had no effect before when I was using GRADLE_OPTS. Although the Gradle message to use fork is quite clear on the matter.
see also:
- https://docs.gradle.org/2.4/userguide/gradle_daemon.html
Related
Executing the gradle application plugin's installDist task creates a directory build/install/my-application-name/bin that contains wrapper scripts, my-application-name and my-application-name.bat. Running either of these scripts runs the application, and arguments passed to these scripts are passed to the underlying application.
In UNIX shell scripts you can access the name that was used to execute the program as $0. In fact, the UNIX version of the gradle-generated startup script uses $0 several times.
How can I configure the gradle application plugin such that these scripts will pass the value of $0 (and whatever the Windows equivalent is on Windows) into the underlying application, perhaps as a Java system property?
Since parameter for obtaining the name of the script being run is referenced differently in Linux($0) and in Windows(%0), the most straightforward way to generate custom scripts would be to use separate custom templates for the respective start script generators:
startScripts {
unixStartScriptGenerator.template = resources.text.fromFile('unixStartScript.txt')
windowsStartScriptGenerator.template = resources.text.fromFile('windowsStartScript.txt')
}
The default templates are easy to obtain invoking e.g. unixStartScriptGenerator.template.asString()
Documentation on customizing the start scripts can be found here.
This is what I ended up doing, based on jihor's answer. I'm posting it here just so that there's a working answer for anyone else interested:
startScripts {
def gen = unixStartScriptGenerator
gen.template = resources.text.fromString(
gen.template.asString().replaceFirst('(?=\nDEFAULT_JVM_OPTS=.*?\n)') {
'\nJAVA_OPTS="\\$JAVA_OPTS "\'"-Dprogname=\\$0"\''
})
// TODO: do something similar for windowsStartScriptGenerator
}
This uses replaceFirst is instead of replace so we can match a pattern. This is a little less brittle, and also lets us use lookahead so we don't have to actually replace what we're looking for. (This is groovy's variant of replaceFirst that takes a closure, by the way. This requires far less escaping than the version that takes a replacement string in this case.)
Also, instead of:
JAVA_OPTS="$JAVA_OPTS -Dprogname=$0"
we actually need something like:
JAVA_OPTS="$JAVA_OPTS "'"-Dprogname=$0"'
This is because $0 may contains special character (like spaces), and the startup script removes one level of quoting in the value of $JAVA_OPTS using eval set --.
(If anyone knows how to make this work on Windows, pleas feel free to update this answer.)
I took an alternative approach. According to the documentation, as far back as Gradle 2.4 and all the way through Gradle 4.8, we should be able to set the following properties within the startScripts task:
applicationName
optsEnvironmentVar
exitEnvironmentVar
mainClassName
executableDir
defaultJvmOpts
appNameSystemProperty
appHomeRelativePath
classpath
Unfortunately, this is not true for the following properties, which seem to have never been exposed:
appNameSystemProperty
appHomeRelativePath
If appNameSystemProperty were exposed as the documentation describes, then we should be able to simply do the following:
startScripts {
applicationName = 'foo'
appNameSystemProperty = 'appName'
}
This would then result in the addition of -DappName=foo to the Java command constructed within both of the start scripts.
Since this is not the case, I took the following approach, which is a bit more verbose than the earlier solution to this question, but is perhaps less brittle because it does not rely on tweaking the out-of-box templates. Instead, it results in the documented behavior.
startScripts {
mainClassName = '...'
applicationName = 'foo'
unixStartScriptGenerator =
new CustomStartScriptGenerator(generator: unixStartScriptGenerator)
windowsStartScriptGenerator =
new CustomStartScriptGenerator(generator: windowsStartScriptGenerator)
}
class CustomStartScriptGenerator implements ScriptGenerator {
#Delegate
ScriptGenerator generator
void generateScript(JavaAppStartScriptGenerationDetails details,
Writer destination) {
details = new CustomDetails(details: details)
this.generator.generateScript(details, destination)
}
static class CustomDetails implements JavaAppStartScriptGenerationDetails {
#Delegate
JavaAppStartScriptGenerationDetails details
#Override
String getAppNameSystemProperty() { 'appName' }
}
}
My requirement is simple. At the beginning of each file there should be a block comment like this:
/*
* This file was last modified by {username} at {date} and has revision number {revisionnumber}
*/
I want to populate the {username}, {date} and {revisionnumber} with the appropriate content from SVN.
How can I achieve this with NetBeans and Subversion? I have searched a lot but I can't find exactly what I need.
I looked at this question and got some useful information. It is not exactly duplicate because I am working with NetBeans but the idea is the same. This is my header:
/*
* $LastChangedDate$
* $LastChangedRevision$
*/
Then I go to Team > Subversion > Svn properties and add svn:keywords as property name and LastChangedDate LastChangedRevision as property value.
And when I commit from NetBeans it looks like this:
/*
* $LastChangedDate: 2012-02-13 17:38:57 +0200 (Пн, 13 II 2012) $
* $LastChangedRevision: 27 $
*/
Thanks all for the support! I will accept my answer because other answers do not include the NetBeans information. Nevertheless I give +1 to the other answers.
As this data only exists after the file was committed it should be set by SVN itself, not a client program. (And client-side processing tends to get disabled or not configured at all.) This means there is no simple template/substitute like you want, because then after the first replacement the template variables would be lost.
You can find information abut SVN's keyword substitution here. Then things like $Rev$ can be replaced by $Rev: 12 $.
You can do this with The SubWCRev Program.
SubWCRev is Windows console program which can be used to read the
status of a Subversion working copy and optionally perform keyword
substitution in a template file. This is often used as part of the
build process as a means of incorporating working copy information
into the object you are building. Typically it might be used to
include the revision number in an “About” box.
This is typically done during the build process.
If you use Linux, you can find a Linux binary here. If you wish, you could also write your own using the output of svn log.
I followed Petar Minchev's suggestions, only I put the $LastChangedRevision$ tag not in a comment block but embedded it in a string. Now it is available to programmatically display the revision number in a Help -> About dialog.
String build = "$LastChangedRevision$";
I can later display the revision value in the about dialog using a String that has all of the fluff trimmed off.
String version = build.replace("$LastChangedRevision:", "").replace("$", "").trim();
I recommend a slightly different approach.
Put the following header at the top of your source files.
/*
* This file was last modified by {username} at {date} and has revision number {revisionnumber}
*/
Then add a shell script like this
post update, checkout script
USERNAME=# // use svnversion to get username
DATE=# // use svnversion to get revisio nnumber
sed -e "s#{username}#${USERNAME}#" -e "s#{date}#${DATE}#" ${SOURCE_CONTROL_FILE} > ${SOURCE_FILE}
pre commit script
cat standard_header.txt > ${SOURCE_CONTROL_FILE}
tail --lines $((${LENGTH}-4)) ${SOURCE_FILE} >> ${SOURCE_CONTROL_FILE}
I am trying to work with args4j. I created a dummy project that contains one single command line option called 'enableAuth'. See Features.java.
I tried to run this in eclipse with run configuration > program arguments as --enableAuth=true, -enableAuth=true, -enableAuth true etc., But none of them work for me. I run into CmdLineException always.
Any help is appreciated. Github project: https://github.com/seshumadhav/java-projects/tree/master/args4j-demo
For boolean fields I don't think we are suppose to give values(i.e. true/false). Just pass the argument as a flag
java XXX.java -enableAuth
If the field was non-boolean than it would have expected a value.
steps I do:
I do in code
System.setProperty("myproperty", 1);
and then I set in a shell script the property "myProperty" to 3.
like this:
# setprop "myproperty" 3
and then in the code I try to read the property like this:
System.getProperty("myproperty");
I get the value of 1. which means that the set from the shell didn't actually work.
but when I print all props from shell with
# getprop
I see in the list that myproperty equals 3.
in shorter words: I want to change the value of a property from a script, and I see that this scripts actually changes the property but in the java code I get the old value.
any ideas?
Java code in Android provides System.getProperty and System.setProperty functions in java library but it's important to note that although these java APIs are semantically equal to native version, java version store data in a totally different place. Actually, a hashtable is employed by dalvik VM to store properties. So, java properties are separated, it can't get or set native properties, and neither vice versa.
You can use android.os.SystemProperties class can manipulate native properties, though it's intended for internal usage only. It calls through jni into native property library to get/set properties.
getprop/setprop work on android.os.SystemProperties, not on java.lang.System.
Unfortunately, this class is not available to third party application. Apparently you have rooted your device, so you may still access it.
You can use that snippet to run getProp as shell command and get the value of any property:
private String getSystemProperty(String propertyName) {
String propertyValue = "[UNKNOWN]";
try {
Process getPropProcess = Runtime.getRuntime().exec("getprop " + propertyName);
BufferedReader osRes =
new BufferedReader(new InputStreamReader(getPropProcess.getInputStream()));
propertyValue = osRes.readLine();
osRes.close();
} catch (Exception e) {
// Do nothing - can't get property value
}
return propertyValue;
}
I've got a HDFS structure something like
a/b/file1.gz
a/b/file2.gz
a/c/file3.gz
a/c/file4.gz
I'm using the classic pattern of
FileInputFormat.addInputPaths(conf, args[0]);
to set my input path for a java map reduce job.
This works fine if I specify args[0] as a/b but it fails if I specify just a (my intention being to process all 4 files)
the error being
Exception in thread "main" java.io.IOException: Not a file: hdfs://host:9000/user/hadoop/a
How do I recursively add everything under a ?
I must be missing something simple...
As Eitan Illuz mentioned here, in Hadoop 2.4.0 a mapreduce.input.fileinputformat.input.dir.recursive configuration property was introduced that when set to true instructs the input format to include files recursively.
In Java code it looks like this:
Configuration conf = new Configuration();
conf.setBoolean("mapreduce.input.fileinputformat.input.dir.recursive", true);
Job job = Job.getInstance(conf);
// etc.
I've been using this new property and find that it works well.
EDIT: Better yet, use this new method on FileInputFormat that achieves the same result:
Job job = Job.getInstance();
FileInputFormat.setInputDirRecursive(job, true);
This is a bug in the current version of Hadoop. Here is the JIRA for the same. It's still in open state. Either make the changes in the code and build the binaries or wait for it to be fixed in the coming releases. Processing of the files recursively can be turned on/off, check the patch attached to the JIRA for more details.