How to get command line arguments in Ceylon? - ceylon

In a command line Java application you can get arguments through the args parameter:
public static void main(String[] args) {
How can I do something similar in Ceylon? I tried copying the Java style:
shared void run(String[] args) {
but got an error since that is not allowed:
ceylon run: Cannot run toplevel method 'test.project.run':
it should have no parameters or they should all have default values.
I've been reading the ceylon-lang.org tour but I haven't found the answer.

Use the top-level process object in the language module.
String[] arguments = process.arguments;
String? argument = process.namedArgumentValue("name");
if (process.namedArgumentPresent("name")) {
// ...
}

Related

JsonParseException when trying to run spring boot

Using the following command:
java -jar target/spring-boot-config-0.0.1-SNAPSHOT.jar --spring.application.json='{"server":{"ip":"192.168.145.78"}}'
I get a org.springframework.boot.json.JsonParseException: Cannot parse JSON exception. I have no idea why, my command seems to be correct. Could anybody help me with this. My application is simple:
public class SpringBootConfigApplication {
private static Logger log = LoggerFactory.getLogger(SpringBootConfigApplication.class);
public static void main(String[] args) {
SpringApplication.run(SpringBootConfigApplication.class, args);
}
#Value("${server.ip}")
String serverIp;
#Bean
public CommandLineRunner values() {
return args -> {
log.info(" > The Server IP is: " + serverIp);
};
}
}
The full stacktrace is:
at org.springframework.boot.json.AbstractJsonParser.trimParse(AbstractJsonParser.java:48)
at org.springframework.boot.json.AbstractJsonParser.parseMap(AbstractJsonParser.java:36)
at org.springframework.boot.json.YamlJsonParser.parseMap(YamlJsonParser.java:46)
at org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor.processJson(SpringApplicationJsonEnvironmentPostProcessor.java:102)
at org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor.lambda$postProcessEnvironment$0(SpringApplicationJsonEnvironmentPostProcessor.java:97)
at java.base/java.util.Optional.ifPresent(Optional.java:176)
at org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor.postProcessEnvironment(SpringApplicationJsonEnvironmentPostProcessor.java:97)
at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:102)
at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:87)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:82)
at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:63)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:62)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:374)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:332)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332)
at be.brzyktom.springbootconfig.SpringBootConfigApplication.main(SpringBootConfigApplication.java:16)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Use double quotations in outer string and escape them when defining keys and values
java -jar target/spring-boot-config-0.0.1-SNAPSHOT.jar --spring.application.json="{\"server\":{\"ip\":\"192.168.145.78\"}}"

How pass body variable as a parameter to custom Exception

I'm struggling to understand how passing a variable stored in the body as a parameter of throwException.
This is my code:
.when(simple("${body[errorCode]} contains '101'"))
.throwException(new IllegalArgumentException(
"Action not allowed- Error code:" + ${body[errorCode]))
.otherwise()
When I run the application the message passed to ErrorHandling is
'Action not allowed- Error code:${body[errorCode]', no replacing for errorCode variable.
Any suggestions? Tnks.
So you are using the Simple language in Java but you have some syntax issues. Nothing major. Your do not complete the delimiter of the Simple expression. Also you dont have to concatenate the string.
Change the code:
.throwException(new IllegalArgumentException("Action not allowed- Error code:" + ${body[errorCode]))
To:
.throwException(new IllegalArgumentException("Action not allowed- Error code: ${body[errorCode]}"))
I am on the buss and using my phone so can't check if the code runs but it should point you in the right direction.
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:start")
.to("mock:start")
**.throwException(IllegalArgumentException.class, "Darn ${body} is invalid")**
.to("mock:result");
}
};
}
See the unit tests of camel-core for an example
https://github.com/apache/camel/blob/master/camel-core/src/test/java/org/apache/camel/processor/ThrowExceptionMessageTest.java

GCP Dataflow pipeline no json rows being read/processed

Based on the WordCount Example, I am trying to read my own json data (instead of the shakespear txts).
I am running the pipeline with:
mvn compile exec:java -Dexec.mainClass=myPkg.myClass -Dexec.args=" \
--project=myProj \
--stagingLocation=gs://myBkt/stage \
--runner=BlockingDataflowPipelineRunner \
--output=gs://myBkt/output/out \
--defaultWorkerLogLevel=DEBUG"
the output from the console is as follows:
<date> com.google.cloud.dataflow.sdk.runners.DataflowPipelineRunner fromOptions
INFO: PipelineOptions.filesToStage was not specified. Defaulting to files from the classpath: will stage 68 files. Enable logging at DEBUG level to see which files will be staged.
<date> myPkg$GroupPublished apply
<date> myPkg$GroupPublished apply
INFO: GroupPublished/JsonToDatePosPlatKeyFn.out [PCollection]
<date> myPkg main
main
static void main(String[] args) {
...
Pipeline p = Pipeline.create(options);
p.apply(TextIO.Read.named("ReadJson").from(options.getInputFile()))
.apply(new GroupPublished())
.apply(ParDo.of(new FormatAsStringFn()))
.apply(TextIO.Write.named("WriteCounts").to(options.getOutput()));
}
GroupPublished transformation
static class GroupPublished extends PTransform<PCollection<String>,
PCollection<KV<DatePosPlatKey, Long>>> {
#Override
public PCollection<KV<DatePosPlatKey, Long>> apply(PCollection<String> lines) {
PCollection<DatePosPlatKey> keyList
= lines.apply(ParDo.of(new JsonToDatePosPlatKeyFn()));
PCollection<KV<DatePosPlatKey, Long>> keysCounted =
keyList.apply(Count.<DatePosPlatKey>perElement());
return keysCounted;
}
}
json row processing
static class JsonToDatePosPlatKeyFn extends DoFn<String, DatePosPlatKey>{
#Override
public void processElement(ProcessContext c) throws Exception {
JsonNode root = mapper.readTree(c.element());
for (JsonNode jsonFact : root) {
DatePosPlatKey key = new DatePosPlatKey(...construct...);
...manipulate...
c.output(key);
}
}
}
data class
#DefaultCoder(AvroCoder.class)
public static class DatePosPlatKey { ... }
stuff I've checked so far:
adding defaultWorkerLogLevel doesn't seem to make any difference to the console output
renaming the json file throws an error, so I know its been seen by TextIO
the json files have data in the format: {...}\n{...}\n...
no logging or dataflow job appears in the google cloud console
how can I better debug a complete lack of data?
can you see what I've done wrong?
Upon offline discussion it turned out the code was missing a call to p.run(), so the pipeline was only constructed but not executed.

How can we pass arguments to the main function in JAVA using command prompt and notepad?

Today, I was learning about passing arguments to the main function in JAVA , with no IDE , only on Notepad and I encountered that it can only be done using command line arguments . My question is how?
We can do this simply by opening the cmd ,
and writing the
javac file_name.java
java file_name [set of arguments]...
suppose the program is like
class temp
{
public static void main(String[] args)
{
System.out.println(args[0]);
System.out.println(args[1]);
//And so on
// As per the length of args
}
}
And if we pass
javac temp.java
java temp_name hello world
it will give output as
hello
world
The parameter for your main method should be something like String[] args, right? Its just an array of Strings. When you run your program from the commandline, the java executable looks at all the arguments passed in after the file name and appends them to the args variable.
For example, take this program that takes two arguments and sums them:
public class Adder
{
public static void main(String[] args)
{
int one = (int) args[0];
int two = (int) args[1];
System.out.println(one + two);
}
}
You'd call this by doing something like C:\> java Adder 15 23, and it would print out 38.
Notice that it reads them all as Strings, so you have to cast them to whatever variable type you need.

Passing command line arguments to JUnit in Eclipse

All,
I am currently using JUnit 4 for writing test cases. I am fairly new to JUnit and finding it difficult to test my main class which takes arguments. I have specified the arguments to my JUnit test class by:
1 > Right click JUnit test class
2 > Goto Run As -> Run Configurations
3 > Select the Arguments tab and specify a value (I have entered an invalid argument i.e. the main class expects the command line argument to be converted to an int and I am passing a String value that cannot be converted to int)
However, the main class that I am testing, if the command line argument cannot be converted to a int, than I throw IllegalArgumentException. However, the JUnit does not show the testMain() method as Error or Failure. I don't think my setup is right for the JUnit class. Can anyone please guide me where I am going wrong
To test your class main method simply write something like:
#Test(expected = IllegalArgumentException.class)
public void testMainWithBadCommandLine()
{
YourClass.main(new String[] { "NaN" });
}
Change the main() method to something like this:
public static void main(String[] args)
{
MyClass myclass = new MyClass(args);
myclass.go();
}
Move the code that was in main() to the new method go(). Now, your test method can do this:
public void myClassTest()
{
String[] args = new String[]{"one", "two"}; //for example
MyClass classUnderTest = new MyClass(testArgs);
classUnderTest.go();
}
Firstly the arguments should be in the program arguments section. Normally the launching point of the application that's the main method doesn't need to be tested if you design the app to be testable.
Refactor the class
public static class ArgumentValidator
{
public static boolean nullOrEmpty(String [] args)
{
if(args == null || args.length == 0)
{
throw new IllegalArgumentException(msg);
}
//other methods like numeric validations
}
}
You can now easily test the nullOrEmpty method using junit like
#Test(expected = IllegalArgumentException.class)
public void testBadArgs()
{
ArgumentValidator.nullOrEmpty(null);
}
I think this is a better approach