Kotlin - System.getProperty cannot resolve command line argument - spring

I have some code to load application.properties dynamically:
fun loadDefaultProperties(): Properties {
val configPath = System.getProperty("spring.config.location")
val resource = FileSystemResource(configPath)
return PropertiesLoaderUtils.loadProperties(resource)
}
But when I run the command...
java -jar my.jar -Dspring.config.location=my/location/application.properties
...System.getProperty("spring.config.location") returns null, and therefore, I get an IllegalArgumentException because the path is null.
Why am I unable to read the argument from the command line?

You're passing them in the wrong sequence. Pass them like:
java "-Dspring.config.location=my/location/application.properties" -jar my.jar
Otherwise they are program arguments. I've just tested it, and on MacOS, both the above as well as
java -Dspring.config.location=my/location/application.properties -jar my.jar
(without quotes) work.

Don't you need quotes?
java -jar my.jar -Dspring.config.location="my/location/application.properties"

Related

how to escape star in bash variable used for program arguments

I have a variable that has program arguments to my java command with the classpath to include all jars in a directory, but I am not able to escape the asterisk correctly so keep getting main class not found error.
Here are few examples. lib/ contains all my jars. test.Main contains main() class.
Inline works as expected:
java -classpath lib/* test.Main
However, all these attempts failed:
# 1)
PRARGS="-classpath lib/*" test.Main
java $PARGS
# 2)
PRARGS="-classpath lib/*" test.Main
java "$PARGS"
# 3)
PRARGS="-classpath lib/\*" test.Main
java $PARGS
# 4)
PRARGS="-classpath lib/\*" test.Main
java "$PARGS"
An alternative to escaping star is to disable path expansion.
Try this:
PRARGS="-classpath lib/* test.Main"
set -o noglob
java $PRARGS
set +o noglob

Variable not working in shell script

I have a source code :
#!/bin/bash
CLASSPATH=Test/bin/
java -cp ${CLASSPATH} "test.shell.com.RunTest"
That code return the error with content as bellow : Error: main class test.shell.com.RunTest could not be found or could not be loaded
But when I change it to :
#!/bin/bash
java -cp Test/bin/ "test.shell.com.RunTest"
It return the correct result of RunTest class.
I try change CLASSPATH to other name but it still error. Please help.

Pass command line arguments to gradle

To start Java program, I can pass arguments like:
java Main arg1 arg2 arg3
What are the good ways to do that in gradle command line:
gradle startProgram arg1 arg2 arg3
And this is in build.gradle:
task startProgram(dependsOn: 'classes', type: JavaExec) {
main = 'Main'
classpath = sourceSets.main.runtimeClasspath
systemProperties = System.properties
}
Best way is to use java system properties (-D switch) but these are more 'global'. Instead You can use simple properties (-P switch) and get the passed values using instance of Project class.

Hadoop command line -D options not working

I am trying to pass a variable (not property) using -D command line option in hadoop like -Dmapred.mapper.mystring=somexyz. I am able to set a conf property in Driver program and read it back in mapper.
So I can use this to pass my string as additional parameter and set it in Driver. But I want to see if -D option can be used to do the same
My command is:
$HADOOP_HOME/bin/hadoop jar /home/hduser/Hadoop_learning_path/toolgrep.jar /home/hduser/hadoopData/inputdir/ /home/hduser/hadoopData/grepoutput -Dmapred.mapper.mystring=somexyz
Driver program
String s_ptrn=conf.get("mapred.mapper.regex");
System.out.println("debug: in Tool Class mapred.mapper.regex "+s_ptrn + "\n");
Gives NULL
BUT this works
conf.set("DUMMYVAL","100000000000000000000000000000000000000"); in driver is read properly in mapper by get method.
My question is if all of Internet is saying i can use -D option then why cant i? is it that this cannot be used for any argument and only for properties? whihc we can read by putitng in file that i should read in driver program then use it?
Something like
Configuration conf = new Configuration();
conf.addResource("~/conf.xml");
in driver program and this is the only way.
As Thomas wrote, you are missing the space. You are also passing variable mapred.mapper.mystring in your CLI, but in the code you are trying to get mapred.mapper.regex. If you want to use -D parameter, you should be using Tool interface. More about it is here - Hadoop: Implementing the Tool interface for MapReduce driver.
Or you can parse your CLI arguments like this:
#Override
public int run(String[] args) throws Exception {
Configuration conf = this.getConf();
String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();
while (i<otherArgs.length) {
if (otherArgs[i].equals("-x")) {
//Save your CLI argument
yourVariable = otherArgs[++i];
}
//then save yourVariable into conf for using in map phase
Than your command can be like this:
$HADOOP_HOME/bin/hadoop jar /home/hduser/Hadoop_learning_path/toolgrep.jar /home/hduser/hadoopData/inputdir/ /home/hduser/hadoopData/grepoutput -x yourVariable
Hope it helps
To use -D option with hadoop jar command correctly, given below syntax should be used:
hadoop jar {hadoop-jar-file-path} {job-main-class} -D {generic options} {input-directory} {output-directory}
Hence -D option should be placed after job main class name i.e at third position. Because when we issue hadoop jar command then, hadoop scripts invokes RunJar class main(). This main () parses first argument to set Job Jar file in classpath and uses second argument to invoke job class main().
Once Job class main () is called then control is transferred to GenericOptionsParser which first parses generic command line arguments (if any) and sets them in Job's configuration object and then calls Job class' run () with remaining arguments (i.e input and output path)

How can I get $ not escaped in application default jvm args for gradle?

Using the application task I am specifying:
applicationDefaultJvmArgs = ['$DEBUG_OPTS',
'-Djava.library.path=${ZMQ_LIB_PATH}']
In the generated start scripts I see:
DEFAULT_JVM_OPTS='"\$DEBUG_OPTS" "-Djava.library.path=\${ZMQ_LIB_PATH}"'
I don't want the \$ in there. I tried using '$$DEBUG_OPTS' and also '\$DEBUG_OPTS' but got the same result. What is the right way to escape the $ so it ends up in the script without a backslash in front of it?
I had a similar issue, trying to add a commandline parameter $1 in there. With some googling came up with this solution, fixing the script after the fact.
applicationDefaultJvmArgs=['-Dmy.property=DOLLARONE']
...
startScripts{
doLast{
def bashFile = new File(getOutputDir(),applicationName)
String bashContent = bashFile.text
bashFile.text = bashContent.replaceFirst('DOLLARONE', Matcher.quoteReplacement('$1'))
}
}
The StartScriptGenerator code implies that '$' will be unconditionally replaced by the '\$'.
I assume that your intention is to use '$' character for shell parameters extension but I would like to point out that such usage (if permitted by the gradle task that generates the scripts) is not interoperable between bash and bat scripts - in the bash it will be used for shell parameters extension but in the bat it will have no meaning.
For Kotlin build script the solution could look like:
tasks.named<CreateStartScripts>("startScripts") {
doLast {
unixScript.writeText(unixScript.readText().replace("{{APP_HOME}}", "\${APP_HOME}"))
windowsScript.writeText(windowsScript.readText().replace("{{APP_HOME}}", "%APP_HOME%"))
}
}

Resources