I have a .Jar file that will just load data into database when it's run. I have scheduled to run this job via Jenkins. When I execute the job in Jenkins it runs the .JAR successfully. However say if there is a null pointer exception in the job and it did not complete successfully. Even then Jenkins says that job has "Passed". How do I fail the job if there is an issue during the job execution?
#Corey's solution is good. And if you don't want to write a JUnit test and support it in Jenkins, you can just do what he alluded to earlier: catch the null-pointer exception (really, just have a top-level catch in your app), and call the API to exit with a return code:
try {
myCode.call();
catch (Exception e) {
System.out.println("An exception was caught at the top level:" + e);
System.exit(-1);
}
Last time I had this problem, I decided to take a different tack and changed the program call into a junit test. Jenkins was quite happy then.
Steps I took:
1. create an empty (maven) project
2. added a single java class SmokeTest.java
3. Added test that called the method I was testing via a script
4. Create a (maven) Jenkins job to run the project
Contents of my test:
public class SmokeTest
{
private static final String OK = "OK"; //$NON-NLS-1$
#Test
public void test()
{
// Create a new instance of the Firefox driver
final WebDriver driver = new HtmlUnitDriver();
final String url = PropertyManager.getInstance().getString(PropertyManager.SMOKE_TEST_URL_BASE) + "smoke/smoketest"; //$NON-NLS-1$
AuditLog.registerEvent("Smoke test url is: " + url, this.getClass(), AuditLog.INFO); //$NON-NLS-1$
driver.get(url);
// Find the text element by its id
final WebElement databaseElement = driver.findElement(By.id("database")); //$NON-NLS-1$
final String databaseResult = databaseElement.getText();
Assert.assertEquals(SmokeTest.OK, databaseResult);
//Close the browser
driver.quit();
}
}
The most important part here is the "Assert.assertEquals" line. The result of this is pickup by jUnit and therefore jenkins
Jenkins jobs fails if the exit code is anything but zero.
System.exit(1);
Should work (or fail, to be more precise :-)
Related
I want to see the exceptions on console. I am using TestNG with Maven as a build tool. I have defined my testng.xml in the Maven surefire plugin.
https://www.javadoc.io/doc/org.testng/testng/latest/org/testng/reporters/VerboseReporter.html
you should use above reporter , but the constructor expects a string so you cannot initialize it using testng.xml ( if any one knows how to pass string argument to listener in testng.xml please do add it here )
So the work around is to add the listener through script and initiate testng through a java entry file.
public static void main(String[] args) {
TestNG testng = new TestNG();
// Create a list of String
List<String> suitefiles = new ArrayList<String>();
// Add xml file which you have to execute
suitefiles.add(prop.getProperty("path_to_your_existing_testngxml\testng.xml"));
// now set xml file for execution
testng.setTestSuites(suitefiles);
testng.addListener(new VerboseReporter("[TestNG] "));
// finally execute the runner using run method
testng.run();
}
Output:
Note
As this reporter constructor expects a string you should not provide it in your testng.xml you will get initialization error
If you use any kind of logging framework you should probably stick with that.
Otherwise you can always print Exceptions using https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Throwable.html#printStackTrace() (and siblings) such as
...
} catch (Exception e) {
e.printStackTrace(System.out);
e.printStackTrace(System.err);
}
...
I was exploring the Virtual Threads in Project Loom. The Documents say it as straight forward with simple lines of code as below:
Thread.startVirtualThread(() -> {
System.out.println("Hello, Loom!");
});
Or
Thread t = Thread.builder().virtual().task(() -> { ... }).start();
I have tried both of them, For the first one, I receive an error
The method startVirtualThread(() -> {}) is undefined for the type Thread
And for the second one
- The method builder() is undefined for the type Thread
One browsing, found that lombok is required, Installed lombok as well. However it doesn't show up in Eclipse About section, I am able to use lombok, But still my issue is not resolved.
Below link show the documentation, I am referring to.
enter link description here
Sample Code:
public class threads {
public void simpleThread() {
Thread start = Thread.builder().virtual().task(() -> {
System.out.println("Hello World");
}).start();
Thread.startVirtualThread(() -> {
System.out.println("Hello, Loom!");
});
}
public static void main(String[] args) {
// TODO Auto-generated method stub
threads trd = new threads();
trd.simpleThread();
}
}
It looks like older versions of Eclipse is giving a compilation error when calling the new Thread methods related to Loom.
Please try to use the latest Eclipse (currently 2020-09) with an OpenJDK Project Loom Early-Access Build.
You can make sure that this is an Eclipse related issue by compiling and running your program directly from the command line (using javac and java commands).
For ubuntu system:
Set the java 16 path in .bashrc file. Make sure only have java 16 path present in the file. If any other java path is mentioned then following command may not work.
If you want to confirm if the java version is set to 16 then execute java -version.
Then you can try directly compile your loom class through following command.
javac className.java
java className
It worked for me.
Even when you get the compilation problems go away, this might or might not print anything.
A virtual thread needs a carrier (a native thread to be executed on); and if the native thread finishes earlier then the virtual one starts, there is no such carrier; thus you get no printing. There are a couple of ways to work around that.
The simplest (just to see that this works), is to make the carrier threads sleep for a short while:
Thread.startVirtualThread(() -> {
while (true) {
System.out.println("trying " + Thread.currentThread().getName());
}
});
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));
On my machine this gives enough time for some output to be generated.
Another way would be join on the carrier:
Thread t = Thread.startVirtualThread(() -> {
System.out.println("trying " + Thread.currentThread().getName());
});
t.join();
This works for demo purposes, but in real life you probably need an executor. One way to supply it would be via :
Thread.builder()
.virtual(Executors.newFixedThreadPool(1))
.task(() -> {
System.out.println("started");
})
.build()
.start();
System.out.println("done");
You can even use Executors::newVirtualThreadExecutor where the current documentation states:
Creates an Executor that starts a new virtual thread for each task
So what you could do, is something like:
ExecutorService service = Executors.newVirtualThreadExecutor();
service.execute(() -> {
System.out.println(Thread.currentThread().getId());
});
service.execute(() -> {
System.out.println(Thread.currentThread().getId());
});
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));
I have a project in NetBeans that starts with a main function, that takes arguments. When I hit the "Stop" Button, the project continues running, but there is no output anymore.
Currently I have to remember to manually stop the process from the console.
How can I modify my project, maven setup or NetBeans configuration to make the process halt when I hit stop.
I can live with the process not having its finalizers or ShutdownHooks called.
Consider this class:
public class Main {
public static void main(String[] args) {
System.out.println("args: " + Arrays.asList(args));
new Main().action();
}
private void action() {
Date start = new Date();
long endTime = start.getTime() + 600000;
Date end;
do {
synchronized (Thread.currentThread()) {
try {
Thread.currentThread().wait(1000);
System.out.println("PING");
} catch (InterruptedException iex) {
return;
}
}
end = new Date();
} while (end.getTime() < endTime);
}
}
I want it to die using only NetBeans Stop button.
When you hit "Stop" in the NetBeans output, NB stops the maven process, but maven had spawned the actual program output, so the stop command is not handed over to your program.
NetBeans calls the exec-maven-plugin with the 'exec' goal by default. If you change it to the 'java' goal there is no new process. After the change below, the 'Run' section in your projects 'Properties' will be empty and of no use. I did not test what happens if you call 'System.exit' or similar in this scenario.
Also note, that you have to take care that you modify the version number here by yourself from now on.
You have to go to Projects window, right click your project, go to the Properties and select the Actions element and the the Run project entry. It will look like this:
You have to modify
Execute Goals: to process-classes org.codehaus.mojo:exec-maven-plugin:1.2.1:java (change the exec in the end to java).
Set Properties: to
exec.mainClass=de.steamnet.stopfromnetbeans.Main
exec.classpath=%classpath
exec.args=First Second 'Third Space'
So that it looks like this:
From now on, Maven will not fork a new process, so when you hit "Stop" it will actually Stop the process.
I create project in Intellij Idea, add tess4j 2.0 from maven, write test application. When I start debug all works fine. When I click "build artifacts" and launch jar file I haven't any result, no errors, nothing.
public class MainApp {
static String fileName = "C:\\Users\\Alex\\Google Drive\\TW\\LIB\\Tess4J\\eurotext.png";
public static void main(String[] args) {
try {
System.setOut(new PrintStream(new File("output-file.txt")));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Start");
ITesseract instance = new Tesseract1(); // JNA Direct Mapping
try {
String result = instance.doOCR(new File(fileName));
System.out.println(result);
} catch (TesseractException e) {
System.out.println("Error");
System.out.println(e.getMessage());
e.printStackTrace();
}
System.out.println("End");
}
}
Output when debug
Start
The (quick) [brown] {fox} jumps!
Over the $43,456.78 #90 dog
& duck/goose, as 12.5% of E-mail.........
End
Output when launch jar
Start
No "Error", no "End". How it's possible?
I had the same issue. Sometimes it doesn't load classes correctly for some reason. here's how i was able to get it fixed for some far.
Build your artifact and then Remote debug your jar with intellij.
Find out in which line your application breaks.
Then wrap it with try{... line where application breaks..} catch(Error e){e.getMessage(); }
You can see the error message in variable "e" in debug output. So you can determine the issue.
May be this is not an appropriate way to do it. But this is how i was able to track down the errors in my jar file.
How ever it is best to use this as a temporary way to track the errors in your jar and to find out why it breaks and then find out correct way (Which is i'm not currently aware about.. but however got to heard about some library called One-Jar) to build jar without getting any errors on deployment.
Background:
I am currently working on a project in eclipse that programatically executes JUnit tests that are pushed to a server.
So far everything works but I would like to know the results of the tests (specifically any failures) so I can push them out to an email. Right now the tests just output to the console but that doesn't seem to give me much output to actually use.
Right now I use the Runtime class to call the tests but that doesn't seem to have the functionality I need for getting results.
I have looked into the JUnitCore class but can't call any tests outside of the current java project.
So my main question would be how can I use JUnitCore to run junit tests in a specific JAR file? Or is there an easier way to approach this problem using a different class?
This is the only thing I've been able to get to work:
RunTests()
{
junitCore = new JUnitCore();
junitCore.run(AllTests.class);
}
But I would like to do something along the lines of this:
RunTests()
{
junitCore = new JUnitCore();
junitCore.run("C:\\$batch\\test\\hil research\\201507071307\\CommsTestRunner\\plugins\\TestSuite\\US35644.class");
}
I would appreciate any suggestions to this problem I am having. I'm an EE and was just introduced to java last month so this has been quite the challenge for me.
JUnitCore expects to read loaded classes, not class files in a JAR. Your real question is likely how to load the JAR (or directory of .class files) so it can be run.
Poke around with URLClassLoader; once you've amended the classpath appropriately, you can get a Class out of findClass and pass it into the JUnitCore methods you've found.
Since the tests might have classes that are also used by your server (but not necessarily at the same version) I would suggest not having your server directly run the tests. Instead, you can have your server start a new JVM that runs the tests. This is how IDEs like Eclipse run tests. You simply need to write a main class that has JUnit run the tests, and serializes the results on disk.
Your main class would look something like this:
public class MyRunner {
public static void main(String... args) throws IOException {
String path = System.getProperty("resultPath");
if (path == null) {
throw new NullPointerException("must specify resultPath property");
}
// Possibly install a security manager to prevent calls to System.exit()
Result result = new JUnitCore().runMain(new RealSystem(), args);
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path)) {
out.writeObject(result);
}
System.exit(result.wasSuccessful() ? 0 : 1);
}
}
Then your server simply needs to construct a java command line with the jars that include the tests, the JUnit jar file, and a jar that contains MyRunner.