Multiple java version usage in pipeline jobs - java

We have upgraded the ant jar files to 51 which needs to detect the java version11 but our old applications are still using the old jar file50 so we need to detect the java versions according to the pull request id. here we give PR id as parameter.
stage("abc"){
steps{
script{
if (PR_ID == '100')
tools{
jdk 'java11.0.5'
}
else
tools{
jdk 'java8'
fi
}
i am trying this way but getting error like java.lang.NoSuchMethodError: No such DSL method 'tools' found among steps [ArtifactoryGradleBuild, MavenDescriptorStep, addInteractivePromotion, archive, artifactoryDistributeBuild, artifactoryDownload, artifactoryEditProps.
Kindly help me on how can we use if else condition or any other condition to detect the java version according to the PR id.

A tools block is only allowed inside a pipeline block or stage block, not inside a script block.
What I would suggest is creating two different stages and using when to select the one to execute.
stage("abc-java11") {
when {
expression {
return PR_ID == '100'
}
}
tools {
jdk 'java11.0.5'
}
steps {
// Your steps
}
}
stage("abc-java8") {
when {
expression {
return PR_ID != '100'
}
}
tools {
jdk 'java8'
}
steps {
// Your steps
}
}

Related

Gradle Kotlin DSL - Cannot access 'verbose': it is private in 'CompileOptions'

I am trying to set the verbose flag/option to true in the gradle build script (Kotlin DSL).
Gradle throws error that this property is private and not accessible in Kotlin DSL. The same thing works in Groovy DSL though.
Groovy DSL (working)
plugins {
id("java")
}
tasks.named("compileJava") {
options.verbose = true
}
Kotlin DSL (not-working)
plugins {
id("java")
}
tasks.named<JavaCompile>("compileJava") {
options.verbose = true
}
Error
Script compilation error:
Line 32: options.verbose = true;
^ Cannot access 'verbose': it is private in 'CompileOptions'
1 error
I am sure I am missing something. Any help is appreciated. Thanks.
CompileOptions has a setter for verbose, so this will work
tasks.named<JavaCompile>("compileJava") {
options.setVerbose(true)
}
It is also possible to set the flag via property:
tasks.named<JavaCompile>("compileJava") {
options.isVerbose = true
}
Not sure why it is private for Kotlin DSL and not for Groovy DSL, but found an alternative using compilerArgs from this stackoverflow post
tasks.named<JavaCompile>("compileJava") {
val compilerArgs = options.compilerArgs
compilerArgs.add("-verbose")
}
This, to me, feels a bit low-level since we are directly updating the compiler arguments instead of using objects/maps to set them. Will wait for someone to post a better solution (if it exists).

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 do we properly create an execution phase tasks?

this is what the ideal build script I have:
I do want to execute tasks "unzip_natives_os" manually. But it seems it only works at config phase. And when I take a test run with this set-up it gives me an error: "java.lang.UnsatisfiedLinkError" but if I change the configuration from "nativesOS" into "runtimeOnly" inside of the dependencies block, it works fine. Do I have to explicitly create this "applicationDefaultJvmArgs" and insert the libraryPath of the natives. Is there any other way? And when I need to unzip the "nativesOS" config it needs an explicit version, it seems it did not see the platform/BOM?
// build.gradle.kts
val nativesOS : Configuration by configurations.creating {
this.isTransitive = false
this.extendsFrom(configurations.runtimeOnly.get())
}
dependencies {
implementation(platform("org.lwjgl:lwjgl-bom:3.2.3"))
listOf(
"", "-assimp", "-openal",
"-opengl", "-glfw"
).map { lib ->
implementation("org.lwjgl:lwjgl$lib")
// I give it an explicit version, because it would not work if I unzip this.
nativeOS("org.lwjgl","lwjgl$lib", "3.2.3", classifier = LWJGL.lwjglNatives)
}
...
}
// unzip_native_os tasks, here is the problem.
tasks.register<Copy>("unzip_native_os") {
this.group = "zip"
doLast {
nativesOS.asFileTree.filter { it.name.contains("natives") }.forEach {
unzipTo(File("$buildDir/libs/natives-os"), it)
}
}
}
Edited: Why this is not working? I config it first then execute it.
tasks.register<Copy>("unzip_native_os") {
this.group = "zip"
val nativesJar = nativesOS.asFileTree.filter { it.name.contains("natives") }.files
doFirst {
nativesJar.forEach {
println(">>>> $it")
unzipTo(File("$buildDir/libs/natives-os/v2"), it)
}
}
}
Edited: I found a possible answer and it looks promising but I did not implement it yet, because I need some learning to do on building this kind of script plugin/inline plugin. Here's the link: gradle custom task execution phase
Edited: found an alternative/another quick solution here: Fix custom tasks in gradle. Want to run it manually via at Execution Phase

Fixing JRE error in Java code and recompiling application

I tried run on Windows 7 some old utility that depends on old JRE version.
I have last Java Runtime Environment 1.7.0_79 installed. When I attepmt to start application, I got an error:
"Sivus requires JRE 1.4 or later to run. You can download JRE
from...etc"
Is there a workaround to resolve/fix this or something of that nature?
Program main executable packed in SFX ZIP archive, I extracted files, and found Java file, which makes the check. There is a code:
public static boolean checkJavaVersion(){
boolean ok = false;
String version = System.getProperty("java.version");
if (version.indexOf("1.1") > -1) {
ok = false;
}
else if (version.indexOf("1.2") > -1) {
ok = false;
}
else if (version.indexOf("1.3") > -1) {
ok = false;
}
else if (version.indexOf("1.4") > -1) {
ok = true;
}
else if (version.indexOf("1.5") > -1) {
ok = true;
}
return ok;
}
public static void main(String[] args) {
boolean DEBUG = false;
try {
// check if JRE is over 1.4
if (checkJavaVersion() == false){
JOptionPane.showMessageDialog(
null,
"SiVuS requires JRE 1.4 (or later) to run.\n"
+"You can download the latest JRE from java.sun.com",
"Java Run Time Environment Error",
JOptionPane.WARNING_MESSAGE);
System.exit(1);
}
How to correct this issue and recompile the application again? Will the application that relies on JRE 1.4 work with current JRE?
An example of how I'm doing patches like this.
Fix code - you can add 1.6, 1.7, 1.8 to checkJavaVersion or remove this check at main method.
Put fixed java file in folder that matches package
Compile java file, for example:
call "C:\Program Files (x86)\Java\jdk1.7.0_79\bin\javac.exe" C:\test\mypackage\MyClass.java -cp C:\test\My.jar -source 1.4 -target 1.4
Get compiled class file and replace old file (backup it first)
First of all, I would recommend not using an old tool whose "provenance" is doubtful. Especially, not as a security scanner. Surely, you can find a tool that is newer, and better supported than this one ...
If you wish to proceed (and take a risk) then one approach would be to modify that class, recompile and rebuild the JAR file, as suggested by #Rustam.
Another approach would be to create a simple wrapper class with a main method that called System.setProperty to tweak the value of the "java.version" property, and then called the real main method.

Customising the Selenium Java Junit4 Webdriver exporter

I have done some research and a lot of mucking around in selenium IDE and I cannot find any way of doing this yet.
What I am trying to do is basically add extra support and change the existing implementation for some the commands, namely isTextPresent and addSelection. I basically can leave most of the functionality of the WebDriver JUnit exporter alone as it is working fine but just want to added some customised method returns.
For example I would like to change the out of the exporter for isTextPresent() from this:
// Warning: waitForTextPresent may require manual changes
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (driver.findElement(By.cssSelector("BODY")).getText().matches("^[\\s\\S]*SOME INTERESTING TEXT[\\s\\S]*$")) break; } catch (Exception e) {}
Thread.sleep(1000);
}
To this:
SeleniumHelperUtil.isTextPresent("SOME INTERESTING TEXT");
This is so I can use my customised SeleniumHelperUtil java class that I want all my selenium tests to use. This is large complex workflow project so we will end up having hundreds of tests. I would like my testers to build their testcases, export them into Java using the WebDriver into JUnit4 tests. Then they can check them into CVS where our automatic Hudson build server will run the new tests nightly. I would like this to happen with minimal intervention from our Devs (well for now it is only me ATM really and I don't have the time until they invent a 30 hour day :)).
What I have tried
I have tried making a custom exporter by doing a cut and paste of all the code from webdriver.js, including the options, and I have modified the waitFor function to look like this:
function waitFor(expression) {
return "SeleniumHelperUtil.isTextPresent(" + expression ")";
}
Unfortunately all I am getting back is the WebDriver.js implementation which is:
// Warning: waitForTextPresent may require manual changes
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (driver.findElement(By.cssSelector("BODY")).getText().matches("^[\\s\\S]*SOME INTERESTING TEXT[\\s\\S]*$")) break; } catch (Exception e) {}
Thread.sleep(1000);
}
I am using version 1.9.1 of Selenium and Firefox 13 (on a thinapp implementation because of work restrictions I cannot have the full installed version apparently).
Now I have found the part of the code in WebDriver-Junit4.js file in the xpi file so I could modify it and rebuild the plugin with my custom code, but it would be nice just to do it via the selenium-ide as I am not sure what else I might bust when I am in there.
public boolean isTextPresent(WebDriver driver, String textToCheck)
{
try
{
org.openqa.selenium.By by = By.xpath("//p[contains(.,'"+textToCheck+"')]"));
driver.findElement(by);
return true;
}
catch (NoSuchElementException e)
{
return false;
}
}
To check the result of the Selenium Unit Testing : use firebug.

Categories

Resources