How to start Vert.x server from IntelliJ IDEA? - java

How do I start a simple Vert.x server from inside IntelliJ IDEA?
My build.gradle is as below:
apply plugin: 'java'
version = '3.0.0'
repositories {
mavenCentral()
}
dependencies {
compile 'io.vertx:vertx-core:3.0.0'
}
My Vertx-server, MyVertex.java is as below:
package com.example;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
public class MyVerticle extends AbstractVerticle {
#Override
public void start(Future<Void> fut) {
vertx.createHttpServer()
.requestHandler(r -> r.response().end("<h1>Hello</h1>"))
.listen(8081);
}
}
And my IntelliJ run configuration is as below, with io.vertx.core.Starteras main class:
But when I run it with my run configuration I get this error message:
Error: Could not find or load main class run
Is the VM option (in Run configuration) run something I need to install and add to my path or how do I get started with Vert.x-server development?

I'm using vertx 3.2.1 and it's complaining about io.vertx.core.Starter. It's deprecated now. So, one should use io.vertx.core.Launcher.
This is an example of launching via intellij with the option of specifying a config JSON file:
Main Class: io.vertx.core.Launcher
VM Options: <up to you, or leave blank>
Program Arguments: run com.app.verticle.MyVerticle -conf /path/to/my_config.json
When using a logging framework it will be added in VM Options as below.
Log4j with either log4j or slf4j delgate:
-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.Log4jLogDelegateFactory -Dlog4j.configuration=log4j.xml
-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory -Dlog4j.configuration=log4j.xml
Logback:
-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory -Dlogback.configurationFile=logback.xml

Simply add this to your MyVerticle (or a separate class):
import io.vertx.core.Launcher;
...
public static void main(final String[] args) {
Launcher.executeCommand("run", MyVerticle.class.getName());
}
Then simply Ctrl+Shift+F10 to run it and IntelliJ will automatically create the Run Configuration.

Ah, my mistake:
run com.example.MyVerticle should be the value of Program arguments: and not as VM options in the IntelliJ IDEA Run configuration.

You can simply add a main and use deployVerticle() and then from there in IntelliJ you can Run or Debug it easily.
With deployVerticle, you can pass a new instance of your main/bootstrap verticle or you can pass yourMainVerticle.class
public class VertxVerticleMain {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new MyVerticle());
//vertx.deployVerticle(MyVerticle.class);
}
}

You have to use this: org.vertx.java.platform.impl.cli.Starter as your Main Class in IntelliJ IDEA; and if you are using arguments and things like that you might want to use something like: runmod <groupId>~<artifactId>~<version> [-conf src/main/resources/your_config.json -cp]
Have a look at this project.
For Vert.x 3.0.0 you have to use this: io.vertx.core.Starter as your Main Class and run com.example.other.AnyVerticle as your Program arguments.

Related

Using JUnit Hooks with Cucumber CLI Runner

I'm trying to run Cucumber's feature files in parallel using Cucumber's CLI Runner and I'm currently stuck trying to figure out how to make JUnit #BeforeClass hook to work with the CLI Runner.
At the moment, my working Runner class looks like this:
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = {
"pretty",
"html:target/reports/basic/report.html",
"json:target/reports/cluecumber/cucumber.json",
"timeline:target/reports/timeline"
},
tags = "#RegressionTests",
snippets = SnippetType.CAMELCASE,
stepNotifications = true,
features = "classpath:features",
glue = "my.steps.package")
public class RegressionTestsIT {
#BeforeClass
public static void setup() {
ContextHolder.setupTestContext();
}
}
And my CLI command looks like this:
java -cp "target/test-jar-with-dependencies.jar" io.cucumber.core.cli.Main -p "pretty" -p "html:target/reports/basic/report.html" -p "json:target/reports/cluecumber/cucumber.json" -p "timeline:target/reports/timeline" --threads 10 -g "my.steps.package" target/test-classes/features
What happens is that I get a NullPointerException at the tests because TestContext was not properly set up as the hook was not executed.
I tried to include both the Runner's package and the Runner class itself as glue and it didn't work.
Also tried to make my Runner extend io.cucumber.core.cli.Main and then execute my Runner in the CLI and not surprisingly it did not work either, sadly still getting NPE.
Although this issue is related to the CLI Runner use, I'm content with any answer that might help me run multiple feature files in parallel whatever the method.
Using JUnit Rules
Cucumber supports JUnit's #ClassRule, #BeforeClass, and #AfterClass annotations. These will be executed before and after all scenarios. Using these is not recommended as it limits portability between different runners; they may not execute correctly when using the command line, IntelliJ IDEA, or Cucumber-Eclipse. Instead it is recommended to use Cucumber's hooks.
When using the CLI, JUnit is not involved at all so you can not use any of JUnit annotations. However since Cucumber v7 you can use #BeforeAll and #AfterAll to declare methods that executed before and after all scenarios.
package io.cucumber.example;
import io.cucumber.java.AfterAll;
import io.cucumber.java.BeforeAll;
public class StepDefinitions {
#BeforeAll
public static void beforeAll() {
// Runs before all scenarios
}
#AfterAll
public static void afterAll() {
// Runs after all scenarios
}
}
JUnit #BeforeClass didn't work for me. Since I'm kinda in a hurry with this, I didn't bother keep on trying to make it work. I don't really need to run the command in a pipeline at the moment, so I was completely fine in running it on IntelliJ as long as it was running in parallel.
My solution was creating a custom CLI Runner that runs the context configuration before Cucumber's CLI run method.
public class CLIRunner {
public static void main(String[] args) {
ContextHolder.setupTestContext();
io.cucumber.core.cli.Main.run(
new String[] {
"-p", "pretty",
"-p", "html:target/reports/basic/report.html",
"-p", "json:target/reports/cluecumber/cucumber.json",
"-p", "timeline:target/reports/timeline",
"-g", "my.steps.package",
"classpath:features",
"--threads", "10"
}, Thread.currentThread().getContextClassLoader());
}
}

Write Unit Test In Different Package Calling Private/Protected Methods Using Intellij

I realize this question has been asked before here -> How to create a test directory in Intellij 13?
However, the answer is not working for me and I can't figure out why...
Intellij Version:
IntelliJ IDEA 2016.1.4
Build #IC-145.2070, built on August 2, 2016
JRE: 1.8.0_77-b03 x86
JVM: Java HotSpot(TM) Server VM by Oracle Corporation
MyApp.java
package main.java.com.simpleproject;
public class MyApp {
private int updNum;
public MyApp(int givenNum){
this.updNum = givenNum;
}
private void updateNumPlusTwo(){
this.updNum += 2;
}
protected int getUpdatedNum(){
return this.updNum;
}
}
MyAppTest.java
package test.java.com.simpleproject;
import main.java.com.simpleproject.MyApp;
public class MyAppTest {
public static void main(String[] args) {
MyApp app = new MyApp(4);
app.getUpdatedNum();
app.updateNumPlusTwo();
}
}
The package/directory tree:
The Issue:
What I have tried:
Anyone have any idea how to get this to work?
Your sources directories and packages are wrong.
You have chosen the Maven default sources directories structure of src/main/java for production code, and src/test/java for test code. You should declare both directories as source folders in IntelliJ (Project Structure -> Modules -> select the folders and click on Sources for src/main/java and Tests for src/test/java)
Your packages should be the same: com.simpleproject. The problem is that you have declared 2 different packages (main.java.com.simpleproject and test.java.com.simpleproject) that's why you cannot call a protected method.
It is not possible to call a private method, from the same or different package. You have to use reflection for that. But preferably you should at least put your method protected or package default.
Your test should use JUnit, not a main method. Something like :
package com.simpleproject;
import static org.assertj.core.api.Assertions.assertThat;
public class Test {
#Test
public void shouldTestMyClass() {
// Given
int givenNum = 3;
// When
MyApp myApp = new MyApp(givenNum);
myApp.updateNumPlusTwo();
// Then (use AssertJ library for example)
assertThat(myApp.getUpdatedNum()).isEqualTo(5);
}
}

Spring Dependency Injection example project does not have a main class. How can I run it?

Consider this code GitHub: Spring Pattern Example Code
If you checkout Chapter3 - Dependency Injection, the project does not have any main class in it.
I did a
mvn clean install
which was successful.
When I go to execute the jar, I get the below error:
bash-3.2$ java -jar
./target/Chapter-03-Spring-Dependency-Injection-0.0.1-SNAPSHOT.jar
no
main manifest attribute, in
./target/Chapter-03-Spring-Dependency-Injection-0.0.1-SNAPSHOT.jar
How can I run this project? Should I edit the build portion of pom to build as spring-boot? Should I manually add a MANIFEST file?
Its not a complete application that you could run, so you must type some lines to see what's going on , here is what you could do to run examples :
import project into your IDE as maven project
create Main class with famous static main
if you want to instantiate the config with xml style you could do it as follow
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
TransferService bean = context.getBean(TransferService.class);
bean.transferAmmount(10l, 10l, new Amount(1000d));
}
}
Another approach is to use config file :
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
TransferService bean = context.getBean(TransferService.class);
bean.transferAmmount(10l, 10l, new Amount(1000d));
}
}
run the project as java application

How to run ajc from Java?

I'm trying to run ajc compiler from Java (not from Maven or Ant!). The question is which Maven dependency do I need and which class is an entry point? The best option I have now is org.aspectj.tools.ajc.Main from org.aspectj:aspectjtools:1.7.2. Am I right?
Yes. In your Java project you need aspectjrt.jar (for the runtime) and aspectjtools.jar (for the compiler) on the class path. Then you can build an AspectJ project and create a JAR file containing aspects and classes like this:
import org.aspectj.tools.ajc.Main;
public class AjcRunner {
public static void main(String[] args) throws Exception {
String[] ajcArgs = {
"-sourceroots", "c:\\my\\aspectj_project\\src",
"-outjar", "my_aspects.jar"
};
Main.main(ajcArgs);
}
}
Afterwards you can test the result on the console like this, assuming you have a class Application with a main method:
java -cp C:\path\to\aspectjrt.jar;my_aspects.jar Application

Logging in custom ant tasks

I'm creating a custom ant task, which performs an IO tasks based on the user received param(like an file write/append)
I wanted to write the task so as if the developer using it in the ant task runs it with a -v or -d flag, will output more,
I'm wondering how are the core ant tasks doing it. Are they checking the output level before printing to console or is it just done by using java.util.logging.Logger
Follow this tutorial.
Extract :
Integration with TaskAdapter
Our class has nothing to do with Ant. It extends no superclass and
implements no interface. How does Ant know to integrate? Via name
convention: our class provides a method with signature public void
execute(). This class is wrapped by Ant's
org.apache.tools.ant.TaskAdapter which is a task and uses reflection
for setting a reference to the project and calling the execute()
method.
Setting a reference to the project? Could be interesting. The Project
class gives us some nice abilities: access to Ant's logging facilities
getting and setting properties and much more. So we try to use that
class:
import org.apache.tools.ant.Project;
public class HelloWorld {
private Project project;
public void setProject(Project proj) {
project = proj;
}
public void execute() {
String message = project.getProperty("ant.project.name");
project.log("Here is project '" + message + "'.", Project.MSG_INFO);
} }
[...]

Categories