I have a maven project which will generate a JAR file, if you build it as Maven Install.
Inside this project, I have a code like this -
public class GameBot extends GameController {
public int botNumber = 1
Static String botName = "Bot1";
...// Rest of the code..
}
I want to create around 150 JAR files from this project with incremented botNumbers. For example - JAR File 1 should contain botNumber = 1 and botName = Bot1
JAR file 2 should contain botNumber = 2 and BotName = Bot2 .. So on till 150.
I used to build each of these manually and now it looks cumbersome to build each time this way. Because, if I make any small change in the code, I have to build all 150 Files again.
Does any one have some suggestions as in Can I automate the process and get all 150 JAR in a folder built for me?
Thanks.
Why dont you externalize the botNumber to a property file and using shell script or batch file create the property file and build the maven project.
Java Code
Properties properties = new Properties();
properties.load(this.getClass().getResourceAsStream("/bottest.properties"));
botNumber = Integer.parseInt(properties.getProperty("botnumber"));
botName = "Bot"+botNumber;
Shell Script
#!/bin/sh
mvn clean;
for i in {1..5}
do
echo "botnumber=$i" > ./src/main/resources/bottest.properties;
mvn install -Dmaven.test.skip;
cp target/bottest-1.0-SNAPSHOT.jar target/bootest$i.jar
done
Batch File
echo off
call mvn clean
for /l %%x in (1, 1, 5) do (
echo botnumber=%%x > .\src\main\resources\bottest.properties
call mvn install -Dmaven.test.skip
copy target\bottest-1.0-SNAPSHOT.jar target\bootest%%x.jar
)
The above example is for 5 times.
Related
I have a basic java app using java.awt Swing UI and I want to create a snap for it so when it's installed there is a launcher available and my UI Launches. I use gradle and the jar task to create a jar which works fine.
Naturally I have in a class that when called loads my app just fine:
package com.foo
class Bar() {
static void main(String... args) { launchUI() }
}
I created a snap folder at the root of the project and a snap.yaml where i followed the instructions on https://snapcraft.io/docs/java-applications so i have a snap yaml that produces a snap file which also installs fine:
name: deepthought
base: core18
version: '0.0.7'
summary: ""
icon: gui/foo.png
description: |
Computes the ultimate answer for life the universe and everything
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
# This doesn't work
#apps:
# htmldoc:
# command: desktop-launch $SNAP/bin/foo.sh
## desktop: share/applications/htmldoc.desktop
# plugs: [home, network, x11]
parts:
foopart:
plugin: gradle
source: https://github.com/bsautner/foo.git
source-type: git
gradle-options: [] # suppress running of tests and run the war task
gradle-output-dir: build/libs
I've spent quite some time trying to figure out:
If i create a shell script to run a java -jar foo.jar command it ends up in the /snap directory but it's not on the users path so they can't get to it
I've tried creating launchers but always get an error that my launcher can't be found, if i put it in my root folder as /bin/launch.sh snap can't find it and if i put it in the snap/bin/ folder i also get errors to not put things in the snap folder
When I do install my snap, i don't see where it puts my jar i want to execute, so i can't write a script that does that
I'd really appreciate if anyone can share a working snap.yaml for a java program with a launcher and if there is any mention of a path to something that you note where those files are in relation to the path of the /snap/snap.yaml file
ok figured it out - the docs don't say this but the files are relative to the root of the project so even though the yaml says this is the launch
apps:
cmd3:
command: usr/bin/foo.sh
foo.sh should be in the root of the project and the orginize section here moves it to the bin dir
foo:
plugin: gradle
source-type: local
source: .
build-packages:
- openjdk-11-jdk
stage-packages:
- openjdk-11-jdk
- x11-utils
organize:
${SNAPCRAFT_PART_BUILD}/jg-snap: usr/bin/foo.sh
The jar is in the /snap/foo/current/usr/jar directory
I have a git repository with 2 modules in it. One is SpringBoot based backend module and another one is VueJS based frontend module.
app-root
- backend
- frontend
I have a declarative style Jenkinsfile to build my backend module with relevant maven commands. I want to execute all those maven commands from inside backend directory.
One option is to use dir("backend") { ....} for all commands separately, which looks ugly to me.
Is there any other option to instruct Jenkins to execute the entire pipeline from inside a sub-directory?
I ended up with a "prepare project" stage that puts the subdirectory content into the root.
It's also probably a good idea to remove all the root contents (stage "clean") to be absolutely sure there are no leftovers from previous builds.
node {
def dockerImage
stage('clean') {
sh "rm -rf *"
}
stage('checkout') {
checkout scm
}
// need to have only 'backend' subdir content on the root level
stage('prepare project') {
// The -a option is an improved recursive option, that preserve all file attributes, and also preserve symlinks.
// The . at end of the source path is a specific cp syntax that allow to copy all files and folders, included hidden ones.
sh "cp -a ./backend/. ."
sh "rm -rf ./backend"
// List the final content
sh "ls -la"
}
stage('build docker image') {
dockerImage = docker.build("docker-image-name")
}
stage('publish docker image') {
docker.withRegistry('https://my-private-nexus.com', 'some-jenkins-credentials-id') {
dockerImage.push 'latest'
}
}
}
You can have jenkinsfiles inside backend and frontend modules and just point to them on each pipeline, eg:
and on the pipeline itself you just cd to the submodule and execute its commands:
pipeline {
agent any
stages {
stage('build') {
steps {
sh 'cd backend'
sh 'mvn clean package'
}
}
//other stages
}
}
if you don't want to cd to a sub module you can use sparse checkouts but in this case you have to change the path to the jenkinsfile accordingly because it will be on the root folder.
I have a junit test suite, that i need to run with several different properties, so that i can have only 1 test suite, but run it several times but with different data on it.
I can make the test suite read the properties from a properties file, that i can change with an environment variable, matching that with the filename of the properties file:
$ export OPERATOR=myoper
and in my java code:
String operator = System.getenv("OPERATOR");
//Reading properties file in Java example
Properties props = new Properties();
//String propertiesFile = "src/test/resources/data" + operator + ".properties";
FileInputStream fis = new FileInputStream("src/test/resources/data" + operator + ".properties");
//loading properites from properties file
props.load(fis);
But I cannot seem to find a way to iterate for all the properties files i could have, so, if i have say, 10 different properties files, that the test suite get executed that many times with all the different set of properties on the files.
I'm using maven and junit4 to run the suites, with the command:
mvn test -Dtest=TestSuite#testCase
I'll be launching the command from a Jenkins Job.
Thanks in advance!
Well after a little research i came up with the following command:
$ export OPERATOR=dataWeb*
$ for f in src/test/resources/$OPERATOR ; do export OPERATOR=$(basename "$f" | cut -d. -f1) && mvn test -Dtest=$TESTSUITE#$TESTCASE -q ; done
Which takes the environment variable of the operator, that is taken by the test suite to select the corresponding properties file, iterating in as many files exists in the directory with that pattern.
Hope it helps other people in the same situation. Maybe it's a better way to achieve this with the Junit + Maven + Jenkins combo that i'm not aware of.
I am executing a batch file (placed in the User's folder) using below code :
Process p = Runtime.getRuntime().exec(System.getProperty("user.home") + "/myapp/bin/dashboard.bat");
OR
Process process = new ProcessBuilder(System.getProperty("user.home") +"/myapp/bin/dashboard.bat").start();
dashboard.bat run some jars which has UI interface contains :
#echo off
TITLE MyApp Console
if exist %APP_HOME% goto checkuserdata
set APP_HOME=C:\Users\<UserName>\myApp
:checkuserdata
if exist %APP_USERDATA_DIR% goto setuserdatadir
set APP_USERDATA_DIR_TMP=%APP_HOME%\userdata
goto startapp
:setuserdatadir
set APP_USERDATA_DIR_TMP=%APP_USERDATA_DIR%
:startapp
set POI_JARS= .. // Path of some jar file inside the APP_HOME
set JAVAX_MAIL_JARS= .. // Path of some jar file inside the APP_HOME
set C3P0_JARS= .. // Path of some jar file inside the APP_HOME
set APPLET_JARS= .. // Path of some jar file inside the APP_HOME
set APP_CLASS_PATH= .. // Path of some jar file inside the APP_HOME
java -version
java -Djsse.enableSNIExtension=false -Djava.util.logging.config.file=%APP_USERDATA_DIR_TMP%\config\log.properties -classpath %APP_EXT_CLASS_PATH%;%APP_CLASS_PATH% net.ui.Dashboard "%APP_HOME%" "%APP_USERDATA_DIR_TMP%"
pause
after executing the dashboard.bat in TaskManager process get started but we are not able to get UI interface (i think it run as background process - not sure).
But if we move the dashboard.bat to some other location [other than C drive(OS drive)] and then if we run the batch file from java then it works fine.
please suggest any other way to achieve this or tell me where I am doing wrong ?
Thanks in advance.
I'm trying to embed jruby in a weblogic app to run sass/compass with no luck ;-(
This is what've done so far:
Install sass/compass GEMS:
java -jar jruby-complete-1.7.10.jar -S gem install -i . compass --no-rdoc --no-ri
Create a jar that contains all the gems
jar uf jruby-complete-1.7.10.jar -C sass-compass .
Check that the new jruby-complete-1.7.10.jar contains all the gems:
java -jar jruby-complete-1.7.10.jar -S gem list
*** LOCAL GEMS ***
bouncy-castle-java (1.5.0147)
chunky_png (1.2.9)
compass (0.12.2)
fssm (0.2.10)
jruby-openssl (0.9.3)
json (1.8.0 java)
krypt (0.0.1)
krypt-core (0.0.1 universal-java)
krypt-provider-jdk (0.0.1)
rake (10.1.0)
rdoc (4.0.1)
sass (3.2.14)
So far, so good, I verify that my new uber jruby-complete-1.7.10.jar contains sass and compass gems
Enters weblogic (Weblogic 11 - Oracle 10.3.6)
I create a WebApp with a servlet that uses JRuby to compile sass/compass css and put it inside an EAR
Deploy the ear so the structure is like:
MyEAR
|-APP-INF
| |-classes
| |-lib
| |-jruby-complete-1.7.10.jar <- my jruby jar that contains sass/compass gems
|-META-INF
|-MyWAR
|-META-INF
|-WEB-INF
|-classes
| |-MyServlet.class <- the servlet that compiles sass
|-lib
|-web.xml
When I call the servlet to compile some sass/compass css, I get the following error:
LoadError: no such file to load -- sass/plugin
require at org/jruby/RubyKernel.java:1083
require at classpath:/META-INF/jruby.home/lib/ruby/shared/rubygems/core_ext/kernel_require.rb:55
(root) at :2
In order to compile my sass/compass styles I've to run the following ruby script:
require 'rubygems'
require 'sass/plugin'
require 'sass/engine'
source = '...the scss code....'
engine = Sass::Engine.new(source,{ :syntax => :scss, :compass => {:css_dir => '/styles',:js_dir => '/scripts',images_dir => '/images'} })
result = engine.render
So in my servlet I use jruby like:
ScriptingContainer rubyEngine = new ScriptingContainer(LocalContextScope.CONCURRENT);
String rubyScript = ...
final StringWriter rawScript = new StringWriter();
rawScript.append(rubyScript);
rubyScript.flush();
String compiledCSS = rubyEngine.runScriptlet(theScript)
.toString();
** NO LUCK ** I got the LoadError: no such file to load -- sass/plugin
So I tried to set the LOAD_PATH like:
List<String> paths = new ArrayList<String>();
paths.add("classpath:/gems/sass-3.2.14/lib");
rubyEngine .setLoadPaths(paths);
** NO LUCK EITHER **
¿any idea?
Thanks in advance
The solution as Tom's clue said was putting sass/compass gems path at the LOAD_PATH.
So the script to make sass/compass run under weblogic 10.3.6 was:
sassGemDir = 'D:/compass-gems/gems/sass-3.2.13/lib'
compassGemDir = 'D:/compass-gems/gems/compass-0.12.2/lib'
chunkyPngGemDir = 'D:/compass-gems/gems/chunky_png-1.2.9/lib'
fssmGemDir = 'D:/compass-gems/gems/fssm-0.2.10/lib'
$LOAD_PATH.insert(0,sassGemDir,remoteSassGemDir,compassGemDir,chunkyPngGemDir,fssmGemDir)
require 'rubygems'
require 'sass/plugin'
require 'sass/engine'
source = '...the scss code....'
engine = Sass::Engine.new(source,{ :syntax => :scss,:compass => {:css_dir => '/styles',:js_dir => '/scripts',images_dir => '/images'} })
result = engine.render
NOTE:
Finally I didn't managed to make jruby load sass/compass from a JAR so there's NO need to create an uber-jar that contains jruby-complete and sass/compass (step 2 in my question)
The only change in the ruby-script to run sass/compass from a JAR is:
sassGemDir = 'classpath:/gems/sass-3.2.13/lib'
compassGemDir = 'classpath/compass-0.12.2/lib'
chunkyPngGemDir = 'classpath/gems/chunky_png-1.2.9/lib'
fssmGemDir = 'classpath/gems/fssm-0.2.10/lib'
BUT when I run sass/compass loading from the uber-jar I got two errors:
compass's sprite-importer.rb failed to load sprite_importer.erb file since it was loaded like:
TEMPLATE_FOLDER = File.join(File.expand_path('../', __FILE__), 'sprite_importer')
so I changed sprite-importer.rb to:
TEMPLATE_FOLDER = File.join( File.expand_path(File.join(File.dirname(__FILE__))),'sprite_importer')
and this problem went away
compass's frameworks.rb failed to load the frameworks dir: jruby cannot load a dir's contents when the dir is inside a JAR (I susspect it's an error with java 6 or jrockit, which is the JDK I use in weblogic 10.3.6)
I could not find a solution for this problem so I switched to load sass/compass to be loaded directly from the filesystem and NOT from a JAR file
FINAL NOTE
All the problems with the GEMs LOAD_PATH and compass being loaded from within a JAR were NOT an issue when running inside TOMCAT under Java 7
Hope this helps someone who's trying to run sass/compass using an embeded jruby