Flyway - oracle PL/SQL procedures migration - java

What would be the preferable way to update schema_version table and execute modified PL/SQL packages/procedures in flyway without code duplication?
My example would require a class file be created for each PL/SQL code modicaition
public class V2_1__update_scripts extends AbstractMigration {
// update package and procedures
}
AbstractMigration class executes the files in db/update folder:
public abstract class AbstractMigration implements SpringJdbcMigration {
private static final Logger log = LoggerFactory.getLogger(AbstractMigration.class);
#Override
public void migrate(JdbcTemplate jdbcTemplate) throws Exception {
Resource packageFolder = new ClassPathResource("db/update");
Collection<File> files = FileUtils.listFiles(packageFolder.getFile(), new String[]{"sql"}, true);
for (File file : files ) {
log.info("Executing [{}]", file.getAbsolutePath());
String fileContents = FileUtils.readFileToString(file);
jdbcTemplate.execute(fileContents);
}
}
}
Is there any better way of executing PL/SQL code?

I wonder if it's better to duplicate the code into the standard migrations folder. It seems like with the given example you wouldn't then be able to migrate up to version N of the db, as some prior version would execute all the current version of the pl/sql. I'd be interested to see if you settled on a solution for this.

There is no built-in support or other command you have missed.
Of the top of my head, I would think about either the way you presented here or using a generator to produce new migration sql files after an SCM commit.
Let's see if someone else found a better solution.

The version of Flyway current at the time of this writing (v4.2.0) supports the notion of repeatable scripts designed specifically for such situations. Basically any script with a "Create or replace" semantic is a candidate.
Simply name your script as R__mypackage_body.sql or whatever prefix you wish for repeatable scripts. Please see Sql-based migrations and Repeatable migrations for further information.

Related

Getting a specific version of an image with Jib (Maven, Docker, testcontainers)

I'm trying to understand a comment that a colleague made. We're using testcontainers to create a fixture:
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
public class SalesforceFixture extends GenericContainer<SalesforceFixture> {
private static final String APPLICATION_NAME = "salesforce-emulator";
public SalesforceFixture() {
// super(ImageResolver.resolve(APPLICATION_NAME));
super(DockerImageName.parse("gcr.io/ad-selfserve/salesforce-emulator:latest"));
...
}
...
The commented code is what it used to be. The next line is my colleague's suggestion. And on that line he commented:
This is the part I don't know. The [ImageResolver] gets the specific version of the emulator, rather than the latest. You need a docker-info file for that though, which jib doesn't automatically generate (but I think it can).
This is what I know or have figured so far:
SalesforceFixture is a class that will be used by other projects to write tests. It spins up a container in Docker, running a service that emulates the real service's API. It's like a local version of the service that behaves enough like the real thing that if one writes code and tests using the fixture, it should work the same in production. (This is where my knowledge ends.)
I looked into ImageResolver—it seems to be a class we wrote that searches a filesystem for something:
public static String resolve(String applicationName, File... roots) {
Stream<File> searchPaths = Arrays.stream(roots).flatMap((value) -> {
return Stream.of(new File(value, "../" + applicationName), new File(value, applicationName));
});
Optional<File> buildFile = searchPaths.flatMap((searchFile) -> {
if (searchFile.exists()) {
File imageFile = new File(searchFile + File.separator + "/target/docker/image-name");
if (imageFile.exists()) {
return Stream.of(imageFile);
}
}
return Stream.empty();
}).findAny();
InputStream build = (InputStream)buildFile.map(ImageResolver::fileStream).orElseGet(() -> {
return searchClasspath(applicationName);
});
if (build != null) {
try {
return IOUtils.toString(build, Charset.defaultCharset()).trim();
} catch (IOException var6) {
throw new RuntimeException("An exception has occurred while reading build file", var6);
}
} else {
throw new RuntimeException("Could not resolve target image for application: " + applicationName);
}
}
But I'm confused. What filesystem? Like, what is the present working directory? My local computer, wherever I ran the Java program from? Or is this from within some container? (I don't think so.) Or maybe the directory structure inside a .jar file? Or somewhere in gcr.io?
What does he mean about a "specific version number" vs. "latest"? I mean, when I build this project, whatever it built is all I have. Isn't that equivalent to "latest"? In what case would an older version of an image be present? (That's what made me think of gcr.io.)
Or, does he mean, that in the project using this project's image, one will not be able to specify a version via Maven/pom.xml—it will always spin up the latest.
Sorry this is long, just trying to "show my work." Any hints welcome. I'll keep looking.
I can't comment on specifics of your own internal implementations, but ImageResolver seems to work on your local filesystem, e.g. it looks into your target/ directory and also touches the classpath. I can imagine this code was just written for resolving an actual image name (not an image), since it also returns a String.
Regarding latest, using a latest tag for a Docker image is generally considered an anti-pattern, so likely your colleague is commenting about this. Here is a random article from the web explaining some of the issues with latest tag:
https://vsupalov.com/docker-latest-tag/
Besides, I don't understand why you ask these questions which are very specific to your project here on SO rather than asking your colleague.

How should I approach for creating a command-line parser in java? [duplicate]

What is a good way of parsing command line arguments in Java?
Check these out:
http://commons.apache.org/cli/
http://www.martiansoftware.com/jsap/
Or roll your own:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
For instance, this is how you use commons-cli to parse 2 string arguments:
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) throws Exception {
Options options = new Options();
Option input = new Option("i", "input", true, "input file path");
input.setRequired(true);
options.addOption(input);
Option output = new Option("o", "output", true, "output file");
output.setRequired(true);
options.addOption(output);
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd = null;//not a good practice, it serves it purpose
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp("utility-name", options);
System.exit(1);
}
String inputFilePath = cmd.getOptionValue("input");
String outputFilePath = cmd.getOptionValue("output");
System.out.println(inputFilePath);
System.out.println(outputFilePath);
}
}
usage from command line:
$> java -jar target/my-utility.jar -i asd
Missing required option: o
usage: utility-name
-i,--input <arg> input file path
-o,--output <arg> output file
Take a look at the more recent JCommander.
I created it. I’m happy to receive questions or feature requests.
I have been trying to maintain a list of Java CLI parsers.
Airline
Active Fork: https://github.com/rvesse/airline
argparse4j
argparser
args4j
clajr
cli-parser
CmdLn
Commandline
DocOpt.java
dolphin getopt
DPML CLI (Jakarta Commons CLI2 fork)
Dr. Matthias Laux
Jakarta Commons CLI
jargo
jargp
jargs
java-getopt
jbock
JCLAP
jcmdline
jcommander
jcommando
jewelcli (written by me)
JOpt simple
jsap
naturalcli
Object Mentor CLI article (more about refactoring and TDD)
parse-cmd
ritopt
Rop
TE-Code Command
picocli has ANSI colorized usage help and autocomplete
It is 2022, time to do better than Commons CLI... :-)
Should you build your own Java command line parser, or use a library?
Many small utility-like applications probably roll their own command line parsing to avoid the additional external dependency. picocli may be an interesting alternative.
Picocli is a modern library and framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It lives in 1 source file so apps can include it as source to avoid adding a dependency.
It supports colors, autocompletion, subcommands, and more. Written in Java, usable from Groovy, Kotlin, Scala, etc.
Features:
Annotation based: declarative, avoids duplication and expresses programmer intent
Convenient: parse user input and run your business logic with one line of code
Strongly typed everything - command line options as well as positional parameters
POSIX clustered short options (<command> -xvfInputFile as well as <command> -x -v -f InputFile)
Fine-grained control: an arity model that allows a minimum, maximum and variable number of parameters, e.g, "1..*", "3..5"
Subcommands (can be nested to arbitrary depth)
Feature-rich: composable arg groups, splitting quoted args, repeatable subcommands, and many more
User-friendly: usage help message uses colors to contrast important elements like option names from the rest of the usage help to reduce the cognitive load on the user
Distribute your app as a GraalVM native image
Works with Java 5 and higher
Extensive and meticulous documentation
The usage help message is easy to customize with annotations (without programming). For example:
(source)
I couldn't resist adding one more screenshot to show what usage help messages are possible. Usage help is the face of your application, so be creative and have fun!
Disclaimer: I created picocli. Feedback or questions very welcome.
Someone pointed me to args4j lately which is annotation based. I really like it!
I've used JOpt and found it quite handy: http://jopt-simple.sourceforge.net/
The front page also provides a list of about 8 alternative libraries, check them out and pick the one that most suits your needs.
I know most people here are going to find 10 million reasons why they dislike my way, but nevermind. I like to keep things simple, so I just separate the key from the value using a '=' and store them in a HashMap like this:
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
String[] parts = arg.split("=");
argsMap.put(parts[0], parts[1]);
}
You could always maintain a list with the arguments you are expecting, to help the user in case he forgot an argument or used a wrong one... However, if you want too many features this solution is not for you anyway.
This is Google's command line parsing library open-sourced as part of the Bazel project. Personally I think it's the best one out there, and far easier than Apache CLI.
https://github.com/pcj/google-options
Installation
Bazel
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)
Gradle
dependencies {
compile 'com.github.pcj:google-options:1.0.0'
}
Maven
<dependency>
<groupId>com.github.pcj</groupId>
<artifactId>google-options</artifactId>
<version>1.0.0</version>
</dependency>
Usage
Create a class that extends OptionsBase and defines your #Option(s).
package example;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
import java.util.List;
/**
* Command-line options definition for example server.
*/
public class ServerOptions extends OptionsBase {
#Option(
name = "help",
abbrev = 'h',
help = "Prints usage info.",
defaultValue = "true"
)
public boolean help;
#Option(
name = "host",
abbrev = 'o',
help = "The server host.",
category = "startup",
defaultValue = ""
)
public String host;
#Option(
name = "port",
abbrev = 'p',
help = "The server port.",
category = "startup",
defaultValue = "8080"
)
public int port;
#Option(
name = "dir",
abbrev = 'd',
help = "Name of directory to serve static files.",
category = "startup",
allowMultiple = true,
defaultValue = ""
)
public List<String> dirs;
}
Parse the arguments and use them.
package example;
import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;
public class Server {
public static void main(String[] args) {
OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
parser.parseAndExitUponError(args);
ServerOptions options = parser.getOptions(ServerOptions.class);
if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
printUsage(parser);
return;
}
System.out.format("Starting server at %s:%d...\n", options.host, options.port);
for (String dirname : options.dirs) {
System.out.format("\\--> Serving static files at <%s>\n", dirname);
}
}
private static void printUsage(OptionsParser parser) {
System.out.println("Usage: java -jar server.jar OPTIONS");
System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
OptionsParser.HelpVerbosity.LONG));
}
}
https://github.com/pcj/google-options
Take a look at the Commons CLI project, lots of good stuff in there.
Yeap.
I think you're looking for something like this:
http://commons.apache.org/cli
The Apache Commons CLI library provides an API for processing command line interfaces.
If you are already using Spring Boot, argument parsing comes out of the box.
If you want to run something after startup, implement the ApplicationRunner interface:
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(ApplicationArguments args) {
args.containsOption("my-flag-option"); // test if --my-flag-option was set
args.getOptionValues("my-option"); // returns values of --my-option=value1 --my-option=value2
args.getOptionNames(); // returns a list of all available options
// do something with your args
}
}
Your run method will be invoked after the context has started up successfully.
If you need access to the arguments before you fire up your application context, you can just simply parse the application arguments manually:
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
ApplicationArguments arguments = new DefaultApplicationArguments(args);
// do whatever you like with your arguments
// see above ...
SpringApplication.run(Application.class, args);
}
}
And finally, if you need access to your arguments in a bean, just inject the ApplicationArguments:
#Component
public class MyBean {
#Autowired
private ApplicationArguments arguments;
// ...
}
Maybe these
JArgs command line option parsing
suite for Java - this tiny project provides a convenient, compact, pre-packaged and comprehensively documented suite of command line option parsers for the use of Java programmers. Initially, parsing compatible with GNU-style 'getopt' is provided.
ritopt, The Ultimate Options Parser for Java - Although, several command line option standards have been preposed, ritopt follows the conventions prescribed in the opt package.
I wrote another one: http://argparse4j.sourceforge.net/
Argparse4j is a command line argument parser library for Java, based on Python's argparse.
If you are familiar with gnu getopt, there is a Java port at: http://www.urbanophile.com/arenn/hacking/download.htm.
There appears to be a some classes that do this:
http://docs.sun.com/source/816-5618-10/netscape/ldap/util/GetOpt.html
http://xml.apache.org/xalan-j/apidocs/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.html
airline # Github looks good. It is based on annotation and is trying to emulate Git command line structures.
Argparse4j is best I have found. It mimics Python's argparse libary which is very convenient and powerful.
I want to show you my implementation: ReadyCLI
Advantages:
for lazy programmers: a very small number of classes to learn, just see the two small examples on the README in the repository and you are already at 90% of learning; just start coding your CLI/Parser without any other knowledge;
ReadyCLI allows coding CLIs in the most natural way;
it is designed with Developer Experience in mind; it largely uses the Builder design pattern and functional interfaces for Lambda Expressions, to allow a very quick coding;
it supports Options, Flags and Sub-Commands;
it allows to parse arguments from command-line and to build more complex and interactive CLIs;
a CLI can be started on Standard I/O just as easily as on any other I/O interface, such as sockets;
it gives great support for documentation of commands.
I developed this project as I needed new features (options, flag, sub-commands) and that could be used in the simplest possible way in my projects.
If you want something lightweight (jar size ~ 20 kb) and simple to use, you can try argument-parser. It can be used in most of the use cases, supports specifying arrays in the argument and has no dependency on any other library. It works for Java 1.5 or above. Below excerpt shows an example on how to use it:
public static void main(String[] args) {
String usage = "--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
InputData inputData = (InputData) argParser.parse(args);
showData(inputData);
new StatsGenerator().generateStats(inputData);
}
More examples can be found here
As one of the comments mentioned earlier (https://github.com/pcj/google-options) would be a good choice to start with.
One thing I want to add-on is:
1) If you run into some parser reflection error, please try use a newer version of the guava. in my case:
maven_jar(
name = "com_google_guava_guava",
artifact = "com.google.guava:guava:19.0",
server = "maven2_server",
)
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
server = "maven2_server",
)
maven_server(
name = "maven2_server",
url = "http://central.maven.org/maven2/",
)
2) When running the commandline:
bazel run path/to/your:project -- --var1 something --var2 something -v something
3) When you need the usage help, just type:
bazel run path/to/your:project -- --help
Take a look at Spring Shell
Spring Shell’s features include
A simple, annotation driven, programming model to contribute custom commands
Use of Spring Boot auto-configuration functionality as the basis for a command plugin strategy
Tab completion, colorization, and script execution
Customization of command prompt, shell history file name, handling of results and errors
Dynamic enablement of commands based on domain specific criteria
Integration with the bean validation API
Already built-in commands, such as clear screen, gorgeous help, exit
ASCII art Tables, with formatting, alignment, fancy borders, etc.
For Spring users, we should mention also https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html and his twin brother https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/JOptCommandLinePropertySource.html (JOpt implementation of the same functionality).
The advantage in Spring is that you can directly bind the command line arguments to attributes, there is an example here https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/CommandLinePropertySource.html

How to access version of my project in build.gradle from a Java class

I'm quite new to Gradle so the answer might be simple, so I apologize if the answer is simple: I have a testing tool that needs to fetch it's version and compare it to the version of the application it is testing. However , the version of my tool is in my build.graddle as
version '1.0'
I tried different way to access it ( such as) :
task generateSources {
File outDir
outDir = file("$buildDir/classes/test/tests/Version.java")
doFirst {
outDir.exists() || outDir.mkdirs()
new File(outDir).write("public class Version { public static final String VERSION = \"$project.version\"; }")
}
}
compileJava.dependsOn generateSources
compileJava.source generateSources.outputs.files, sourceSets.main.java
I found this piece of code to output the version to another java file, but I fail to see how I'd be able to retrieve that info afterwards ( I mean, my tests are defined in src and I would need to point to a file that doesn't exist at compilation -- correct me if I'm wrong here).
Any idea on how I could accomplish this task?
First of all, you are trying to create java source file in your build/classes (it should contain compiled classes, not sources) directory, but you have to do it in your sources, otherwise it won't be compiled. And if you need this new class to be vailable not for tests, then use src/main/java, not src/test/java/
But anyway, I suppose for your case it's much easier to use some properties file for that and replace some token within it during build. That will allow you to make some static logic to get this property value and use it yet before running the build. So all you need is:
1- to have some properties file in your resources src/main/resources (for example app.properties), where should version variable be stored, with it's value like APP_VERSION_TOKEN
version=%APP_VERSION_TOKEN%
2- configure you Gradle processResources to replace tokens, something like this:
processResources {
filesMatching('**/app.properties') {
filter {
it.replace('%APP_VERSION_TOKEN%', version)
}
}
}
3- make some method to read this file and return the value of the property and use it where you need.
And that's all. For unit tests you can have another file with the same name under src/test/resource with the unchanging value you need for testing.

java jar arguments for swing application [duplicate]

What is a good way of parsing command line arguments in Java?
Check these out:
http://commons.apache.org/cli/
http://www.martiansoftware.com/jsap/
Or roll your own:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
For instance, this is how you use commons-cli to parse 2 string arguments:
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) throws Exception {
Options options = new Options();
Option input = new Option("i", "input", true, "input file path");
input.setRequired(true);
options.addOption(input);
Option output = new Option("o", "output", true, "output file");
output.setRequired(true);
options.addOption(output);
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd = null;//not a good practice, it serves it purpose
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp("utility-name", options);
System.exit(1);
}
String inputFilePath = cmd.getOptionValue("input");
String outputFilePath = cmd.getOptionValue("output");
System.out.println(inputFilePath);
System.out.println(outputFilePath);
}
}
usage from command line:
$> java -jar target/my-utility.jar -i asd
Missing required option: o
usage: utility-name
-i,--input <arg> input file path
-o,--output <arg> output file
Take a look at the more recent JCommander.
I created it. I’m happy to receive questions or feature requests.
I have been trying to maintain a list of Java CLI parsers.
Airline
Active Fork: https://github.com/rvesse/airline
argparse4j
argparser
args4j
clajr
cli-parser
CmdLn
Commandline
DocOpt.java
dolphin getopt
DPML CLI (Jakarta Commons CLI2 fork)
Dr. Matthias Laux
Jakarta Commons CLI
jargo
jargp
jargs
java-getopt
jbock
JCLAP
jcmdline
jcommander
jcommando
jewelcli (written by me)
JOpt simple
jsap
naturalcli
Object Mentor CLI article (more about refactoring and TDD)
parse-cmd
ritopt
Rop
TE-Code Command
picocli has ANSI colorized usage help and autocomplete
It is 2022, time to do better than Commons CLI... :-)
Should you build your own Java command line parser, or use a library?
Many small utility-like applications probably roll their own command line parsing to avoid the additional external dependency. picocli may be an interesting alternative.
Picocli is a modern library and framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It lives in 1 source file so apps can include it as source to avoid adding a dependency.
It supports colors, autocompletion, subcommands, and more. Written in Java, usable from Groovy, Kotlin, Scala, etc.
Features:
Annotation based: declarative, avoids duplication and expresses programmer intent
Convenient: parse user input and run your business logic with one line of code
Strongly typed everything - command line options as well as positional parameters
POSIX clustered short options (<command> -xvfInputFile as well as <command> -x -v -f InputFile)
Fine-grained control: an arity model that allows a minimum, maximum and variable number of parameters, e.g, "1..*", "3..5"
Subcommands (can be nested to arbitrary depth)
Feature-rich: composable arg groups, splitting quoted args, repeatable subcommands, and many more
User-friendly: usage help message uses colors to contrast important elements like option names from the rest of the usage help to reduce the cognitive load on the user
Distribute your app as a GraalVM native image
Works with Java 5 and higher
Extensive and meticulous documentation
The usage help message is easy to customize with annotations (without programming). For example:
(source)
I couldn't resist adding one more screenshot to show what usage help messages are possible. Usage help is the face of your application, so be creative and have fun!
Disclaimer: I created picocli. Feedback or questions very welcome.
Someone pointed me to args4j lately which is annotation based. I really like it!
I've used JOpt and found it quite handy: http://jopt-simple.sourceforge.net/
The front page also provides a list of about 8 alternative libraries, check them out and pick the one that most suits your needs.
I know most people here are going to find 10 million reasons why they dislike my way, but nevermind. I like to keep things simple, so I just separate the key from the value using a '=' and store them in a HashMap like this:
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
String[] parts = arg.split("=");
argsMap.put(parts[0], parts[1]);
}
You could always maintain a list with the arguments you are expecting, to help the user in case he forgot an argument or used a wrong one... However, if you want too many features this solution is not for you anyway.
This is Google's command line parsing library open-sourced as part of the Bazel project. Personally I think it's the best one out there, and far easier than Apache CLI.
https://github.com/pcj/google-options
Installation
Bazel
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)
Gradle
dependencies {
compile 'com.github.pcj:google-options:1.0.0'
}
Maven
<dependency>
<groupId>com.github.pcj</groupId>
<artifactId>google-options</artifactId>
<version>1.0.0</version>
</dependency>
Usage
Create a class that extends OptionsBase and defines your #Option(s).
package example;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
import java.util.List;
/**
* Command-line options definition for example server.
*/
public class ServerOptions extends OptionsBase {
#Option(
name = "help",
abbrev = 'h',
help = "Prints usage info.",
defaultValue = "true"
)
public boolean help;
#Option(
name = "host",
abbrev = 'o',
help = "The server host.",
category = "startup",
defaultValue = ""
)
public String host;
#Option(
name = "port",
abbrev = 'p',
help = "The server port.",
category = "startup",
defaultValue = "8080"
)
public int port;
#Option(
name = "dir",
abbrev = 'd',
help = "Name of directory to serve static files.",
category = "startup",
allowMultiple = true,
defaultValue = ""
)
public List<String> dirs;
}
Parse the arguments and use them.
package example;
import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;
public class Server {
public static void main(String[] args) {
OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
parser.parseAndExitUponError(args);
ServerOptions options = parser.getOptions(ServerOptions.class);
if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
printUsage(parser);
return;
}
System.out.format("Starting server at %s:%d...\n", options.host, options.port);
for (String dirname : options.dirs) {
System.out.format("\\--> Serving static files at <%s>\n", dirname);
}
}
private static void printUsage(OptionsParser parser) {
System.out.println("Usage: java -jar server.jar OPTIONS");
System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
OptionsParser.HelpVerbosity.LONG));
}
}
https://github.com/pcj/google-options
Take a look at the Commons CLI project, lots of good stuff in there.
Yeap.
I think you're looking for something like this:
http://commons.apache.org/cli
The Apache Commons CLI library provides an API for processing command line interfaces.
If you are already using Spring Boot, argument parsing comes out of the box.
If you want to run something after startup, implement the ApplicationRunner interface:
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(ApplicationArguments args) {
args.containsOption("my-flag-option"); // test if --my-flag-option was set
args.getOptionValues("my-option"); // returns values of --my-option=value1 --my-option=value2
args.getOptionNames(); // returns a list of all available options
// do something with your args
}
}
Your run method will be invoked after the context has started up successfully.
If you need access to the arguments before you fire up your application context, you can just simply parse the application arguments manually:
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
ApplicationArguments arguments = new DefaultApplicationArguments(args);
// do whatever you like with your arguments
// see above ...
SpringApplication.run(Application.class, args);
}
}
And finally, if you need access to your arguments in a bean, just inject the ApplicationArguments:
#Component
public class MyBean {
#Autowired
private ApplicationArguments arguments;
// ...
}
Maybe these
JArgs command line option parsing
suite for Java - this tiny project provides a convenient, compact, pre-packaged and comprehensively documented suite of command line option parsers for the use of Java programmers. Initially, parsing compatible with GNU-style 'getopt' is provided.
ritopt, The Ultimate Options Parser for Java - Although, several command line option standards have been preposed, ritopt follows the conventions prescribed in the opt package.
I wrote another one: http://argparse4j.sourceforge.net/
Argparse4j is a command line argument parser library for Java, based on Python's argparse.
If you are familiar with gnu getopt, there is a Java port at: http://www.urbanophile.com/arenn/hacking/download.htm.
There appears to be a some classes that do this:
http://docs.sun.com/source/816-5618-10/netscape/ldap/util/GetOpt.html
http://xml.apache.org/xalan-j/apidocs/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.html
airline # Github looks good. It is based on annotation and is trying to emulate Git command line structures.
Argparse4j is best I have found. It mimics Python's argparse libary which is very convenient and powerful.
I want to show you my implementation: ReadyCLI
Advantages:
for lazy programmers: a very small number of classes to learn, just see the two small examples on the README in the repository and you are already at 90% of learning; just start coding your CLI/Parser without any other knowledge;
ReadyCLI allows coding CLIs in the most natural way;
it is designed with Developer Experience in mind; it largely uses the Builder design pattern and functional interfaces for Lambda Expressions, to allow a very quick coding;
it supports Options, Flags and Sub-Commands;
it allows to parse arguments from command-line and to build more complex and interactive CLIs;
a CLI can be started on Standard I/O just as easily as on any other I/O interface, such as sockets;
it gives great support for documentation of commands.
I developed this project as I needed new features (options, flag, sub-commands) and that could be used in the simplest possible way in my projects.
If you want something lightweight (jar size ~ 20 kb) and simple to use, you can try argument-parser. It can be used in most of the use cases, supports specifying arrays in the argument and has no dependency on any other library. It works for Java 1.5 or above. Below excerpt shows an example on how to use it:
public static void main(String[] args) {
String usage = "--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
InputData inputData = (InputData) argParser.parse(args);
showData(inputData);
new StatsGenerator().generateStats(inputData);
}
More examples can be found here
As one of the comments mentioned earlier (https://github.com/pcj/google-options) would be a good choice to start with.
One thing I want to add-on is:
1) If you run into some parser reflection error, please try use a newer version of the guava. in my case:
maven_jar(
name = "com_google_guava_guava",
artifact = "com.google.guava:guava:19.0",
server = "maven2_server",
)
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
server = "maven2_server",
)
maven_server(
name = "maven2_server",
url = "http://central.maven.org/maven2/",
)
2) When running the commandline:
bazel run path/to/your:project -- --var1 something --var2 something -v something
3) When you need the usage help, just type:
bazel run path/to/your:project -- --help
Take a look at Spring Shell
Spring Shell’s features include
A simple, annotation driven, programming model to contribute custom commands
Use of Spring Boot auto-configuration functionality as the basis for a command plugin strategy
Tab completion, colorization, and script execution
Customization of command prompt, shell history file name, handling of results and errors
Dynamic enablement of commands based on domain specific criteria
Integration with the bean validation API
Already built-in commands, such as clear screen, gorgeous help, exit
ASCII art Tables, with formatting, alignment, fancy borders, etc.
For Spring users, we should mention also https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html and his twin brother https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/JOptCommandLinePropertySource.html (JOpt implementation of the same functionality).
The advantage in Spring is that you can directly bind the command line arguments to attributes, there is an example here https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/CommandLinePropertySource.html

TestNG - WebDriver - Web apps Testing - Independent Tests

How to handle DB inside of your script using TestNG framework?
How to delete DB before each run of test script?
How to load sql file into clean DB before running test script?
Goal: Each test case must be independent
Framework: TestNG
Language: Java
Each test case must be independent against other test cases. Goal is to run Test cases randomly, no order is required.
Previously I have used PHPUnit framework where each test case was independent.
Before running each test script, I would:
dropdatabase
create a new database
load sql file into database with initial data
I was using this inside of shell script, and I would call shell script via command line:
mysql -u$DB_USER -p$DB_PWD -h$HOST -e "DROP DATABASE $DB_NAME"
mysql -u$DB_USER -p$DB_PWD -h$HOST -e "CREATE DATABASE $DB_NAME"
mysql -u$DB_USER -p$DB_PWD -h$HOST $DB_NAME < sql/dbinit.sql
Google-ing was not helpfull, therefore I am posting question here. I would need something like this for TestNG but I have not found anything similiar.
Could someone give advice to fellow QA.
How do you handle with oracle database, how do you delete data from the DB and load them inside of your test script?
Any advice, book, tutorial would be very helpfull.
You should look into DbUnit. I've recently started using it myself (I'm a TestNG user) and, as of yet, I haven't come across scenarios where you absolutely need JUnit itself. You can restore your database between tests, populate it, export it, etc ...
http://dbunit.sourceforge.net/
basic example:
private DatabaseHelper dbh;
private EntityManager em;
private IDatabaseConnection connection;
private IDataSet dataset;
#BeforeClass
private void setupDatabaseResource() throws Exception {
// using JPA and a custom helper class
em = dbh.getEntityManager();
connection = new DatabaseConnection(((SessionImpl) (em.getDelegate())).connection());
connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory());
// full database export
IDataSet fullDataSet = connection.createDataSet();
FlatXmlDataSet.write(fullDataSet, new FileOutputStream("target/generated-sources/test-dataset.xml"));
FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder();
flatXmlDataSetBuilder.setColumnSensing(true);
// keep the dataset in memory, for later restore points
dataset = flatXmlDataSetBuilder.build(new FileInputStream("target/generated-sources/test-dataset.xml"));
}
edit: an example where #BeforeMethod restores your database between tests
#BeforeMethod
public void cleanDB() throws Exception {
DatabaseOperation.CLEAN_INSERT.execute(connection, dataset);
}

Categories

Resources