tag:blogger.com,1999:blog-33886938610495797572024-03-17T08:35:22.210+01:00rostislav.matlExploring the possibilities.Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.comBlogger46125tag:blogger.com,1999:blog-3388693861049579757.post-27800567804472099462021-02-20T17:42:00.000+01:002021-02-20T17:42:01.440+01:00GRUB 2 configuration<p><span style="font-family: arial;">I've recently found time and need to improve my <b>GRUB 2 setup</b> and I hope sharing that could help somebody, although it is not something you won't find in other HOWTOs. </span></p><p style="text-align: left;"><span style="font-family: arial;">I'm quite conservative and not spending in boot screen much time so all I use is <b>text mode</b>. </span></p><p style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt; text-align: left;"><span style="font-family: arial;">First of all, the location of onfig files. All the <b>configuration settings</b> are in </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><b><span style="font-family: courier;">/etc/default/grub</span></b><span style="font-family: arial;">. The settings are used as variables when you generate a new GRUB configuration. </span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">The settings there are used whe you generate a new GRUB configuration </span><span style="white-space: pre-wrap;"><span style="font-family: courier;">/boot/grub/grub.cfg</span></span><span style="font-family: arial; white-space: pre-wrap;"> with </span><span style="white-space: pre-wrap;"><a href="http://www.linuxhowtos.org/manpages/8/grub2-mkconfig.htm"><span style="font-family: courier;">grub-mkconfig</span></a></span><span style="font-family: arial; white-space: pre-wrap;"> command and are all you usually need to change. </span></p><div style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt; text-align: left;"><span style="font-family: arial; white-space: pre-wrap;">If you need to put some custom logic to the generation for the config file, you can achieve that by adding a script into </span><span style="font-family: "Courier New"; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><b>/etc/grub.d</b></span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: arial;"> directory.</span></span></div><h3 style="line-height: 1.38; margin-bottom: 6pt; margin-top: 18pt; text-align: left;"><span style="background-color: transparent; color: black; font-family: Arial; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: small;">disabling framebuffer</span></span></h3><div><span style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: arial;"><span style="background-color: white; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">Wher you try to</span><span style="background-color: white; color: #202122; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> avoid problems with a proprietary driver or just like text mode:</span></span></span></div><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: #eeeeee; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">GRUB_TERMINAL_OUTPUT=console</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: #eeeeee; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;"><br /></span></span></p><div style="text-align: left;"><span style="background-color: white; color: #202122; white-space: pre-wrap;"><span style="font-family: Arial;">Some information about current framebuffer setup can be found by: <br /></span></span><span style="background-color: white; color: #202122; white-space: pre-wrap;"><span style="font-family: courier;">hwinfo | grep -i framebuffer</span></span></div><div style="line-height: 1.38; margin-bottom: 6pt; margin-top: 18pt; text-align: left;"><h3 style="text-align: left;"><span style="background-color: transparent; color: black; font-family: Arial; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: small;">menu timeout</span></span></h3><span style="font-size: small; font-weight: normal;"><span style="font-family: arial;">Setting menu-style timeout, with 5sec countdown:<br /></span></span><span style="font-size: small; font-weight: normal;"><span style="font-family: courier;">GRUB_TIMEOUT=5<br /></span></span><span style="font-size: small; font-weight: normal;"><span style="font-family: courier;">GRUB_TIMEOUT_STYLE=menu</span></span></div><div style="text-align: left;"><span style="color: #434343; white-space: pre-wrap;"><span style="font-family: arial; font-size: small;"><br /></span></span></div><h3 style="text-align: left;"><span style="color: #434343; white-space: pre-wrap;"><span style="font-family: arial; font-size: small;">menu font</span></span></h3><div><span style="color: #434343; font-family: arial; white-space: pre-wrap;"><span style="font-size: small;"><br /></span></span></div><div><span style="color: #434343; font-family: arial; white-space: pre-wrap;"><span style="font-size: small;">GRUB allows to set a custom font. You can create a new GRUB font by converting </span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">an existing font with </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><a href="http://www.linuxhowtos.org/manpages/1/grub2-mkfont.htm"><span style="font-family: courier;">grub-mkfont</span></a></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> utility. AFAIK at least TTF and PCF font formats are supported. </span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span></div><div><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: arial;"><br /></span></span></div><div><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Example of using converted <a href="http://terminus-font.sourceforge.net/">Terminus font</a> in bold weight and 16pt size:
</span><span style="background-color: #eeeeee; white-space: pre-wrap;"><span style="font-family: courier;">GRUB_FONT=/usr/share/grub/terminus16b.pf2</span></span></div><div><span style="background-color: white; white-space: pre-wrap;"><span style="font-family: arial;"><br /></span></span></div><div><span style="background-color: white; white-space: pre-wrap;"><span style="font-family: arial;">Note that this font is a bitmap one so I had to just chose the proper size and coverte it, when converting TTF fonts you need also provide the desired size.</span></span></div><h2 style="text-align: left;"><span style="color: #434343; white-space: pre-wrap;"><span style="font-family: arial; font-size: small;">menu colors</span></span></h2><p><span style="font-family: arial;">The palette for text-mode colors is quite limited, v</span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">alid color names are: </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">black</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">blue</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">brown</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">cyan</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">dark-gray</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">green</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">light-cyan</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">light-blue</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">light-green</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">light-gray</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">,</span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">light-magenta</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">light-red</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">magenta</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">red</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">white</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">yellow</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">.</span></p><p><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">There are two config options, for setting normal and highlight colors, in format foreground/background:
</span><span style="background-color: #eeeeee; font-family: courier;"><span style="white-space: pre-wrap;">GRUB_COLOR_NORMAL=white/blue
</span><span style="white-space: pre-wrap;">GRUB_COLOR_HIGHLIGHT=yellow/light-blue</span></span></p><p><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">As it seems these settings are ignored, I created file </span><span style="font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">/etc/grub.d/99_set_colors</span></span><span style="font-family: arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> with following content to fix that. It's rather simplistic as it does now allow any spaced or quotes around the color values but it does the job:</span></p><div align="left" dir="ltr" style="margin-left: 0pt;"><table style="border-collapse: collapse; border: none; table-layout: fixed; width: 451.27559055118115pt;"><colgroup><col></col></colgroup><tbody><tr style="height: 0pt;"><td style="border-bottom: dotted #000000 0.5pt; border-left: dotted #000000 0.5pt; border-right: dotted #000000 0.5pt; border-top: dotted #000000 0.5pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt 5pt 5pt 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: white; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier; font-size: x-small;">#!/bin/sh</span></span></p><span style="font-family: courier; font-size: x-small;"><br /></span><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier; font-size: x-small;">color_normal=`grep "^GRUB_COLOR_NORMAL" /etc/default/grub | cut -d "=" -f2`</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier; font-size: x-small;">color_highlight=`grep "^GRUB_COLOR_HIGHLIGHT" /etc/default/grub | cut -d "=" -f2`</span></span></p><span style="font-family: courier; font-size: x-small;"><br /></span><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier; font-size: x-small;">cat <<EOF</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier; font-size: x-small;">set color_normal=${color_normal}</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier; font-size: x-small;">set color_highlight=${color_highlight}</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier; font-size: x-small;">set menu_color_normal=${color_normal}</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: courier; font-size: x-small;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">set </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">menu_color_highlight=${color_highlight}</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier; font-size: x-small;">EOF</span></span></p></td></tr></tbody></table></div><h3 style="line-height: 1.38; margin-bottom: 4pt; margin-top: 16pt; text-align: left;"><span style="background-color: transparent; color: #434343; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: arial; font-size: small;">recalling previously selected menu entry</span></span></h3><div><span style="background-color: transparent; color: #434343; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: arial; font-size: small;"><br /></span></span></div><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: arial;"><span style="white-space: pre-wrap;">GRUB can save the menu entry you selected last time and use it as default for the next boot:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: #eeeeee; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">GRUB_DEFAULT=saved</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: #eeeeee; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;">GRUB_SAVEDEFAULT=true</span></span></p><h3 style="line-height: 1.38; margin-bottom: 4pt; margin-top: 16pt; text-align: left;"><span style="background-color: transparent; color: #434343; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: arial; font-size: small;">play tune</span></span></h3><div><span style="background-color: transparent; color: #434343; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="color: black;"><span style="font-family: arial;"><br /></span></span></span></div><div><span style="background-color: transparent; color: #434343; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="color: black;"><span style="font-family: arial;">If you do not like the waiting for the moment when the GRUB menu is shows up, you can set a tune that will be played just the moment before it appears.</span></span></span></div><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: arial;"><br /></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="background-color: transparent; font-family: arial;">Example with the greeting from the film Close Encounters of The Third Kind:
</span><span style="background-color: #eeeeee;"><span style="font-family: courier;">GRUB_INIT_TUNE="</span><span style="font-family: courier;">480 900 2 1000 2 800 2 400 2 600 3</span><span style="font-family: courier;">"</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: courier;"><br /></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: arial;">You canl find other well-known tunes on internet, e.g. in <a href="https://forums.linuxmint.com/viewtopic.php?t=174854">Linuxmint forum</a> .</span></span></p><p><br /></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><br /></p><div id="gtx-trans" style="left: -3px; position: absolute; top: 501.63px;"><div class="gtx-trans-icon"></div></div>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-90632659133849724532020-06-25T01:44:00.002+02:002020-06-25T01:47:48.808+02:00Continuous Versioning with Git and Gradle<h3>
Semantic Versaioning</h3>
Everybody knows <a href="https://semver.org/"><b>semantic versioning</b></a>. I think it's still good for software sold in boxes, regardless if the real paper ones or as downloads. But for continuous deployment it does not seem to be good enough.<br />
<br />
Looking at the semantic version number <b>does not tell you much</b>. It is barely more than "<i>hey, something was changed and the change is/maybe/should-not be disturbing"</i>. Not mentioning that the developers tend to forget to change the version number. And even when they do, it is unnecessarily difficult to find what exact changes, i.e. commits, are in the semantically versioned release.<br />
<br />
<h3>
Continuous Versioning</h3>
Here comes what I call <b>continuous versioning</b>. It's more principle than exact versioning pattern, although I am going to suggest this one:<br />
<br />
<span style="background-color: #fff2cc; font-family: "courier new" , "courier" , monospace;">${semantic_version}-${commit_timestamp}-${commit_id}</span>.<br />
<br />
As you see the <b>semantic version</b> is still there, mainly because people like to see something familiar when you change things :). The main point is to add information about the last commit the change release contains. The <b>commit timestamp</b> is there to give the version numbers nice chronological ordering. For developers is the most useful the last part - <b>id of the commit</b>, for which we use short hash of Git commit.<br />
<br />
As you see there is no big demand for developers to increment the semantic version - it's nice if they do that, but each artifact still gets unique version number if they do not. What's even better, all the information can be gathered during build and used for various artifacts the build can produce - nowadays often executable package and Docker image.<br />
<br />
The example how to achieve the described versioning with Gradle and use it to tag a Docker image artifact is below. To get information from Git we use both <a href="https://github.com/palantir/gradle-git-version"><span style="background-color: #fff0f0;">com.palantir.git-version</span> Gradle plugin</a> and Git command line, because the plugin does not provide timestamp info.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border: solid 1px gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">plugins <span style="color: #333333;">{</span>
id <span style="background-color: #fff0f0;">'com.palantir.git-version'</span> version <span style="background-color: #fff0f0;">'0.12.3'</span>
id <span style="background-color: #fff0f0;">'com.bmuschko.docker-remote-api'</span> version <span style="background-color: #fff0f0;">'6.1.2'</span>
<span style="color: #333333;">}</span>
<span style="color: #333399; font-weight: bold;">def</span> semanticVersion <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">'1.0.0'</span>
<span style="color: #333399; font-weight: bold;">def</span> gitTimestamp <span style="color: #333333;">=</span> <span style="color: #333333;">{</span> <span style="color: #333333;">-></span>
<span style="color: #333399; font-weight: bold;">def</span> stdout <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> ByteArrayOutputStream<span style="color: #333333;">()</span>
exec <span style="color: #333333;">{</span>
commandLine <span style="background-color: #fff0f0;">'git'</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">'show'</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">'-s'</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">'--format=%ct'</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">'HEAD'</span>
standardOutput <span style="color: #333333;">=</span> stdout
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">return</span> stdout<span style="color: #333333;">.</span><span style="color: #0000cc;">toString</span><span style="color: #333333;">().</span><span style="color: #0000cc;">trim</span><span style="color: #333333;">()</span>
<span style="color: #333333;">}</span>
<span style="color: #333399; font-weight: bold;">def</span> gitVersion <span style="color: #333333;">=</span> details<span style="color: #333333;">.</span><span style="color: #0000cc;">gitHash</span>
version <span style="color: #333333;">=</span> semanticVersion <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">"-"</span> <span style="color: #333333;">+</span> gitTimestamp<span style="color: #333333;">()</span> <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">"-"</span> <span style="color: #333333;">+</span> gitVersion
<span style="color: #888888;">// ...</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">com.bmuschko.gradle.docker.tasks.image.DockerBuildImage</span>
task <span style="color: #0066bb; font-weight: bold;">buildDockerImage</span><span style="color: #333333;">(</span><span style="color: #997700; font-weight: bold;">type:</span> DockerBuildImage<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #888888;">// custom task to prepare files ind build/docker directory:</span>
<span style="color: #888888;">// dependsOn "prepareFilesForDockerBuild"</span>
inputDir <span style="color: #333333;">=</span> file<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">'build/docker'</span><span style="color: #333333;">)</span>
images<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"mycooldockerrepo.com/${project.name}:${version}"</span><span style="color: #333333;">)</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">com.bmuschko.gradle.docker.tasks.image.DockerPushImage</span>
task <span style="color: #0066bb; font-weight: bold;">pushDockerImage</span><span style="color: #333333;">(</span><span style="color: #997700; font-weight: bold;">type:</span> DockerPushImage<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
dependsOn <span style="background-color: #fff0f0;">"buildDockerImage"</span>
images<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"mycooldockerrepo.com/${project.name}:${version}"</span><span style="color: #333333;">)</span>
registryCredentials <span style="color: #333333;">{</span>
url <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"mycooldockerrepo.com"</span>
username <span style="color: #333333;">=</span> System<span style="color: #333333;">.</span><span style="color: #0000cc;">getenv</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">'docker_user'</span><span style="color: #333333;">)</span> <span style="color: #333333;">?:</span> <span style="background-color: #fff0f0;">"${docker_user}"</span>
password <span style="color: #333333;">=</span> System<span style="color: #333333;">.</span><span style="color: #0000cc;">getenv</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">'docker_password'</span><span style="color: #333333;">)</span> <span style="color: #333333;">?:</span> <span style="background-color: #fff0f0;">"${docker_password}"</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
To package the version info inside the Docker image, we can define custom task <span style="font-family: Courier New, Courier, monospace;">prepareFilesForDockerBuild</span> and uncomment the dependsOn line of buildDockerImage(). <br />To <b>save the version number into a file</b>, e.g. named <b>docker/version.txt</b>, this should be inside that task:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border: solid 1px gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">new</span> <span style="color: #0066bb; font-weight: bold;">File</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"docker/version.txt"</span><span style="color: #333333;">).</span><span style="color: #0000cc;">text</span> <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"${version}"</span>
</pre>
</div>
<br />
I hope this article helps somebody to look at versioning schemes from a newer point of view. I will add Maven version when I have one but my recent projects seem to be Gradle-only, so it coudl take time - feel free to post yours to share.<br />
<br />
<br />Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-33996557282834524662020-06-13T21:30:00.001+02:002020-06-13T22:28:14.436+02:00Sharing Files From Linux to Windows VM<div style="text-align: left;"><p><br /></p><p>I have a Linux workstation and created a Windows virtual machine in it, running on KVM+<a href="https://www.qemu.org/" target="_blank"><b>QEMU</b></a>+libvirt stack. Recently I haveve decided to actually start using this VM and found that to make it comfortable I need some file sharing between the Linux host and Windows guest. Following article describes how to make working, as simple as possible settup to achieve it.</p><p>My configuration is Gentoo Linux as the host and Windows 10 a the guest. It should work similarly on any other recent Linux and also on Windows 7. For managing of the VMs I'm using both commandline (mostly virsh and qemu-img) and <a href="https://virt-manager.org/" target="_blank">Virtual Machine Manager</a>. </p><p>I expect the <b>libvirt</b> and <b>nfs</b> daemons are already running on your machine and you are familiar with basic usage of these tools.</p><p>I hope the description bellow will help somebody to save some time. Just don't ask me about systemd setup, I don't use it. </p><p>First of all what approaches I considered and rejected:</p><p></p><ul style="text-align: left;"><li>Plan 9 file sharing protocol - there is no support on Windows side for that</li><li>Samba - would work but I wanted something simpler</li></ul><p></p><p>While exploring, what's possible, I found that Windows are able to use NFS and it also seemed as the most simple solution so I decided to give it a try. To my suprise, it really works, although my setup is very simplified. Steps to achieve that in brief:</p><p></p><ul style="text-align: left;"><li>create directory to be shared and export it as NFS volume</li><li>anable NFS support in Windows and mount the NFS volume</li></ul><p></p><h1 style="text-align: left;">Creating the Directory and Export It</h1><p>The location of the directory is quite flexible but should be accessible by the account that will be used for the sharing -- I decided to use good old <b><font face="courier">nobody</font></b>:</p><pre style="text-align: left;">>id nobody<br />uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)</pre><p>Create the directory and set the ownership:</p><pre style="text-align: left;">>mkdir /mnt/diskx/nfsshare<br />>sudo chown nobody:nobody /mnt/diskx/nfsshare</pre><p>Let's expect IP address of Windows VM is 192.168.11.11. You can find the real value for your VM in Virtual Machine manager when you got to Details and look at NIC settings. For easier manipulation we give it a name by new record in <b><font face="courier">/etc/hosts</font></b>:</p><pre style="text-align: left;"><span style="font-family: monospace;"><span style="background-color: white;">192.168.11.11 windowsvm</span></span></pre><p>Now we need to export the directory via NFS by adding following line to <b><font face="courier">/etc/exports</font></b>:</p><pre style="text-align: left;">/mnt/disk3/nfsshare/ windowsvm(rw,all_squash,anonuid=65534,anongid=65534)</pre><p>It will map all the userd ids to our <font face="courier">nobody</font> user.</p><p>To make the change active, it should be followed by either restarting of the NFS daemon or by executing '<font face="courier">exportfs -ra</font>'.</p><h1 style="text-align: left;">Mounting the NFS Volume in Windows</h1><p>Start the Windows VM. To add support for NFS, we must go to "<b>Turn Windows Features on or off</b>" and <b>enable "Services for NFS"</b>.</p><p><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPHi9Q4e7AC0boO1CkbRmlkNG-_x_3J5Y-DSKHqnEkIEU46jZgAtNpaSJ0Bko-Fa9lrDp3QRvFGb-igpyT85YZLOakhgfAEffvzd-Jxt8fr0JATKpCNv32qkZHdxj2m9wK41HkuNubNJz6/s802/01-features.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="678" data-original-width="802" height="542" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPHi9Q4e7AC0boO1CkbRmlkNG-_x_3J5Y-DSKHqnEkIEU46jZgAtNpaSJ0Bko-Fa9lrDp3QRvFGb-igpyT85YZLOakhgfAEffvzd-Jxt8fr0JATKpCNv32qkZHdxj2m9wK41HkuNubNJz6/w640-h542/01-features.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXfCTatFroyoV8pLny7dmHmjlDS4bZH8LldTESeWbJOER6RfvydUtWS_Qjr5z8J34prhjwsX0N7blOC3Sd3a1yK2b-92RpfQE52Rs_lzFUI8-jcYRJc7JDNBcBMvydtCMdYXfmPH-cE_N8/s769/02-services_for_nfs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="769" data-original-width="750" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXfCTatFroyoV8pLny7dmHmjlDS4bZH8LldTESeWbJOER6RfvydUtWS_Qjr5z8J34prhjwsX0N7blOC3Sd3a1yK2b-92RpfQE52Rs_lzFUI8-jcYRJc7JDNBcBMvydtCMdYXfmPH-cE_N8/w624-h640/02-services_for_nfs.png" width="624" /></a></div><p><br /></p><p>After that we need to use the same anonymous UID and GID as set on server side. For that open regedit, find "<font face="courier"><b>Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Default</b></font>" and add there two DWORD values named <font face="courier"><b>AnonymousUid</b></font> and <font face="courier"><b>AnonymousGid</b></font> with the same value as used in <font face="courier">/etc/exports</font>.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtk8kaPYNdDQvWf-ratdirzPzdxoTmPkrADSKyhyphenhyphengjFYf7d1PemCxESEscEROgHefETqh3bUaLgZbx8flm3TQW5lrctdSQEeADXzrMkMPb3lY62k9U7xfb-Jvn-esh4yYzU1xriOKfrlZF/s751/03-anonymous_uid_and_gid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="514" data-original-width="751" height="438" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtk8kaPYNdDQvWf-ratdirzPzdxoTmPkrADSKyhyphenhyphengjFYf7d1PemCxESEscEROgHefETqh3bUaLgZbx8flm3TQW5lrctdSQEeADXzrMkMPb3lY62k9U7xfb-Jvn-esh4yYzU1xriOKfrlZF/w640-h438/03-anonymous_uid_and_gid.png" width="640" /></a></div><p><br /></p><p>With the IP address of the Linux host set to 10.10.11.11 we can now execute the following command in command.com shell: </p><pre style="text-align: left;">mount -o anon \\10.10.11.11\mnt\diskx\nfsshare Z:</pre><p>After that the NFS volume should appear as Windows volume "Z:" and we should be able both to read and write to it.</p><p>Save the command to a file called <font face="courier">mounntfs.bat</font> and keep it for future use. I have it in my home folder in sub-folder named <font face="courier">scripts</font>.</p><h2 style="text-align: left;">Mounting It Automatically on Startup</h2><p>To avoid the necessity to execute the script manually each time you start the VM, you can use Windows Scheduler and create and a scheduled task for that. The desired task in my cas uses <font face="courier">SYSTEM</font> account, triggers at startup whenever a network connection is available.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRH2eG-pZz2nT7zTOjLX2A-SUNIvBQJoUNV7AGyspOJb_UGJTUGUnRqoMsjLTRjRPo7SB1NX8spyXlh5OcJEepOBC4D_rBzKhlq2nei5NrSJOuvtNyRl2lCFcjRsOK0PiwKHbGXVNI_LWo/s812/04-scheduler.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="683" data-original-width="812" height="538" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRH2eG-pZz2nT7zTOjLX2A-SUNIvBQJoUNV7AGyspOJb_UGJTUGUnRqoMsjLTRjRPo7SB1NX8spyXlh5OcJEepOBC4D_rBzKhlq2nei5NrSJOuvtNyRl2lCFcjRsOK0PiwKHbGXVNI_LWo/w640-h538/04-scheduler.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJbKbPIPtFxlMI1pwTsyFb_2OxAnh_-lBgHsqjPX7MBNNC1jvgxxO8vzvRQzeVtep6EZ-WVU_wmkntbRjkgtMTc0cDiM92_GmwK0_sjJ-NLCmoCUGcINazOJ7oQFfYXuCiWWIcFe3vnoZy/s788/05-scheduler-task-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="788" height="584" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJbKbPIPtFxlMI1pwTsyFb_2OxAnh_-lBgHsqjPX7MBNNC1jvgxxO8vzvRQzeVtep6EZ-WVU_wmkntbRjkgtMTc0cDiM92_GmwK0_sjJ-NLCmoCUGcINazOJ7oQFfYXuCiWWIcFe3vnoZy/w640-h584/05-scheduler-task-1.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWKvQfhC8vbMXiZK8IjFQrdPyVRTHILnKmND7ePaii3YNjoCzb5Az2t9hD7Yd7eUU_3Q6LwnSdV5Kugdbz7lWlmp0uI_Jva-OCj1sMkFOAJZJjnlF19Gae3Bez7_hSu4nY1Z0JcXON2bi6/s788/05-scheduler-task-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="382" data-original-width="788" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWKvQfhC8vbMXiZK8IjFQrdPyVRTHILnKmND7ePaii3YNjoCzb5Az2t9hD7Yd7eUU_3Q6LwnSdV5Kugdbz7lWlmp0uI_Jva-OCj1sMkFOAJZJjnlF19Gae3Bez7_hSu4nY1Z0JcXON2bi6/w640-h310/05-scheduler-task-2.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqEALlLI6kx1z-7SrgTm5OlO_5fjo3IcRkNbF7_p5wcIIzJzx3Yk21IYmEHOZ7w1tsESe_1tgNDQrnZlSZQ0ggha_PgM6Hmq9YGXCrsQ8mOGuJHl-RtHoCP1WUDUR9R8_SpQ9cm0Kn_u_l/s783/05-scheduler-task-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="364" data-original-width="783" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqEALlLI6kx1z-7SrgTm5OlO_5fjo3IcRkNbF7_p5wcIIzJzx3Yk21IYmEHOZ7w1tsESe_1tgNDQrnZlSZQ0ggha_PgM6Hmq9YGXCrsQ8mOGuJHl-RtHoCP1WUDUR9R8_SpQ9cm0Kn_u_l/w640-h298/05-scheduler-task-3.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMU40H5nElfwC7vkcICSUnci9D65GM3fEO4SPI7OCNch188sBks1ixbReLs55-tDkzXtDyAk-N5cjw9T_b-qfEaLKQFjsL-0SPTCU7owYxhc2_BwmgIRDHDzoCr4JDG6byKeCwi-NyemcI/s862/05-scheduler-task-4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="549" data-original-width="862" height="408" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMU40H5nElfwC7vkcICSUnci9D65GM3fEO4SPI7OCNch188sBks1ixbReLs55-tDkzXtDyAk-N5cjw9T_b-qfEaLKQFjsL-0SPTCU7owYxhc2_BwmgIRDHDzoCr4JDG6byKeCwi-NyemcI/w640-h408/05-scheduler-task-4.png" width="640" /></a></div><p><br /></p><p><br /></p><p><br /></p><p> </p></div>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-22857769389515752932016-05-02T10:12:00.000+02:002020-06-13T21:42:45.551+02:00Preparing Virtual Machine for Virsh Shutdown<span style="font-family: "arial" , "helvetica" , sans-serif;">One of the a bit tricky things with libvirt is to make guest OS support shutdown command directly, i.e. when you call <span style="font-family: "courier new" , "courier" , monospace;">virsh shutdown ${machine_name}</span> the virtual machine shuts down gracefully and without any delay. </span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Libvirt sends the an <b><a href="https://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface" target="_blank">ACPI</a></b> (see <a href="http://www.acpi.info/">acpi.info</a> for details)event to virtual machine when shutdown command is issued. Although <a href="http://wiki.libvirt.org/page/FAQ#Why_doesn.27t_.27shutdown.27_seem_to_work.3F" target="_blank">delivering of ACPI events can be disabled in libvirt configuration</a><span style="font-family: "arial" , "helvetica" , sans-serif;">,</span> often the problem is that default settings of the most operating systems ignores the events or requires user interaction during their processing. That <span style="font-family: "arial" , "helvetica" , sans-serif;">i</span>s undesired behavior for headless automated virtual machines -- <span style="font-family: "arial" , "helvetica" , sans-serif;">b</span>elow is how to configure some of the curren<span style="font-family: "arial" , "helvetica" , sans-serif;">tly used </span>operating systems to <span style="font-family: "arial" , "helvetica" , sans-serif;">correctly shutdown<span style="font-family: "arial" , "helvetica" , sans-serif;"> <span style="font-family: "arial" , "helvetica" , sans-serif;">when they receive the</span> proper ACPI</span></span> event. </span><br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><i>note: I intend to update this article when I get experience with any other operating system setup.</i> <i>Feel free to send me yous hands-on as comments.</i></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<h4>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Ubuntu</span>
</h4>
<h4 dir="ltr" id="docs-internal-guid-00f9c425-707b-9144-cf50-19dc87b30c25" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;"> </span></h4>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">install <b>acpid </b>: </span><span style="background-color: transparent; color: black; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">apt-get install acpid</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">start it : </span><span style="background-color: transparent; color: black; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">service acpid start</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Add it to default run level: </span><span style="background-color: transparent; color: black; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">update-rc.d acpid enable</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">disable confirmation dialogs by editing </span><b><span style="background-color: transparent; color: black; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">/etc/acpi/events/powerbtn</span></b><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"> </span></div>
</li>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">add # to comment line: </span><span style="background-color: transparent; color: black; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">#action=/etc/acpi/powerbtn.sh</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">add a new line: </span><span style="background-color: transparent; color: black; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">action=/sbin/poweroff</span></div>
</li>
</ol>
</ol>
<br />
<div dir="ltr" id="docs-internal-guid-00f9c425-707b-9144-cf50-19dc87b30c25" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
<h4>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Windows Server
</span></h4>
<div dir="ltr" id="docs-internal-guid-00f9c425-707e-ad96-3dd8-e17fb8169540" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">change <b>policies</b></span></div>
</li>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">open the Group Policy Editor: gpedit.msc</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">allow shutdown when an administrator is not logged in</span></div>
</li>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-roman; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">navigate to Local Computer Policy -> Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-roman; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">find option: “<b>Shutdown: Allow system to be shut down without having to log on</b>” and set it to “Enabled”</span></div>
</li>
</ol>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">disable the “Shutdown Event Tracker” (the dialog that will be presented to the user when a shutdown is requested)</span></div>
</li>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-roman; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">navigate to Local Computer Policy -> Computer Configuration -> Administrative Templates -> System</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-roman; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">find option “<b>Display Shutdown Event Tracker</b>” and set it to “Disabled”</span></div>
</li>
</ol>
</ol>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">set <b>power button</b> to shutdown </span></div>
</li>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">open Control Panel</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">select Power Options</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">left pane select “</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span id="docs-internal-guid-b0030485-f28b-d8b9-2d86-a181bbb2c5f4" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Change what the power buttons do</span>” and set it to “shutdown”</span></div>
</li>
</ol>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">disable monitor <b>sleep</b></span></div>
</li>
<ol style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">open Control Panel</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">select Power Options, </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">select "</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span id="docs-internal-guid-b0030485-f28b-d8b9-2d86-a181bbb2c5f4" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Change power-saving settings</span><span id="docs-internal-guid-b0030485-f28b-d8b9-2d86-a181bbb2c5f4" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">"</span></span> </span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">select “High performance”</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: lower-alpha; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">click on “Change plan settings” and disable monitor sleep by setting "Turn off display" option to 'Never"</span></div>
</li>
</ol>
</ol>
Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-52507275200446812192016-04-29T11:41:00.000+02:002016-05-02T08:56:52.356+02:00Getting IP Address of a Virtual Machine<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">When assigning IP addresses to a virtual machine, aka domain, you have two options -- either to assign a fixed IP to the machine or use DHCP for providing an IP address from a predefined range.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">In environment in which you need to dynamically create groups of cooperating virtual machines the approach with fixed IP address is not feasible as it uses the network address range inefficiently and/or requires careful IP address management. </span><br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">We needed the<b> DHCP way</b>. The problem is how to <b>get the IP address for a virtual machine when all you have is only the machine's name</b>.</span><br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">There are two <span style="font-family: "arial" , "helvetica" , sans-serif;">ways how to find out <span style="font-family: "arial" , "helvetica" , sans-serif;">most of the information about<span style="font-family: "arial" , "helvetica" , sans-serif;"> </span></span></span>a v<span style="font-family: "arial" , "helvetica" , sans-serif;">i</span>rtual machine, includ<span style="font-family: "arial" , "helvetica" , sans-serif;">ing its <span style="font-family: "arial" , "helvetica" , sans-serif;">I</span>P address</span>:</span><br />
<ul>
<li><span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><b>with a help from inside</b> -- guest OS needs to have installed k<span style="font-family: "arial" , "helvetica" , sans-serif;">i</span>nd of hypervi<span style="font-family: "arial" , "helvetica" , sans-serif;">s</span>or-specific software, so called <b>guest agent</b>, mediating communication <span style="font-family: "arial" , "helvetica" , sans-serif;">of the host</span> with the guest</span></span></li>
<li><span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><b>from outside</b> -- gathering the desired in<span style="font-family: "arial" , "helvetica" , sans-serif;">formation </span>relie<span style="font-family: "arial" , "helvetica" , sans-serif;">s</span> on <b>standard</b><span style="font-family: "arial" , "helvetica" , sans-serif;"><b> tools o<span style="font-family: "arial" , "helvetica" , sans-serif;">f</span> host OS</b> and network connectivity</span></span></span></li>
</ul>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<h3>
</h3>
<h4>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Virtualbox - Guest Additions</span></h4>
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">The IP address of the virtual machine can by retrieved from the machine properties with a single command<span id="docs-internal-guid-7db060fa-6138-39f0-1fcd-e41cd7257c08" style="background-color: transparent; color: #980000; font-size: 14.6667px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="color: black;"> vboxmanage guestproperty enumerate ${machine_name}.<span style="font-family: "arial" , "helvetica" , sans-serif;"> The information about guest network is available in guest properties only when the guest has installed <a href="https://www.virtualbox.org/manual/ch04.html" target="_blank">Guest Additions</a>, which limits the list of guest operating systems to Linux, Windows and Solaris.</span></span></span></span></span><br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span id="docs-internal-guid-7db060fa-6138-39f0-1fcd-e41cd7257c08" style="background-color: transparent; color: #980000; font-size: 14.6667px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="color: black;">To extract just the IP in bash or similar UNIX shell run:</span></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span id="docs-internal-guid-7db060fa-6138-39f0-1fcd-e41cd7257c08" style="background-color: transparent; color: #980000; font-size: 14.6667px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="color: black;"><span style="font-size: small;"><span style="font-family: "courier new" , "courier" , monospace;"><span id="docs-internal-guid-7db060fa-6138-39f0-1fcd-e41cd7257c08" style="background-color: transparent; color: #980000; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="color: black;">vboxmanage guestproperty enumerate ${machine_name} </span></span>| grep IP | cut -d " " -f 4 | cut -d "," -f 1</span></span></span></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span id="docs-internal-guid-7db060fa-6138-39f0-1fcd-e41cd7257c08" style="background-color: transparent; color: #980000; font-size: 14.6667px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="color: black;"></span></span></span><br />
<h4>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Libvirt - QEMU Guest Agent</span></h4>
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">Also QEMU has Guest Agent, supporting Linux and Windows guests, that <a href="http://dustymabe.com/2013/07/14/find-guest-ip-address-using-qemu-guest-agent/" target="_blank">can be use to get machine's IP address</a>. </span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<h4>
<span style="font-family: "arial" , "helvetica" , sans-serif;">No Guest Tools, Just Linux</span></h4>
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">Second approach relies some basic knowledge about the virtual machine and the network interface it is connected to. Basically you need to <b>know machine's MAC address and name of the <a href="https://en.wikipedia.org/wiki/Network_interface_controller" target="_blank">NIC</a></b>. For bridged networking the NIC is likely to be named <span style="font-family: "courier new" , "courier" , monospace;">br0</span>.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Let's suppose the <b>host OS is Linux</b>. Similar approach should work on other operating systems but the tools will differ. </span><br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">For the translation if MAC address to IP address I rely on<b> <a href="https://github.com/royhills/arp-scan" target="_blank">arp-scan</a></b>. It scans the whole network or given range if IP addresses and provides the MAC-to-IP mapping. To scan a whole network you can run <span style="font-family: "courier new" , "courier" , monospace;">arp-scan --interface ${bridge_name} -l</span> , for larger networks you should provide IP address range to reduce time and memory footprint:<br /><span style="font-family: "courier new" , "courier" , monospace;">arp-scan --interface ${brige_name} ${low_ip_limit}-${high_ip_limit}</span> .</span><br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif;">So the complete bash script for getting virtual machine's IP address could look like this (for libvirt and br0 NIC):</span><br />
<br />
<div dir="ltr" id="docs-internal-guid-00f9c425-6161-6cd0-4d0a-e30685d41b43" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: blue; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">#!/bin/bash</span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: blue; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">vm_name=$1</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: blue; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">bridge_name="br0"</span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: blue; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">mac_address=`virsh dumpxml ${vm_name} | grep "mac address" | cut -d "'" -f 2`</span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: blue; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">arp_scan_record=`arp-scan --interface ${bridge_name} -l | grep $mac_address`</span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: blue; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">ip_address=`echo -n ${arp_scan_record} | cut -d " " -f 1`</span></div>
<br />
<span style="background-color: transparent; color: blue; font-family: "courier new"; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">echo -n "${ip_address}"</span><span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-46443153822746287072015-10-15T17:03:00.000+02:002015-10-16T10:56:54.413+02:00Moving TeamCity Build to Remote Agent<br />
As we added more build configuration to our <a href="https://www.jetbrains.com/teamcity/" target="_blank">TeamCity </a>server, it was soon too much for the machine hosting it. Having a spare machine we decided to move some build to this new machine to lift the burden from our TeamCity's shoulders.<br />
<br />
It was also opportunity to look at <a href="https://confluence.jetbrains.com/display/TCD9/Developing+TeamCity+Plugins" target="_blank">TeamCity plugins</a> in general an specifically at so called agent tools.<br />
<h3>
Pre-requisities </h3>
<ul>
<li>fresh installation of the Linux distribution of your choice</li>
<li>JDK</li>
<li>OpenSSH daemon for remote access </li>
</ul>
<h3>
Agent Push</h3>
On the target machine create an account for teamcity, e.g. teamcity - to make the maintenance easier use the same user/group name and id as on the machine hosting TeamCity.<br />
<br />
I wanted to use password-based authentication but avoid to disclose root password so I used the same credentials "push agent" as used for "run under". It worked up to the "su" point -- see below.<br />
<h4>
Problem: push fails with "Algorithm negotiation fail"</h4>
This is cause by the removal of unsafe algorithms from OpenSSH default configuration. Unfortunately the <a href="http://www.jcraft.com/jsch/" target="_blank">JSCH library</a> used by TeamCity still tries to use them and is refused.<br />
<br />
To make JSCH happy, you can enable weak key-exchage algorithms by adding following line to the <span style="font-family: "Courier New",Courier,monospace;"><b>/etc/ssh/sshd_config</b></span> file (diffie-hellman-group1-sha1 stands for 1024 bit DH with SHA1, diffie-hellman-group-exchange-sha1 for custom DH with SHA1):<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">KexAlgorithms diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1</span><br />
<br />
Please enable this line only for the agent push and make sure it is removed after that. It is <a href="https://youtrack.jetbrains.com/issue/TW-42759" target="_blank">broken in current TeamCity 9.1.3</a>.<br />
<br />
<h4>
Problem: "su: must be run from a terminal"</h4>
The whole error message looks similar to this: <br />
<br />
Remote agent installation failed: Command '[./bootstrapper.sh "http://myteamcity:8111" "/home/teamcity/BuildAgent" "some_security_token" "user" "password"]' was executed with error message(s): su: must be run from a terminal.<br />
<br />
There are <a href="https://youtrack.jetbrains.com/issues/TW?q=su%3A+must+be+run+from+a+terminal" target="_blank">several issues</a> associated with this error and I am not sure what is the proper solution at the time being - addding user teamcity to group sudo did not work. As I installed only one agent, I "solved" it by logging to the agent machine as the teamcity user, editing <b>name in <span style="font-family: "Courier New",Courier,monospace;">buildAgent.properties</span></b> and executing "<b><span style="font-family: "Courier New",Courier,monospace;">agent.sh start</span></b>".<br />
<br />
The last thing to do its to go to the <b>Agents tab</b> in TeamCity, check the agent's status, authorize it if it is not authorized and set compatible configuration so no build is run on the agent until it is really ready.<br />
<h3>
Agent Tools</h3>
TeamCity plugins can have both server and agent side. The agent-side plugins that do not load any classes into the runtime are called <b><a href="https://confluence.jetbrains.com/display/TCD9/Plugins+Packaging#PluginsPackaging-Tools" target="_blank">agent tools</a></b> - it is TeamCity way for distribution of binary files to agents.<br />
<br />
In your <span style="font-family: "Courier New",Courier,monospace;">.BuildServer/plugins</span> directory (default value) create directory <span style="font-family: "Courier New",Courier,monospace;">.tools</span>, if it is not there yet. Each <a href="https://confluence.jetbrains.com/display/TCD9/Installing+Agent+Tools" target="_blank">agent plugin then can put either zip file or directory with the tools to distribute</a> to all agents. The distribution starts in about 2 minutes. It is possible that a build configuration asociated with the agent is required to trigger the process.<br />
<br />
Create directory <span style="font-family: "Courier New",Courier,monospace;"><b>.BuildServer/plugins/.tools</b>/my_plugin </span>and put your scripts inside. The files should be accompanied with plugin descriptor <b><span style="font-family: "Courier New",Courier,monospace;">teamcity-plugin.xml</span></b> . If you do not create it, an empty one is created on the agent side. The distribution process removes executable bit from all files put into the directory -- to prevent it you have to list your executable in the descriptor under "executable-files":<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: #004a43;"><?</span><span style="color: maroon; font-weight: bold;">xml</span><span style="color: #004a43;"> </span><span style="color: #074726;">version</span><span style="color: #808030;">=</span><span style="color: maroon;">"</span><span style="color: #7d0045;">1.0</span><span style="color: maroon;">"</span><span style="color: #004a43;"> </span><span style="color: #074726;">encoding</span><span style="color: #808030;">=</span><span style="color: maroon;">"</span><span style="color: #0000e6;">UTF-8</span><span style="color: maroon;">"</span><span style="color: #004a43;">?></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">teamcity-agent-plugin</span> <span style="color: #666616;">xmlns</span><span style="color: purple;">:</span><span style="color: #074726;">xsi</span><span style="color: #808030;">=</span><span style="color: maroon;">"</span>http://www.w3.org/2001/XMLSchema-instance<span style="color: maroon;">"</span>
<span style="color: #666616;">xsi</span><span style="color: purple;">:</span><span style="color: #074726;">noNamespaceSchemaLocation</span><span style="color: #808030;">=</span><span style="color: maroon;">"</span><span style="color: #666616;">urn</span><span style="color: purple;">:</span><span style="color: #40015a;">schemas-jetbrains-com:teamcity-agent-plugin-v1-xml</span><span style="color: maroon;">"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">tool-deployment</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">layout</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">executable-files</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">include</span> <span style="color: #274796;">name</span><span style="color: #808030;">=</span><span style="color: maroon;">'</span><span style="color: #0000e6;">path_to_executable</span><span style="color: maroon;">'</span><span style="color: #a65700;">/></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">executable-files</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">layout</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">tool-deployment</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">teamcity-agent-plugin</span><span style="color: #a65700;">></span>
</pre>
<br />
The path is relative to the plugin directorty and you do not have to start it with "./".<br />
<br />
<h3>
Calling Your Agent Tools Script</h3>
<br />
Create a <b>build step of runner type "Command line"</b> and <b>set working directory of the step to %teamcity.tool.my_plugin%</b> . Then you can execute scripts relative to the plugin directory, .e.g. with "Command executable" set to "./helloWorld.py" .Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com1tag:blogger.com,1999:blog-3388693861049579757.post-24168920463168209042015-04-01T20:36:00.001+02:002020-06-13T21:58:03.350+02:00Better Looking TestNG Reports with ReportNGWe had a set of system tests using Selenium 2 <b>Webdriver</b> and I was not satisfied with the default <a href="http://testng.org/" target="_blank">TestNG</a> reports. I was looking for a way to make reports look better and provide all the information necessary for analysis of a test failure when is happens. There were two requirements :<br />
<ol>
<li>provide <b>nice, compact overview</b> </li>
<li>include <b>screenshot</b> of a moment of failure</li>
</ol>
First thing I tried was Allure framework - it creates very nice reports but I had to reject it after some trials because it the way it works it was incompatible with the existing tests and its also quite invasive.<br />
<br />
Fortunately I found <b><a href="http://reportng.uncommons.org/" target="_blank">ReportNG</a></b> after that. The default design might not be so fancy but it is still very good and it fits well into TestNG and our tests.<br />
<br />
First we had to <b>add </b>necessary <b>dependencies to </b>our <b>maven </b>POM:<br />
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.testng<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>testng<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>6.8.8<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.uncommons<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>reportng<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.1.4<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">exclusions</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">exclusion</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.testng<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>testng<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">exclusion</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">exclusions</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>com.google.inject<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>guice<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>3.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
</pre>
<br />
TestNG has several interfaces to hook into the test processing, the most interesting probably are <a href="http://testng.org/javadoc/org/testng/ITestListener.html" target="_blank">ITestListener</a>, <a href="http://testng.org/javadoc/org/testng/IConfigurationListener.html" target="_blank">IConfigurationListener</a>, and sometimes <a href="http://testng.org/javadoc/org/testng/IMethodInterceptor.html" target="_blank">IMethodInterceptor</a>. ReportNG add class HTMLReporter to that.<br />
<br />
To add a screenshot to the report, we need to save it <b>ITestListener.onContextFailure() </b>and pick it up<br />
in a custom <b>ReportNGUtils </b>-- for customization we need to provide custom Velocity context by overriding <b>createContext()</b> and passing custom ReportNGUtils implementation. <br />
<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">apache</span><span style="color: #808030;">.</span><span style="color: #004a43;">commons</span><span style="color: #808030;">.</span><span style="color: #004a43;">io</span><span style="color: #808030;">.</span><span style="color: #004a43;">FileUtils</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">apache</span><span style="color: #808030;">.</span><span style="color: #004a43;">velocity</span><span style="color: #808030;">.</span><span style="color: #004a43;">VelocityContext</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">openqa</span><span style="color: #808030;">.</span><span style="color: #004a43;">selenium</span><span style="color: #808030;">.</span><span style="color: #004a43;">OutputType</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">openqa</span><span style="color: #808030;">.</span><span style="color: #004a43;">selenium</span><span style="color: #808030;">.</span><span style="color: #004a43;">TakesScreenshot</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">openqa</span><span style="color: #808030;">.</span><span style="color: #004a43;">selenium</span><span style="color: #808030;">.</span><span style="color: #004a43;">WebDriver</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">testng</span><span style="color: #808030;">.</span><span style="color: #004a43;">IConfigurationListener</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">testng</span><span style="color: #808030;">.</span><span style="color: #004a43;">ITestContext</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">testng</span><span style="color: #808030;">.</span><span style="color: #004a43;">ITestListener</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">testng</span><span style="color: #808030;">.</span><span style="color: #004a43;">ITestResult</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">uncommons</span><span style="color: #808030;">.</span><span style="color: #004a43;">reportng</span><span style="color: #808030;">.</span><span style="color: #004a43;">HTMLReporter</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">io</span><span style="color: #808030;">.</span><span style="color: #004a43;">File</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">net</span><span style="color: #808030;">.</span><span style="color: #004a43;">URL</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">class</span> TestListener <span style="color: maroon; font-weight: bold;">extends</span> HTMLReporter
<span style="color: maroon; font-weight: bold;">implements</span> ITestListener, IConfigurationListener
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">protected</span> <span style="color: maroon; font-weight: bold;">static</span> <span style="color: maroon; font-weight: bold;">final</span> CustomReportNgUtils REPORT_NG_UTILS <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> CustomReportNgUtils<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;"><span style="color: #808030;">@</span>Override </span></pre>
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;"> protected</span> VelocityContext createContext<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
VelocityContext context <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">super</span><span style="color: #808030;">.</span>createContext<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: dimgrey;">// VelocityContext has three properties: meta, utils, messages </span>
<span style="color: dimgrey;">// - see AbstractReporter.createContext()</span>
context<span style="color: #808030;">.</span>put<span style="color: #808030;">(</span><span style="color: #0000e6;">"utils"</span><span style="color: #808030;">,</span> REPORT_NG_UTILS<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">return</span> context<span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: #3f5fbf;">/** Invoked when test method (method with annotation </span><span style="color: #7f9fbf; font-weight: bold;">@</span><span style="color: #3f5fbf;">Test) fails. */</span>
<span style="color: #808030;">@</span>Override
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: #bb7977;">void</span> onTestFailure<span style="color: #808030;">(</span>ITestResult testResult<span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #808030;">(</span>getWebDriver<span style="color: #808030;">(</span>testResult<span style="color: #808030;">)</span> <span style="color: #808030;">!</span><span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">null</span><span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
<span style="color: #bb7977; font-weight: bold;">File</span> scrFile <span style="color: #808030;">=</span> <span style="color: #808030;">(</span><span style="color: #808030;">(</span>TakesScreenshot<span style="color: #808030;">)</span> getWebDriver<span style="color: #808030;">(</span>testResult<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">
.</span>getScreenshotAs<span style="color: #808030;">(</span>OutputType<span style="color: #808030;">.</span>FILE<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977; font-weight: bold;">String</span> screenshotName <span style="color: #808030;">=</span> createScreenshotName<span style="color: #808030;">(</span>testResult<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977; font-weight: bold;">File</span> targetFile <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> <span style="color: #bb7977; font-weight: bold;">File</span><span style="color: #808030;">(</span>screenshotName<span style="color: #808030;">)</span><span style="color: purple;">;</span>
FileUtils<span style="color: #808030;">.</span>copyFile<span style="color: #808030;">(</span>scrFile<span style="color: #808030;">,</span> targetFile<span style="color: #808030;">)</span><span style="color: purple;">;</span> </pre>
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;"> </span></pre>
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;"> </span><span style="color: maroon; font-weight: bold;"><span style="color: #bb7977; font-weight: bold;">URL</span> scrUrl <span style="color: #808030;">= </span>new</span> <span style="color: #bb7977; font-weight: bold;">URL</span><span style="color: #808030;">(</span>getDriver<span style="color: #808030;">(</span>testResult<span style="color: #808030;">)</span><span style="color: #808030;">.</span>getCurrentUrl<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;"></span><span style="color: purple;">;</span> </pre>
<pre style="background: #ffffff; color: black;"> Screenshot screenshot <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> Screenshot<span style="color: #808030;">(</span>targetFile<span style="color: #808030;">,</span> srcUrl <span style="color: #808030;">)</span><span style="color: purple;">;</span>
testResult<span style="color: #808030;">.</span>setAttribute<span style="color: #808030;">(</span>Screenshot<span style="color: #808030;">.</span>KEY<span style="color: #808030;">,</span> screenshot<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: purple;">}</span>
<span style="color: dimgrey;">// ...</span>
<span style="color: purple;">}</span>
</pre>
<br />
Class Screenshot is a custom <b>class holding screenshot-related data</b>, bare bones version could looke as this: <br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">class</span> Screenshot
<span style="color: purple;">{</span>
<span style="color: dimgrey;">/* Name of {@link ITestResult} attribute for Screenshot. */</span>
<span style="color: maroon; font-weight: bold;">static</span> <span style="color: maroon; font-weight: bold;">final</span> <span style="color: #bb7977; font-weight: bold;">String</span> KEY <span style="color: #808030;">=</span> <span style="color: #0000e6;">"screenshot"</span><span style="color: purple;">;</span>
<span style="color: #3f5fbf;">/** File in which is the screenshot stored. */</span>
<span style="color: #bb7977; font-weight: bold;">File</span> file<span style="color: purple;">;</span>
<span style="color: #3f5fbf;">/** URL of a web application's page the screenshot captures. */</span>
<span style="color: #bb7977; font-weight: bold;">URL</span> url<span style="color: purple;">;</span>
<span style="color: purple;">}</span>
</pre>
<br />
Now we need to add the <b> custom ReportNGUtils implementation</b> which picks up contextual information (Screenshot instance in our case) and uses it to modify the report output.<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">util</span><span style="color: #808030;">.</span><span style="color: #004a43;">List</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">testng</span><span style="color: #808030;">.</span><span style="color: #004a43;">ITestResult</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">uncommons</span><span style="color: #808030;">.</span><span style="color: #004a43;">reportng</span><span style="color: #808030;">.</span><span style="color: #004a43;">ReportNGUtils</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">class</span> CustomReportNgUtils <span style="color: maroon; font-weight: bold;">extends</span> ReportNGUtils
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: #bb7977; font-weight: bold;">List</span><span style="color: #808030;"><</span><span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">></span> getTestOutput<span style="color: #808030;">(</span>ITestResult testResult<span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
<span style="color: #bb7977; font-weight: bold;">List</span><span style="color: #808030;"><</span><span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">></span> output <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">super</span><span style="color: #808030;">.</span>getTestOutput<span style="color: #808030;">(</span>testResult<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #808030;">(</span> testResult<span style="color: #808030;">.</span>getAttribute<span style="color: #808030;">(</span>Screenshot<span style="color: #808030;">.</span>KEY<span style="color: #808030;">)</span> <span style="color: #808030;">!</span><span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">null</span> <span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
Screenshot screenshot <span style="color: #808030;">=</span> <span style="color: #808030;">(</span>Screenshot<span style="color: #808030;">)</span> testResult<span style="color: #808030;">.</span>getAttribute<span style="color: #808030;">(</span>Screenshot<span style="color: #808030;">.</span>KEY<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977; font-weight: bold;">String</span> screenshotFileName <span style="color: #808030;">=</span> screenshot<span style="color: #808030;">.</span>getFile<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">.</span>getName<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #808030;">(</span>screenshot <span style="color: #808030;">!</span><span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">null</span><span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
<span style="color: #bb7977; font-weight: bold;">String</span> url <span style="color: #808030;">=</span> <span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">)</span> testResult<span style="color: #808030;">.</span>getAttribute<span style="color: #808030;">(</span><span style="color: #0000e6;">"screenshotUrl"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
output<span style="color: #808030;">.</span>add<span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">.</span>format<span style="color: #808030;">(</span><span style="color: #0000e6;">"screenshot for %s %s <br/><img src='../screenshots/%s'>"</span><span style="color: #808030;">,</span>
testResult<span style="color: #808030;">.</span>getName<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span> url<span style="color: #808030;">,</span> screenshotFileName<span style="color: #808030;">)</span>
<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: purple;">}</span>
<span style="color: maroon; font-weight: bold;">return</span> output<span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: purple;">}</span>
</pre>
<br />
The final step is to <b>register test listener</b> in the plugin executing the tests. We use <a href="https://maven.apache.org/surefire/maven-failsafe-plugin/" target="_blank">failsafe</a>, the configuration for surefire is similar if you desire to use it.<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">build</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">plugins</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.apache.maven.plugins<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>maven-failsafe-plugin<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">configuration</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">systemPropertyVariables</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">org.uncommons.reportng.escape-output</span><span style="color: #a65700;">></span> </pre>
<pre style="background: #ffffff; color: black;"> false<span style="color: #a65700;"> </span></pre>
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"> </</span><span style="color: #5f5035;">org.uncommons.reportng.escape-output</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">systemPropertyVariables</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">summaryFile</span><span style="color: #a65700;">></span>${project.build.directory}/failsafe-reports/<span style="background-color: #e4e4ff;">failsafe-summary.xml</span><span style="color: #a65700;"></</span><span style="color: #5f5035;">summaryFile</span><span style="color: #a65700;">></span></pre>
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"> <span style="color: #a65700;"><</span><span style="color: #5f5035;">testClassesDirectory</span><span style="color: #a65700;">></span></span>${project.build.directory}/classes<span style="background-color: #e4e4ff;"></span><span style="color: #a65700;"><span style="color: #a65700;"></</span></span><span style="color: #a65700;"><span style="color: #a65700;"><span style="color: #a65700;"><span style="color: #5f5035;">testClassesDirectory</span></span></span><span style="color: #a65700;">></span> </span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">properties</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">property</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>usedefaultlisteners<span style="color: #a65700;"></</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">value</span><span style="color: #a65700;">></span>false<span style="color: #a65700;"></</span><span style="color: #5f5035;">value</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">property</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">property</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>listener<span style="color: #a65700;"></</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">value</span><span style="color: #a65700;">></span>
org.bithill.test.testng.TestListener
<span style="color: #a65700;"></</span><span style="color: #5f5035;">value</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">property</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">properties</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">suiteXmlFiles</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">suiteXmlFile</span><span style="color: #a65700;">></span>src/main/resources/suiteX.xml<span style="color: #a65700;"></</span><span style="color: #5f5035;">suiteXmlFile</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">suiteXmlFiles</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">configuration</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">executions</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">execution</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">id</span><span style="color: #a65700;">></span>integration-test<span style="color: #a65700;"></</span><span style="color: #5f5035;">id</span><span style="color: #a65700;">></span> </pre>
<pre style="background: #ffffff; color: black;"> <span style="color: #a65700;"><</span><span style="color: #5f5035;">phase</span><span style="color: #a65700;">></span>integration-test<span style="color: #a65700;"></</span><span style="color: #5f5035;">phase</span><span style="color: #a65700;">></span></pre>
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"> </span> <span style="color: #a65700;"><</span><span style="color: #5f5035;">goals</span><span style="color: #a65700;">></span> <span style="color: #a65700;"><</span><span style="color: #5f5035;">goal</span><span style="color: #a65700;">></span>integration-test<span style="color: #a65700;"></</span><span style="color: #5f5035;">goal</span><span style="color: #a65700;">></span> <span style="color: #a65700;"></</span><span style="color: #5f5035;">goals</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">execution</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">execution</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">id</span><span style="color: #a65700;">></span>verify<span style="color: #a65700;"></</span><span style="color: #5f5035;">id</span><span style="color: #a65700;">></span> </pre>
<pre style="background: #ffffff; color: black;"> <span style="color: #a65700;"><</span><span style="color: #5f5035;">phase</span><span style="color: #a65700;">></span>verify<span style="color: #a65700;"></</span><span style="color: #5f5035;">phase</span><span style="color: #a65700;">></span></pre>
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"> </span> <span style="color: #a65700;"><</span><span style="color: #5f5035;">goals</span><span style="color: #a65700;">></span> <span style="color: #a65700;"><</span><span style="color: #5f5035;">goal</span><span style="color: #a65700;">></span>verify<span style="color: #a65700;"></</span><span style="color: #5f5035;">goal</span><span style="color: #a65700;">></span> <span style="color: #a65700;"></</span><span style="color: #5f5035;">goals</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">execution</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">executions</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugins</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">build</span><span style="color: #a65700;">></span> </pre>
<pre style="background: #ffffff; color: black;"> </pre>
And that's all - when you run '<b>mvn failsafe:integration-test</b>' the tests are run, then you follow with '<b>mvn failsafe:verify</b>', which processes the results of the integration tests and generates a report and sets proper build result. Note that set the <b>testClassesDirectory </b>si crucial if you have it different than the expected 'test-classes'.Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-6487679050726431212015-03-28T22:02:00.002+01:002020-06-13T21:58:03.350+02:00Book Review: Mastering Apache Maven 3When I got my hands on <b><a href="https://www.packtpub.com/application-development/mastering-apache-maven-3" target="_blank">Mastering Apache Maven 3</a> by Prabath Siriwardena</b>, I was sceptical at first, thinking it would be another half-cooked product trying to make up for lack of information with funny stories.<br />
<br />
I am glad I can say that's not this case at all. The book is very good and covers all aspects of Maven in satisfactory level. Any developer who wants to us Maven efficiently will probably benefit from reading it and it useful also as comprehensive Maven reference. Yes, as a natural nit-picker I found some things missing but it the number of such things was surprisingly low.<br />
<br />
What is even better it goes directly to the point, not wasting paper and my time on funny stories, jokes, or other filler stuff.<br />
<br />
<br />
You will find in it description of POM (Project Object Model), various Maven configuration options, life cycle, description of several the most popular plug-ins, assemblies, archetypes, and repository management. The final chapter about the best practices would have saved from some pain in past if I had it. <br />
<br />
I will definitively find it place in my bookcase.Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-74669018732399553092015-01-11T16:45:00.001+01:002020-06-13T21:42:45.551+02:00DIY Wi-Fi Access Point on Linux<h3>
Hardware</h3>
From local vendor I bought PCI Express card with <b><a href="https://wikidevi.com/wiki/Atheros" target="_blank">Atheros</a> AR9485</b> chip complying to IEEE <a href="http://en.wikipedia.org/wiki/IEEE_802.11">802.11n</a>. It should be versatile and <a href="http://wireless.kernel.org/en/users/Drivers" target="_blank">well-supported</a> via <b>ath9k</b> Linux kernel driver.<br />
<br />
In case you are interested in the particular device, it is <a href="https://wikidevi.com/wiki/TP-LINK_TL-WN781ND_v2" target="_blank">TP-LINK TL-WN781N</a>. <br />
<h3>
Kernel </h3>
Naturally you must have some decently recent kernel and enabled support for wireless networking, your Wi-Fi chip and bridging (will be explained later).<br />
The more or less relevant config options on my machine looks this way:<br />
<br />
<div font-size="80%">
<pre>Networking support --->
Networking options --->
<M> 802.1d Ethernet Bridging
-*- Wireless --->
<M> cfg80211 - wireless configuration API
[*] enable powersave by default
<M> Generic IEEE 802.11 Networking Stack (mac80211)
-*- Enable LED triggers
<M> RF switch subsystem support
Device Drivers --->
[*] Network device support --->
Wireless LAN --->
<M> Atheros Wireless Cards ---->
<M> Atheros 802.11n wireless cards support
[*] Atheros ath9k PCI/PCIe bus support
-*- Enable LED triggers -->
{M} LED Class Support
-*- LED Trigger support
</pre>
</div>
<h3>
Bridging Wi-Fi and Ethernet </h3>
To connect clients connecting to our Access Point we need to bridge our existing wired ethernet device <b>eth0</b> and the wireless one, names <b>wlp1s0</b> in my case.<br />
<br />
<h3>
Enable IP Forwarding </h3>
Once we have the support in kernel, we should enable it by default, that is done on Gentoo Linux by editing <b>/etc/sysctl.conf</b> and setting <b>net.ipv4.ip_forward = 1</b>.<br />
<br />
You should also install <b>bridge-utils</b>, containing brtctl utility that can be used to query and change setting of ethernet bridges on your machine.<br />
<br />
<h3>
Setup Ethernet Bridge</h3>
Then you can adapt your network configuration. I did it by moving all configuration from eth0 to my bridge, called <b>br0</b>, and add eth0 to it at the boot time. There should also be configuration for the wireless device but we do not want to add it to the bridge on boot - that's what will <b>hostapd</b> take care for.<br />
<br />
So my <b>/etc/conf.d/net</b> looks this way after the above described changes:<br />
<br />
<div font-size="80%">
<pre>modules=("ifconfig")
# wired
config_eth0="null"
# wireless
modules_wlp1s0="!iwconfig !wpa_supplicant"
config_wlp1s0="null"
channel_wlp1s0="6"
essid_wlp1s0="MY_SSID"
mode_wlp1s0="master"
# bridge
config_br0="192.168.1.250/24"
routes_br0="default via 192.168.1.254"
dns_servers_br0="192.168.1.250" #pdnsd
bridge_br0="eth0" # adding eth0 to the bridge on boot
</pre>
</div>
<br />
Your configuration will probably vary, e.g. setup of the DNS server, namely using caching DNS server <a href="http://members.home.nl/p.a.rombouts/pdnsd/index.html" target="_blank">pdnsd</a>, would differ.<br />
<br />
<h3>
</h3>
Don't forget to <b>add net.br0 to the startup scripts for default</b> run level oor you'll end with machine without network at all.<br />
<br />
<h3>
Access Point</h3>
The final piece in the puzzle is <b><a href="http://w1.fi/hostapd/" target="_blank">hostapd</a></b> - the utility that attaches to your wireless device and changes it to Wi-Fi AP. You have to adapt its config (<b>/etc/hostapd/hostapd.conf</b> on my machine) to you needs - make sure that the settings match what you have in your network configuration:<br />
<br />
<div font-size="80%">
<pre>interface=wlp1s0</pre>
<pre>bridge=br0</pre>
<pre>ssid=MY_SSID </pre>
<pre> </pre>
</div>
I also set country_code in hope that it will help me to meet wireless regulations and hw_mode. For security I set wpa (set to 2, to avoid weak WPA 1) and wpa_passphrase. All the configuration options are well-documented so take you time and read it - further details are easily available in wikis on internet.<br />
<br />
The final set is to test hostapd setup and to <b>add hostapd to startup scripts for default</b> run level. <br />
<br />
<h3>
Reboot</h3>
If you did everything right, you can reboot. Boot will bring up eth0, then br0 and add eth0 to it, the hostapd kicks in bringing up the wireless device and adding it to the bridge - once done, AP starts to advertise itself and you can connect using predefined pass-phrase.<br />
<br />
I hope I did not mess things too much as I am newbie to Wi-Fi, and this how-to will help you a bit.Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-20035499451457697082014-09-21T22:18:00.000+02:002020-06-13T21:46:03.209+02:00Lookup Methods in EnumsThere is often the need to map numeric values of a Java enum to the enum instances, aka lookup.<br />
It seems as a simple task yet I saw and even used different approaches until finally came with something acceptable. Below is short comparison of witnessed approaches, ending with what I see as the best one.<br />
<br />
<hr />
<br />
First the list approaches I tried (or witnessed) and refused. <br />
In the following examples the numeric value to look-up is in variable <b>code</b>, method <b>getCode()</b> returns the numeric value of the enumeration instance.<br />
<br />
<h3>
Rummaging Through the Values Using For Loop</h3>
<pre><span style="color: maroon; font-weight: bold;">for</span>(EnumType value : values)
{
if (value.getCode()==code) { return value; }
}</pre>
<br />
Pros: zero maintenance<br />
Cons: waste of cycles<br />
<br />
<h3>
Look-up Values Hard-Coded in the Switch Statement </h3>
<pre><span style="color: maroon; font-weight: bold;">public static</span> EnumType fromInt (int code)
{
EnumType result = UNKNOWN; // fallback value
<span style="color: maroon; font-weight: bold;">switch</span> (code)
{
case 1: result = ENUM_ONE; break;
//...
}
<span style="color: maroon; font-weight: bold;">return</span> result;
}
</pre>
<br />
Pros: fast lookup<br />
Cons: needs maintenance, needs test for assuring the conversion is reflexive (all known values are converted to proper instances)<br />
<br />
<h3>
Storing Values in Hard-Coded Map</h3>
<pre><span style="color: maroon; font-weight: bold;">private static</span> Map<Integer,EnumType> lookupMap = new HashMap<>()<span style="color: maroon; font-weight: bold;">
static</span>
{
lookupMap.put(1,ENUM_ONE);
lookupMap.put(2,ENUM_TWO);
}
<span style="color: maroon; font-weight: bold;">public static</span> EnumType fromInt (int code)
{
<span style="color: maroon; font-weight: bold;">return</span> lookupMap.get(code);
} </pre>
<pre> </pre>
Pros: fast lookup<br />
Cons: needs maintenance<br />
<br />
<hr />
<h3>
Using Load-Time Constructed Map</h3>
The solution merges fast lookup with zero maintenance - it is based on a <b>Map populated with values in static initialization block</b>. This is possible to do for enums as at the moment when the map is going to be filled, all the enum constants are already instantiated (guaranteed by JVM).<br />
<pre><span style="color: maroon; font-weight: bold;">private static</span> Map<Integer,EnumType> lookupMap;
<span style="color: maroon; font-weight: bold;">static</span>
{
EnumType[] values = values();
lookupMap = <span style="color: maroon; font-weight: bold;">new</span> HashMap<Integer,EnumType>(values.length);
<span style="color: maroon; font-weight: bold;">for</span> (EnumType value : values)
{
lookupMap.put(value.getCode(),value);
}
}
<span style="color: maroon; font-weight: bold;">public static</span> EnumType fromInt (int code)
{
<span style="color: maroon; font-weight: bold;">return</span> lookupMap.get(code);
}
</pre>
Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-63074367486919346392014-07-17T23:48:00.001+02:002020-06-25T01:47:48.808+02:00Git with Attlasian Stash via SSH, on WindowsI do not know why Atlassian decided to name the thing Stash when there was Git stash, probably some "clever" marketing.<br />
<br />
I used Git for some time but just recently I had to use the SSH protocol on Windows to authenticate to Stash. Integrating Linux-born software to Windows environment is sometimes easy but that was not this case - to prevent more people to curse Git because of that, I made the following HOWTO.<br />
<br />
<h3>
Install Git</h3>
First of all you need to <b>install Git</b> and configure access using SSH protocol. I decided to not try anything fancy and downloaded the <a href="http://git-scm.com/downloads" target="_blank">standard git client installation file</a>. There is several dialogs during installation, I recommend to use "<b>Run Git from Windows Command Prompt</b>" in the "Adjusting PATH Environment"second dialog. The most important option is "Choosing SSH executable" - select "<b>Use OpenSSH</b>" - the Git will then use OpenSSH included in GIT installation.<br />
<br />
I installed Git into directory C:\git, feel free to choose installation path that suites your needs. I would recommend to avoid using path wit space though.<br />
<br />
When finished, open powershell console and go to directory to <span style="font-family: "Courier New",Courier,monospace;">C:\git\bin.</span><br />
<br />
<h3>
Generate SSH Keys </h3>
Following command generates new pair of keys (private will stay with you and public will be given later to Stash for you authentication).<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">C:\git\bin> <b>.\ssh-keygen.exe -t rsa -C your.email@address.com</b></span><br />
<br />
Set basic key file name to <span style="font-family: "Courier New",Courier,monospace;">C:\git\bin\id_rsa</span> when asked for the keys. To make things simple, use empty pass-phrase (you can fortify your setup later when you get more familiar with OpenSSH). The conversation with ssh-keygen should look like this:<br />
<br />
<span style="color: #666666;"><span style="font-family: "Courier New",Courier,monospace;">Generating public/private rsa key pair.<br />Enter file in which to save the key (//.ssh/id_rsa): C:\git\bin\id_rsa<br />Enter passphrase (empty for no passphrase):<br />Enter same passphrase again:<br />Your identification has been saved in <span style="color: black;"><b>C:\git\bin\id_rsa</b></span>.<br />Your public key has been saved in <span style="color: black;"><b>C:\git\bin\id_rsa.pub</b></span>.</span></span><br />
<br />
<h3>
Configure Bundled OpenSSH</h3>
Create directory C:\git\<b>.ssh</b> and move the newly created files id_rsa (private key) and id_rsa.pub (public key) into it. Then create file C:\git\.<b>ssh\config</b> with following content:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><b>Host</b> stash.atlassian.com</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> HostName stash.atlassian.com<br /> <b>PreferredAuthentications publickey</b><br /> <b>IdentityFile /.ssh/id_rsa</b></span><br />
<br />
In case your company has its own Stash instance running, adapt the Host and HostName options accordingly.<br />
<br />
<h3>
Submit Public Key to Stash</h3>
Login to your Stash account. In the top right corner, from select from drop-down menu "Manage account". On left side of the page you should now see several links, click on "SSH Keys".<br />
<br />
Put content of your public key (id_rsa.pub) into the text of the provided form. Do not edit it the content at all. Removing, regardless if deliberate or accidental, of some white space characters, namely line breaks does not prevent Stash to accept the key but the authentication will fail.<br />
<br />
<h3>
Test Connection</h3>
<span style="font-family: Verdana,sans-serif;">First test the connection using only OpenSSH:</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">C:\git\bin> .\ssh.exe -v -T git@stash.atlassian.com -p 7999</span><br />
<br />
If everything works well, the output you get ends with sentences "Authentication succeeded." and probably also "Entering interactive session." If so, you can <b>move C:\git\bin\.ssh</b> directory to <span style="font-family: "Courier New",Courier,monospace;">C:\your_windows_login\</span> directory and retest that the connection still gets authenticated with the files in new location:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">C:\git\bin\ssh.exe -v -T git@stash.atlassian.com -p 7999</span><br />
<br />
<h3>
Clone</h3>
If everything worked as described so far you should be now able clone your Stash-hosted repository using instructions available from Stash profile or project page. <br />
<br />
<br />Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-63216727652317548762014-05-12T23:59:00.001+02:002020-06-13T21:46:03.210+02:00Testing REST Service in Spring Boot with RestTemplateI have decided to add my bit to <a href="http://projects.spring.io/spring-boot/" target="_blank">Spring Boot</a>'s well-deserved popularity -- one must appreciate how fast you can create a simple application without compromising the design.<br />
<br />
Of course, if you take your work seriously there is no way you can get by without tests. An example is better than hours of explaining -- below you see testing of real service (no mocks) running locally:<br />
<ul>
<li>in first case sending POST request to create a new record and creating an object to from the response</li>
<li>in second case GET request is send and the failure message is treaded as "raw" JSON</li>
</ul>
<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> com</span><span style="color: #808030;">.</span><span style="color: #004a43;">fasterxml</span><span style="color: #808030;">.</span><span style="color: #004a43;">jackson</span><span style="color: #808030;">.</span><span style="color: #004a43;">databind</span><span style="color: #808030;">.</span><span style="color: #004a43;">JsonNode</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> com</span><span style="color: #808030;">.</span><span style="color: #004a43;">fasterxml</span><span style="color: #808030;">.</span><span style="color: #004a43;">jackson</span><span style="color: #808030;">.</span><span style="color: #004a43;">databind</span><span style="color: #808030;">.</span><span style="color: #004a43;">ObjectMapper</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">junit</span><span style="color: #808030;">.</span><span style="color: #004a43;">Test</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">junit</span><span style="color: #808030;">.</span><span style="color: #004a43;">runner</span><span style="color: #808030;">.</span><span style="color: #004a43;">RunWith</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">boot</span><span style="color: #808030;">.</span><span style="color: #004a43;">test</span><span style="color: #808030;">.</span><span style="color: #004a43;">IntegrationTest</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">boot</span><span style="color: #808030;">.</span><span style="color: #004a43;">test</span><span style="color: #808030;">.</span><span style="color: #004a43;">SpringApplicationConfiguration</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">boot</span><span style="color: #808030;">.</span><span style="color: #004a43;">test</span><span style="color: #808030;">.</span><span style="color: #004a43;">TestRestTemplate</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">http</span><span style="color: #808030;">.</span><span style="color: #004a43;">HttpStatus</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">http</span><span style="color: #808030;">.</span><span style="color: #004a43;">ResponseEntity</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">test</span><span style="color: #808030;">.</span><span style="color: #004a43;">context</span><span style="color: #808030;">.</span><span style="color: #004a43;">junit4</span><span style="color: #808030;">.</span><span style="color: #004a43;">SpringJUnit4ClassRunner</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">test</span><span style="color: #808030;">.</span><span style="color: #004a43;">context</span><span style="color: #808030;">.</span><span style="color: #004a43;">web</span><span style="color: #808030;">.</span><span style="color: #004a43;">WebAppConfiguration</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">web</span><span style="color: #808030;">.</span><span style="color: #004a43;">client</span><span style="color: #808030;">.</span><span style="color: #004a43;">RestTemplate</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">io</span><span style="color: #808030;">.</span><span style="color: #004a43;">IOException</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">util</span><span style="color: #808030;">.</span><span style="color: #004a43;">Collections</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> static org</span><span style="color: #808030;">.</span><span style="color: #004a43;">hamcrest</span><span style="color: #808030;">.</span><span style="color: #004a43;">Matchers</span><span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> static org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">test</span><span style="color: #808030;">.</span><span style="color: #004a43;">util</span><span style="color: #808030;">.</span><span style="color: #004a43;">MatcherAssertionErrors</span><span style="color: #808030;">.</span><span style="color: #004a43;">assertThat</span><span style="color: purple;">;</span>
@RunWith (SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration (classes = Config.class)
@WebAppConfiguration
@IntegrationTest
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">class</span> UserControllerTest
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">final</span> <span style="color: #bb7977; font-weight: bold;">String</span> BASE_URL <span style="color: #808030;">=</span> <span style="color: #0000e6;">"http://localhost:9999/customer/"</span><span style="color: purple;">;</span>
<span style="color: #808030;">@</span>Test
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: #bb7977;">void</span> shouldCreateNewUser<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">final</span> <span style="color: #bb7977; font-weight: bold;">String</span> USER_NAME <span style="color: #808030;">=</span> <span style="color: #0000e6;">"Leif Ericson"</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">final</span> <span style="color: #bb7977; font-weight: bold;">String</span> USER_ADDRESS <span style="color: #808030;">=</span> <span style="color: #0000e6;">"Vinland"</span><span style="color: purple;">;</span>
User user <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> User<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
user<span style="color: #808030;">.</span>setName<span style="color: #808030;">(</span>USER_NAME<span style="color: #808030;">)</span><span style="color: purple;">;</span>
user<span style="color: #808030;">.</span>setAddress<span style="color: #808030;">(</span>USER_ADDRESS<span style="color: #808030;">)</span><span style="color: purple;">;</span>
RestTemplate rest <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> TestRestTemplate<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
ResponseEntity<span style="color: #808030;"><</span>User<span style="color: #808030;">></span> response <span style="color: #808030;">=</span>
rest<span style="color: #808030;">.</span>postForEntity<span style="color: #808030;">(</span>BASE_URL<span style="color: #808030;">,</span> user<span style="color: #808030;">,</span> User<span style="color: #808030;">.</span>class<span style="color: #808030;">,</span> Collections<span style="color: #808030;">.</span>EMPTY_MAP<span style="color: #808030;">)</span><span style="color: purple;">;</span>
assertThat<span style="color: #808030;">(</span> response<span style="color: #808030;">.</span>getStatusCode<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">,</span> equalTo<span style="color: #808030;">(</span>HttpStatus<span style="color: #808030;">.</span>CREATED<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
User userCreated <span style="color: #808030;">=</span> response<span style="color: #808030;">.</span>getBody<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
assertThat<span style="color: #808030;">(</span> userCreated<span style="color: #808030;">.</span>getId<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">,</span> notNullValue<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">)</span><span style="color: purple;">;</span>
assertThat<span style="color: #808030;">(</span> userCreated<span style="color: #808030;">.</span>getName<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">,</span> equalTo<span style="color: #808030;">(</span>CUSTOMER_NAME<span style="color: #808030;">)</span> <span style="color: #808030;">)</span><span style="color: purple;">;</span>
assertThat<span style="color: #808030;">(</span> userCreated<span style="color: #808030;">.</span>getAddress<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">,</span> equalTo<span style="color: #808030;">(</span>CUSTOMER_ADDRESS<span style="color: #808030;">)</span> <span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: #808030;">@</span>Test
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: #bb7977;">void</span> shouldFailToGetUnknownUser<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">throws</span> <span style="color: #bb7977; font-weight: bold;">IOException</span> <span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">final</span> <span style="color: #bb7977;">int</span> UNKNOWN_ID <span style="color: #808030;">=</span> <span style="color: #bb7977; font-weight: bold;">Integer</span><span style="color: #808030;">.</span>MAX_VALUE<span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">final</span> <span style="color: #bb7977; font-weight: bold;">String</span> EXPECTED_ANSWER_MESSAGE <span style="color: #808030;">=</span> <span style="color: #0000e6;">"user with id : '"</span> <span style="color: #808030;">+</span> UNKNOWN_ID<span style="color: #808030;">+</span> <span style="color: #0000e6;">"' does not exist"</span><span style="color: purple;">;</span>
RestTemplate rest <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> TestRestTemplate<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
ResponseEntity<span style="color: #808030;"><</span><span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">></span> response <span style="color: #808030;">=</span> rest<span style="color: #808030;">.</span>getForEntity<span style="color: #808030;">(</span>BASE_URL <span style="color: #808030;">+</span> UNKNOWN_ID<span style="color: #808030;">,</span> <span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">.</span>class<span style="color: #808030;">)</span><span style="color: purple;">;</span>
assertThat<span style="color: #808030;">(</span> response<span style="color: #808030;">.</span>getStatusCode<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">,</span> equalTo<span style="color: #808030;">(</span>HttpStatus<span style="color: #808030;">.</span>NOT_FOUND<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
ObjectMapper objectMapper <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> ObjectMapper<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
JsonNode responseJson <span style="color: #808030;">=</span> objectMapper<span style="color: #808030;">.</span>readTree<span style="color: #808030;">(</span>response<span style="color: #808030;">.</span>getBody<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
JsonNode messageJson <span style="color: #808030;">=</span> responseJson<span style="color: #808030;">.</span>path<span style="color: #808030;">(</span><span style="color: #0000e6;">"message"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
assertThat<span style="color: #808030;">(</span> messageJson<span style="color: #808030;">.</span>isMissingNode<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">,</span> is<span style="color: #808030;">(</span><span style="color: maroon; font-weight: bold;">false</span><span style="color: #808030;">)</span> <span style="color: #808030;">)</span><span style="color: purple;">;</span>
assertThat<span style="color: #808030;">(</span> messageJson<span style="color: #808030;">.</span>asText<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">,</span> equalTo<span style="color: #808030;">(</span>EXPECTED_ANSWER_MESSAGE<span style="color: #808030;">)</span> <span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: purple;">}</span>
</pre>
Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com2tag:blogger.com,1999:blog-3388693861049579757.post-17128041461661648582013-06-05T18:00:00.000+02:002020-06-13T21:46:03.209+02:00Resolving Properties With Spring<span style="font-family: Arial,Helvetica,sans-serif;">It is a well known (and not surprising at all) fact, that you can use properties in Spring. You can reference them in you application context configuration file(s), or by the new <a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/new-in-3.html">Spring 3 @Value annotation</a>.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span>
<span style="font-family: Arial,Helvetica,sans-serif;">In the XML config the reference to the property named "x.y.z" this simple: </span><br />
<pre><span style="color: #a65700;"><</span><span style="color: #5f5035;">bean</span> <span style="color: #274796;">name</span><span style="color: #808030;">="theBean"</span><span style="color: #0000e6;"></span><span style="color: #0000e6;"> class=</span><span style="color: #a65700;">"myBean"></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">property</span> <span style="color: #274796;">name</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">parameter</span><span style="color: #0000e6;">"</span> <span style="color: #274796;">value</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">${x.y.z}</span><span style="color: #0000e6;">"</span> <span style="color: #a65700;">/></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">bean</span><span style="color: #a65700;">></span>
</pre>
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">This is usually accompanied by the element from context namespace setting the name of the configuration file:</span><br />
<pre><span style="color: #a65700;"><</span><span style="color: #666616;">context</span><span style="color: purple;">:</span><span style="color: #5f5035;">property-placeholder</span> <span style="color: #274796;">location</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">classpath:app.properties</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">/></span>
</pre>
<br />
<div class="MsoNormal">
<span style="font-family: Arial,Helvetica,sans-serif;">This is good approach for simple scenarios. In a more complex setup things can get a bit unwieldy. </span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: Arial,Helvetica,sans-serif;">First of all <b>each occurrence of <context:property-placeholder> element causes creation of a new instance</b> of the class responsible for property names resolving - <a href="http://static.springsource.org/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html">PropertyPlaceholderConfigurer</a> instance. You can enjoy lot of fun with unresolved placeholders in your application, once the library you're using brings its application context configuration containing <context:property-placeholder>. Even if you set <span style="font-family: "Courier New",Courier,monospace;">ignoreUnresolvablePlaceholders</span></span><wbr></wbr><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;">=false</span> for the element, it does not change the fact you have multiple <a href="http://static.springsource.org/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html">PropertyPlaceholderconfigurer</a>s where you need only one.</span></div>
<span style="font-family: Arial,Helvetica,sans-serif;"><br /></span>
<span style="font-family: Arial,Helvetica,sans-serif;">You may want to the properties loaded by Spring to a Spring unaware class or further customize the property resolving. In such case you'll create a custom <a href="http://static.springsource.org/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html">PropertyPlaceholderConfigurer</a> ... and get more collisions with default ones created by the <context:property-placeholder>. </span><br />
<br />
<h3>
<span style="font-family: Arial,Helvetica,sans-serif;">Custom PropertyPlaceholderConfigurer</span></h3>
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The solution is simple, remove all the occurrences of <context:property-placeholder> and create a custom <a href="http://static.springsource.org/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html">PropertyPlaceholderConfigurer</a>, that will fulfill your desires. Example of one is below. The static method <span style="font-family: "Courier New",Courier,monospace;">getProperty()</span> can serve properties to </span><span style="font-family: Arial,Helvetica,sans-serif;">Spring unaware code.</span><br />
<br />
<pre><span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">beans</span><span style="color: #808030;">.</span><span style="color: #004a43;">factory</span><span style="color: #808030;">.</span><span style="color: #004a43;">config</span><span style="color: #808030;">.</span><span style="color: #004a43;">ConfigurableListableBeanFactory</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">beans</span><span style="color: #808030;">.</span><span style="color: #004a43;">factory</span><span style="color: #808030;">.</span><span style="color: #004a43;">config</span><span style="color: #808030;">.</span><span style="color: #004a43;">PropertyPlaceholderConfigurer</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">util</span><span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">class</span> MyPropertyResolver <span style="color: maroon; font-weight: bold;">extends</span> PropertyPlaceholderConfigurer
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">private</span> <span style="color: maroon; font-weight: bold;">static</span> Map<span style="color: #808030;"><</span><span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">,</span> <span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">></span> propertiesMap <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> HashMap<span style="color: #808030;"><</span><span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">,</span> <span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">></span><span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #808030;">@</span>Override
<span style="color: maroon; font-weight: bold;">protected</span> <span style="color: #bb7977;">void</span> processProperties
<span style="color: #808030;">(</span>ConfigurableListableBeanFactory beanFactory<span style="color: #808030;">,</span> <span style="color: #bb7977; font-weight: bold;">Properties</span> properties<span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">super</span><span style="color: #808030;">.</span>processProperties<span style="color: #808030;">(</span>beanFactory<span style="color: #808030;">,</span> properties<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">for</span> <span style="color: #808030;">(</span> <span style="color: #bb7977; font-weight: bold;">Object</span> propertyKey <span style="color: #808030;">:</span> properties<span style="color: #808030;">.</span>keySet<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
propertiesMap<span style="color: #808030;">.</span>put
<span style="color: #808030;">(</span>
propertyKey<span style="color: #808030;">.</span>toString<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span>
<span style="color: dimgrey;">// Spring 3.x</span>
resolvePlaceholder<span style="color: #808030;">(</span>propertyKey<span style="color: #808030;">.</span>toString<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span> properties<span style="color: #808030;">)</span>
<span style="color: dimgrey;">// for Spring 2.5 :</span>
<span style="color: dimgrey;">// parseStringValue(propertyKey.toString(), properties, Collections.EMPTY_SET)</span>
<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: purple;">}</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">static</span> <span style="color: #bb7977; font-weight: bold;">String</span> getProperty<span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">String</span> name<span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">return</span> propertiesMap<span style="color: #808030;">.</span>get<span style="color: #808030;">(</span>name<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: purple;">}</span></pre>
<pre><span style="color: purple;"> </span>
</pre>
<span style="font-family: Arial,Helvetica,sans-serif;">Following configuration of bean named appProperties provides setup for multiple property files - the last one is the application property file overriding default values provided by libraries. Option</span> <span style="font-family: "Courier New",Courier,monospace;">ignoreResorceNotFound</span><wbr></wbr><span style="font-family: "Courier New",Courier,monospace;">=true<span style="font-family: Arial,Helvetica,sans-serif;"> ensures that the missing files are not taken for an error.</span></span><br />
<pre><span style="color: #004a43;"><?</span><span style="color: maroon; font-weight: bold;">xml</span><span style="color: #004a43;"> </span><span style="color: #074726;">version</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #7d0045;">1.0</span><span style="color: #0000e6;">"</span><span style="color: #004a43;"> </span><span style="color: #074726;">encoding</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">UTF-8</span><span style="color: #0000e6;">"</span><span style="color: #004a43;">?></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">beans</span> <span style="color: #666616;">xmlns</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"http://www.springframework.org/schema/beans"</span>
<span style="color: #666616;">xmlns</span><span style="color: purple;">:</span><span style="color: #074726;">xsi</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span style="color: #666616;">xsi</span><span style="color: purple;">:</span><span style="color: #074726;">schemaLocation</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"http://www.springframework.org/schema/beans</span></pre>
<pre><span style="color: #0000e6;"> http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"</span><span style="color: #a65700;">></span>
<span style="color: dimgrey;"><!--</span><span style="color: dimgrey;"> load it early, provides properties to other classes </span><span style="color: dimgrey;">--></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">bean</span> <span style="color: #274796;">id</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">appProperties</span><span style="color: #0000e6;">"</span> <span style="color: #274796;">class</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">MyPropertyResolver</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">property</span> <span style="color: #274796;">name</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">ignoreResourceNotFound</span><span style="color: #0000e6;">"</span> <span style="color: #274796;">value</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">true</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">/></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">property</span> <span style="color: #274796;">name</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">locations</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">list</span><span style="color: #a65700;">></span>
<span style="color: dimgrey;"><!--</span><span style="color: dimgrey;"> Ordering matters, properties in the later loaded files </span>
<span style="color: dimgrey;"> override values from the previous files </span><span style="color: dimgrey;">--></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">value</span><span style="color: #a65700;">></span>classpath:lib.properties<span style="color: #a65700;"></</span><span style="color: #5f5035;">value</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">value</span><span style="color: #a65700;">></span>classpath:app.properties<span style="color: #a65700;"></</span><span style="color: #5f5035;">value</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">list</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">property</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">bean</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">beans</span><span style="color: #a65700;">></span>
</pre>
<br />
<h3>
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: small;">Adding to an Application Context</span></span></h3>
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The last thing you need to do to make it working is to put the bean into your application context and use it. Following setup for a web application ensures that the bean is instantiated ASAP during application context initialization.</span><br />
<pre><span style="color: #a65700;"><</span><span style="color: #5f5035;">web-app</span> <span style="color: #666616;">xmlns</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"http://java.sun.com/xml/ns/j2ee"</span> <span style="color: #274796;">version</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">2.4</span><span style="color: #0000e6;">"</span>
<span style="color: #666616;">xmlns</span><span style="color: purple;">:</span><span style="color: #074726;">xsi</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span style="color: #666616;">xsi</span><span style="color: purple;">:</span><span style="color: #074726;">schemaLocation</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">context-param</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">param-name</span><span style="color: #a65700;">></span>contextConfigLocation<span style="color: #a65700;"></</span><span style="color: #5f5035;">param-name</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">param-value</span><span style="color: #a65700;">></span>
classpath:spring-resources.xml
...
<span style="color: #a65700;"></</span><span style="color: #5f5035;">param-value</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">context-param</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">web-app</span><span style="color: #a65700;">></span>
</pre>
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">For command-line application it's very simple too:</span> <br />
<pre style="background: #ffffff; color: black;">ClassPathXmlApplicationContext appContext <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> ClassPathXmlApplicationContext<span style="color: #808030;">(</span>
<span style="color: maroon; font-weight: bold;">new</span> <span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">[</span><span style="color: #808030;">]</span> <span style="color: purple;">{</span><span style="color: #0000e6;">"spring-resources.xml"</span><span style="color: purple;">}</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
MyPropertyResolver resolver <span style="color: #808030;">=</span> <span style="color: #808030;">(</span>MyPropertyResolver<span style="color: #808030;">)</span> appContext<span style="color: #808030;">.</span>getBean<span style="color: #808030;">(</span><span style="color: #0000e6;">"appProperties"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
</pre>
Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com4tag:blogger.com,1999:blog-3388693861049579757.post-9870816712395869112013-03-27T01:12:00.000+01:002020-06-13T21:46:03.208+02:00Renamed Logback Config File for Web ApplicationThere are four frameworks frequently used for logging in Java - <a href="http://docs.oracle.com/javase/6/docs/api/java/util/logging/package-summary.html">java.util.logging aka JUL</a>, <a href="http://commons.apache.org/proper/commons-logging//">Apache Commons Logging aka JCL</a>, <a href="http://logging.apache.org/log4j/1.2/">log4j 1.x</a>, and <a href="http://www.slf4j.org/">slf4j</a>. I had "luck" to find them all used by a single web application.<br />
<br />
It was impossible to tell what component uses what logging API for what messages. To make the logging manageable I modified the code base to use SLF4J API with Logback - changes to several places in code were made and <a href="http://www.slf4j.org/legacy.html">bridges were added</a> for third-party libraries.<br />
<br />
The last request was to <b>name the configuration file uniquely</b> so it can be in the same directory with configuration files for other applications. The problem is Logback is not particularly flexible when it comes to the naming of its config files - it <a href="http://grepcode.com/file/repo1.maven.org/maven2/ch.qos.logback/logback-classic/1.0.9/ch/qos/logback/classic/util/ContextInitializer.java#116">looks for logback.groovy, for logback-test.xml, logback.xml</a> and then fails with JoranException.<br />
<br />
According to documentation, there is a system property logback.configurationFile that allows to set a different name for the file.<br />
<br />
It can be set on a command line (<span style="font-size: x-small;">java <b>-Dlogback.configurationFile=/path/to/config.xml</b></span>), but that is not what you want or can use for a web application. Usual way how to pass settings to a web application is to use <context-param> in <span style="font-family: "Courier New",Courier,monospace;">web.xml</span>:<br />
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">context-param</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">param-name</span><span style="color: #a65700;">></span>logback.configurationFile<span style="color: #a65700;"></</span><span style="color: #5f5035;">param-name</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">param-value</span><span style="color: #a65700;">></span>custom-logback.xml<span style="color: #a65700;"></</span><span style="color: #5f5035;">param-value</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">context-param</span><span style="color: #a65700;">></span> </pre>
<br />
The problem is that servlet context parameters are not copie<span style="color: #a65700;">d</span> into system properties, so SLF4J ContextInitializer ends up looking for the "usual suspects" and then gives up: <br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">ContextInitializer.autoConfig()<br /> -> findURLOfDefaultConfigurationFile()<br /> -> findConfigFileURLFromSystemProperties()<br /> // logback.configurationFile is not a system property, returns null: <br /> -> OptionHelper.getSystemProperty(CONFIG_FILE_PROPERTY)<br /> -> getResource("logback.groovy")<br /> -> getResource("logback-test.xml")<br /> -> getResource("logback.xml")<br /> : returns null <br /> -> 3/ BasicConfigurator.configure(loggerContext)</span></span><br />
<br />
<br />
<span style="font-family: inherit;">The solution is to get the context-param as soon as possible during web application initialization and pass it to JoranConfigurator. You have to <b>implement custom ServletContextListener and put the logic inside contextInitialized method</b>:</span><br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">class</span> CustomServletContextListener
<span style="color: maroon; font-weight: bold;">implements</span> ServletContextListener
<span style="color: purple;">{</span>
</pre>
<pre style="background: #ffffff; color: black;"><span style="color: #808030;"> @</span>Override
<span style="color: maroon; font-weight: bold;"> public</span> <span style="color: #bb7977;">void</span> contextInitialized<span style="color: #808030;">(</span>ServletContextEvent contextEvent<span style="color: #808030;">)</span>
<span style="color: purple;"> {</span>
<span style="color: #bb7977; font-weight: bold;">String</span> logbackConfigFile <span style="color: #808030;">=</span> contextEvent<span style="color: #808030;">.</span>getServletContext<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">.</span>getInitParameter<span style="color: #808030;">(</span><span style="color: #0000e6;">"logback.configurationFile"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977; font-weight: bold;">URL</span> configFileURL<span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #808030;">(</span>logbackConfigFile <span style="color: #808030;">!</span><span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">null</span><span style="color: #808030;">)</span>
<span style="color: purple;"> {</span>
configFileURL <span style="color: #808030;">=</span> <span style="color: #bb7977; font-weight: bold;">Thread</span><span style="color: #808030;">.</span>currentThread<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">.</span>getContextClassLoader<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">.</span>getResource<span style="color: #808030;">(</span>logbackConfigFile<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #808030;">(</span>configFileURL <span style="color: #808030;">!</span><span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">null</span><span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
JoranConfigurator configurator <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> JoranConfigurator<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
LoggerContext loggerContext <span style="color: #808030;">=</span> <span style="color: #808030;">(</span>LoggerContext<span style="color: #808030;">)</span> LoggerFactory<span style="color: #808030;">.</span>getILoggerFactory<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
loggerContext<span style="color: #808030;">.</span>reset<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
configurator<span style="color: #808030;">.</span>setContext<span style="color: #808030;">(</span>loggerContext<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">try</span> <span style="color: purple;">{</span> configurator<span style="color: #808030;">.</span>doConfigure<span style="color: #808030;">(</span>configFileURL<span style="color: #808030;">)</span><span style="color: purple;">;</span> <span style="color: purple;">}</span>
<span style="color: maroon; font-weight: bold;">catch</span> <span style="color: #808030;">(</span>JoranException ex<span style="color: #808030;">)</span> <span style="color: purple;">{</span> <span style="color: maroon; font-weight: bold;">throw</span> <span style="color: maroon; font-weight: bold;">new</span> <span style="color: #bb7977; font-weight: bold;">RuntimeException</span><span style="color: #808030;">(</span>ex<span style="color: #808030;">)</span><span style="color: purple;">;</span> <span style="color: purple;">}</span>
<span style="color: purple;">}</span>
<span style="color: purple;"> }</span>
<pre style="background: #ffffff; color: black;"> <span style="color: purple;"> }</span> </pre>
<pre style="background: #ffffff; color: black;"><span style="font-family: "Arial","sans-serif";">To be sure the initialization happens as soon as possible, <b>put the context listener to the top of the listeners list</b> in <span style="font-family: "Courier New",Courier,monospace;">web.xml</span>:
</span></pre>
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">listener</span><span style="color: #a65700;">></span><span style="color: #a65700;">
<</span><span style="color: #5f5035;">listener-class</span><span style="color: #a65700;">></span>org.bithill.CustomServletContextListener<span style="color: #a65700;"></</span><span style="color: #5f5035;">listener-class</span><span style="color: #a65700;">>
<</span><span style="color: #a65700;">/</span><span style="color: #5f5035;">listener</span><span style="color: #a65700;">></span>
</pre>
</pre>
Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com2tag:blogger.com,1999:blog-3388693861049579757.post-16147085498493803452012-10-21T18:37:00.000+02:002020-06-13T21:54:04.754+02:00Accessing Oracle User-Defined Type with Spring JDBCIt's not so long I wrote some single-purpose utility which called a stored procedure in Oracle database. The procedure returned as its result an user-defined data type.<br />
<br />
Definition of the type looked approximately as this one:<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">CREATE</span> <span style="color: maroon; font-weight: bold;">OR</span> <span style="color: maroon; font-weight: bold;">REPLACE</span> <span style="color: maroon; font-weight: bold;">TYPE</span> <span style="color: maroon; font-weight: bold;">Summary</span> <span style="color: maroon; font-weight: bold;">as</span> <span style="color: maroon; font-weight: bold;">OBJECT</span>
<span style="color: #808030;">(</span>
<span style="color: maroon; font-weight: bold;">ID</span> <span style="color: maroon; font-weight: bold;">Number</span><span style="color: #808030;">(</span><span style="color: #008c00;">10</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span>
Sum1 <span style="color: maroon; font-weight: bold;">NUMBER</span><span style="color: #808030;">(</span><span style="color: #008c00;">20</span><span style="color: #808030;">,</span><span style="color: #008c00;">3</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span>
Sum2 <span style="color: maroon; font-weight: bold;">NUMBER</span><span style="color: #808030;">(</span><span style="color: #008c00;">20</span><span style="color: #808030;">,</span><span style="color: #008c00;">3</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">CONSTRUCTOR</span> <span style="color: maroon; font-weight: bold;">FUNCTION</span> <span style="color: maroon; font-weight: bold;">Summary</span> <span style="color: maroon; font-weight: bold;">RETURN</span> SELF <span style="color: maroon; font-weight: bold;">AS</span> RESULT
<span style="color: #808030;">)</span><span style="color: #808030;">;</span>
</pre>
<br />
I could have specified the mappings between Oracle object and Java class by implementing the <a href="http://docs.oracle.com/javase/6/docs/api/java/sql/SQLData.html">SQLData interface</a>, the approach supported by <a href="http://static.springsource.org/spring-data/data-jdbc/docs/1.0.0.M1/reference/html/#datatypes.struct">Spring Data</a>. But I had only <b>Spring JDBC</b> available so I used the <a href="http://static.springsource.org/spring-framework/docs/3.2.0.M2/api/org/springframework/jdbc/core/SqlReturnType.html">SqlReturnType</a>.<br />
<br />
First Maven dependencies: <br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: #004a43;"><?</span><span style="color: maroon; font-weight: bold;">xml</span><span style="color: #004a43;"> </span><span style="color: #074726;">version</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #7d0045;">1.0</span><span style="color: #0000e6;">"</span><span style="color: #004a43;"> </span><span style="color: #074726;">encoding</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">UTF-8</span><span style="color: #0000e6;">"</span><span style="color: #004a43;">?></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">project</span> <span style="color: #666616;">xmlns</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #666616;">http</span><span style="color: purple;">:</span><span style="color: maroon; font-weight: bold;">//</span><span style="color: #5555dd;">maven.apache.org</span><span style="color: #40015a;">/POM/4.0.0</span><span style="color: #0000e6;">"</span>
<span style="color: #666616;">xmlns</span><span style="color: purple;">:</span><span style="color: #074726;">xsi</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #666616;">http</span><span style="color: purple;">:</span><span style="color: maroon; font-weight: bold;">//</span><span style="color: #5555dd;">www.w3.org</span><span style="color: #40015a;">/2001/XMLSchema-instance</span><span style="color: #0000e6;">"</span>
<span style="color: #666616;">xsi</span><span style="color: purple;">:</span><span style="color: #074726;">schemaLocation</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #666616;">http</span><span style="color: purple;">:</span><span style="color: maroon; font-weight: bold;">//</span><span style="color: #5555dd;">maven.apache.org</span><span style="color: #40015a;">/POM/4.0.0</span><span style="color: #0000e6;"> </span><span style="color: #666616;">http</span><span style="color: purple;">:</span><span style="color: maroon; font-weight: bold;">//</span><span style="color: #5555dd;">maven.apache.org</span><span style="color: #40015a;">/xsd/maven-4.0.0.xsd</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">modelVersion</span><span style="color: #a65700;">></span>4.0.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">modelVersion</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.bithill.projectx<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>MyTestUtil<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependencies</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>com.oracle.oracle<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>ojdbc14<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>10.2.0.4<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.springframework<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>spring-jdbc<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>3.0.7.RELEASE<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependencies</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">project</span><span style="color: #a65700;">></span> </pre>
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"> </pre>
The utility to read the data is really simple - just load the driver, define the <b>SimpleJdbcCall</b> and call it and get the result. Only thing you have to remember,is to register the hendler for the user-defined type.<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">jdbc</span><span style="color: #808030;">.</span><span style="color: #004a43;">core</span><span style="color: #808030;">.</span><span style="color: #004a43;">JdbcTemplate</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">jdbc</span><span style="color: #808030;">.</span><span style="color: #004a43;">core</span><span style="color: #808030;">.</span><span style="color: #004a43;">SqlOutParameter</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">jdbc</span><span style="color: #808030;">.</span><span style="color: #004a43;">core</span><span style="color: #808030;">.</span><span style="color: #004a43;">SqlParameter</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">jdbc</span><span style="color: #808030;">.</span><span style="color: #004a43;">core</span><span style="color: #808030;">.</span><span style="color: #004a43;">simple</span><span style="color: #808030;">.</span><span style="color: #004a43;">SimpleJdbcCall</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">jdbc</span><span style="color: #808030;">.</span><span style="color: #004a43;">datasource</span><span style="color: #808030;">.</span><span style="color: #004a43;">DriverManagerDataSource</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">sql</span><span style="color: #808030;">.</span><span style="color: #004a43;">SQLException</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> static java</span><span style="color: #808030;">.</span><span style="color: #004a43;">lang</span><span style="color: #808030;">.</span><span style="color: #004a43;">System</span><span style="color: #808030;">.</span><span style="color: #004a43;">out</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> static oracle</span><span style="color: #808030;">.</span><span style="color: #004a43;">jdbc</span><span style="color: #808030;">.</span><span style="color: #004a43;">OracleTypes</span><span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">class</span> Main
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">static</span> <span style="color: #bb7977;">void</span> main <span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">String</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span> args<span style="color: #808030;">)</span> <span style="color: maroon; font-weight: bold;">throws</span> <span style="color: #bb7977; font-weight: bold;">SQLException</span>
<span style="color: purple;">{</span>
<span style="color: #bb7977; font-weight: bold;">String</span> connectionString <span style="color: #808030;">=</span> args<span style="color: #808030;">[</span><span style="color: #008c00;">0</span><span style="color: #808030;">]</span><span style="color: purple;">;</span> <span style="color: dimgrey;">// JDBC URL</span>
DriverManagerDataSource ds <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> DriverManagerDataSource<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
ds<span style="color: #808030;">.</span>setDriverClassName<span style="color: #808030;">(</span><span style="color: #0000e6;">"oracle.jdbc.OracleDriver"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
ds<span style="color: #808030;">.</span>setUrl<span style="color: #808030;">(</span>connectionString<span style="color: #808030;">)</span><span style="color: purple;">;</span>
SimpleJdbcCall sumProcCall <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> SimpleJdbcCall<span style="color: #808030;">(</span><span style="color: maroon; font-weight: bold;">new</span> JdbcTemplate<span style="color: #808030;">(</span>ds<span style="color: #808030;">)</span><span style="color: #808030;">)</span>
<span style="color: #808030;">.</span>withSchemaName<span style="color: #808030;">(</span><span style="color: #0000e6;">"SCHEMA"</span><span style="color: #808030;">)</span><span style="color: #808030;">.</span>withCatalogName<span style="color: #808030;">(</span><span style="color: #0000e6;">"PKG"</span><span style="color: #808030;">)</span>
<span style="color: #808030;">.</span>withProcedureName<span style="color: #808030;">(</span><span style="color: #0000e6;">"GET_SUMMARY"</span><span style="color: #808030;">)</span>
<span style="color: #808030;">.</span>declareParameters
<span style="color: #808030;">(</span>
<span style="color: dimgrey;">// IN params</span>
<span style="color: maroon; font-weight: bold;">new</span> SqlParameter<span style="color: #808030;">(</span><span style="color: #0000e6;">"P_Id"</span><span style="color: #808030;">,</span> NUMBER<span style="color: #808030;">)</span><span style="color: #808030;">,</span>
<span style="color: maroon; font-weight: bold;">new</span> SqlParameter<span style="color: #808030;">(</span><span style="color: #0000e6;">"P_OrgUnit"</span><span style="color: #808030;">,</span> VARCHAR<span style="color: #808030;">)</span><span style="color: #808030;">,</span>
<span style="color: dimgrey;">// OUT params</span>
<span style="color: maroon; font-weight: bold;">new</span> SqlOutParameter<span style="color: #808030;">(</span><span style="color: #0000e6;">"P_Summary"</span><span style="color: #808030;">,</span> STRUCT<span style="color: #808030;">,</span> <span style="color: #0000e6;">"SUMMARY"</span><span style="color: #808030;">,</span> <span style="color: maroon; font-weight: bold;">new</span> SummaryHandler<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">)</span><span style="color: #808030;">,</span>
<span style="color: maroon; font-weight: bold;">new</span> SqlOutParameter<span style="color: #808030;">(</span><span style="color: #0000e6;">"P_err_msg"</span><span style="color: #808030;">,</span> VARCHAR<span style="color: #808030;">)</span><span style="color: #808030;">,</span>
<span style="color: maroon; font-weight: bold;">new</span> SqlOutParameter<span style="color: #808030;">(</span><span style="color: #0000e6;">"P_err_code"</span><span style="color: #808030;">,</span> NUMBER<span style="color: #808030;">)</span>
<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #808030;">(</span>Summary<span style="color: #808030;">)</span>sumProcCall<span style="color: #808030;">.</span>execute
<span style="color: #808030;">(</span> <span style="color: #bb7977; font-weight: bold;">Integer</span><span style="color: #808030;">.</span>valueOf<span style="color: #808030;">(</span><span style="color: #008c00;">1</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span><span style="color: #0000e6;">"ou.subsidiary1"</span><span style="color: #808030;">)</span><span style="color: #808030;">.</span>get<span style="color: #808030;">(</span><span style="color: #0000e6;">"P_Summary"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span> </pre>
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"> </pre>
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;">Here is the type handler converting the raw information from Oracle's STRUCT to a Java class.</pre>
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> oracle</span><span style="color: #808030;">.</span><span style="color: #004a43;">sql</span><span style="color: #808030;">.</span><span style="color: #004a43;">STRUCT</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">springframework</span><span style="color: #808030;">.</span><span style="color: #004a43;">jdbc</span><span style="color: #808030;">.</span><span style="color: #004a43;">core</span><span style="color: #808030;">.</span><span style="color: #004a43;">SqlReturnType</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">sql</span><span style="color: #808030;">.</span><span style="color: #004a43;">CallableStatement</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">sql</span><span style="color: #808030;">.</span><span style="color: #004a43;">SQLException</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">class</span> SummaryHandler <span style="color: maroon; font-weight: bold;">implements</span> SqlReturnType
<span style="color: purple;">{</span>
<span style="color: dimgrey;">// struct data from jdbc</span>
<span style="color: maroon; font-weight: bold;">private</span> <span style="color: #bb7977; font-weight: bold;">Object</span><span style="color: #808030;">[</span><span style="color: #808030;">]</span> data<span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: #bb7977; font-weight: bold;">Object</span> getTypeValue<span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">CallableStatement</span> cs<span style="color: #808030;">,</span> <span style="color: #bb7977;">int</span> paramIndex<span style="color: #808030;">,</span> <span style="color: #bb7977;">int</span> sqlType<span style="color: #808030;">,</span> <span style="color: #bb7977; font-weight: bold;">String</span> typeName<span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">throws</span> <span style="color: #bb7977; font-weight: bold;">SQLException</span>
<span style="color: purple;">{</span>
data <span style="color: #808030;">=</span> <span style="color: #808030;">(</span><span style="color: #808030;">(</span>STRUCT<span style="color: #808030;">)</span>cs<span style="color: #808030;">.</span>getObject<span style="color: #808030;">(</span>INDEX_OF_SUMMARY_PARAMETER<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">.</span>getAttributes<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
Summary result <span style="color: #808030;">=</span> <span style="color: maroon; font-weight: bold;">new</span> Summary
<span style="color: #808030;">(</span><span style="color: maroon; font-weight: bold;">new</span> SummaryLine<span style="color: #808030;">(</span> <span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">BigDecimal</span><span style="color: #808030;">)</span>data<span style="color: #808030;">[</span><span style="color: #008c00;">0</span><span style="color: #808030;">]</span><span style="color: #808030;">)</span> <span style="color: dimgrey;">/*, ...*/</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">return</span> result<span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: purple;">}</span>
</pre>
Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-74580222455690672922012-04-09T02:05:00.000+02:002020-06-13T21:46:03.210+02:00Using Smart Card as Keystore in Java, signingThis is the promised sequel of the article from September 8th 2011.<br />
It does not represent the only one way how to achieve the desired result, especially when it comes to manipulation with certificates and keys certificate management.<br />
<br />
<h3>
Loading Certificate into the Card</h3>
<br />
It seems that the easiest approach is to prepare the key store on disk and load it into the card when ready. For that we use mostly two tools - <b>openssl</b> to transform keys and certificates and <b>keytool</b> to manage the key store.<br />
<br />
<b>Create the key store on disk and fill with certificates</b><br />
<br />
Create a <b>private key entry</b>, i.e. a certificate containing a private key, by converting our certificate and private key to PKCS12 format: <span style="font-family: "Courier New",Courier,monospace;">openssl pkcs12 -export -out cert.<a href="http://en.wikipedia.org/wiki/X.509#Certificate_filename_extensions">p12</a> -in cert.<a href="http://en.wikipedia.org/wiki/X.509#Certificate_filename_extensions">pem</a> -inkey key.pem</span><br />
<br />
<div style="font-family: inherit;">
I used org.apache.commons.ssl.KeyStoreBuilder to build a keystore from the p12 file. T<span style="font-family: inherit;">he <span style="font-family: "Courier New",Courier,monospace;">password</span> is used both for decryption of private key and encryption of the newly created Java key store. </span> <br />
<span style="font-family: "Courier New",Courier,monospace;">java -cp commons-ssl.jar org.apache.commons.ssl.KeyStoreBuilder password cert.p12</span><br />
<div style="font-family: inherit;">
<br /></div>
</div>
Now you can check the content of the file-based key store: <span style="font-family: "Courier New",Courier,monospace;">keytool -keystore newkeystore.jks -list</span><br />
<br />
<b>Load the file-base key store into the card</b><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">keytool -keystore NONE -storetype PKCS11 -providerName SunPKCS11-OpenSC-PKCS11 -importkeystore -srckeystore newkeystore.jks</span><br />
<br />
Check the content of the on-card key store.<br />
<span style="font-family: "Courier New",Courier,monospace;">keytool -keystore NONE -storetype PKCS11 -providerName SunPKCS11-OpenSC-PKCS11 -list</span><br />
<br />
<h3>
Signing and Verification with the On-Card Certificate</h3>
<h3>
</h3>
<br />
All the error handling was intentionally removed to make following example shorter. I also skipped creation of PKCS7 signed messages - you can you Bouncy Castle <span style="font-family: "Courier New",Courier,monospace;">CMSSignedDataGenerator</span> for that easily.<br />
<br />
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"><span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">security</span><span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">security</span><span style="color: #808030;">.</span><span style="color: #004a43;">cert</span><span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">security</span><span style="color: #808030;">.</span><span style="color: #004a43;">cert</span><span style="color: #808030;">.</span><span style="color: #004a43;">Certificate</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">io</span><span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: purple;">;</span>
...
<span style="color: dimgrey;">// loading the key from file:</span>
KeyStore keyStore = KeyStore.getInstance("JCEKS")<span style="color: #808030;">;</span>
FileInputStream inputStream = new FileInputStream(storeFileName)<span style="color: #808030;">;</span>
keyStore.load(inputStream, storePassword.toCharArray())<span style="color: #808030;">;</span>
KeyStore.ProtectionParameter protectParameter = new KeyStore.PasswordProtection(certPass.toCharArray())<span style="color: #808030;">;</span> }
<span style="color: dimgrey;">// loading the key from token:</span>
KeyStore keyStore = KeyStore.getInstance("PKCS11")<span style="color: #808030;">;</span>
KeyStore.ProtectionParameter protectParameter = null<span style="color: #808030;">;</span>
keyStore.load(null, storePassword.toCharArray())<span style="color: #808030;">;</span>
<span style="color: dimgrey;">// the rest does not depend on the type of the store: </span>
String signatureAlgorithmName = "SHA1withRSA"<span style="color: #808030;">;</span>
KeyStore.Entry entry = keyStore.getEntry(alias, protectParam)<span style="color: #808030;">;</span>
boolean isPrivateKeyEntry = keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)<span style="color: #808030;">;</span>
if (isPrivateKeyEntry)
<span style="color: purple;">{</span>
<span style="color: #bb7977; font-weight: bold;">Signature</span> signatureAlgorithm <span style="color: #808030;">=</span> <span style="color: #bb7977; font-weight: bold;">Signature</span><span style="color: #808030;">.</span>getInstance<span style="color: #808030;">(</span>signatureAlgorithmName<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: dimgrey;">// signing</span>
KeyStore<span style="color: #808030;">.</span>PrivateKeyEntry privateKeyEntry <span style="color: #808030;">=</span> <span style="color: #808030;">(</span>KeyStore<span style="color: #808030;">.</span>PrivateKeyEntry<span style="color: #808030;">)</span>entry<span style="color: purple;">;</span>
<span style="color: #bb7977; font-weight: bold;">PrivateKey</span> privateKey <span style="color: #808030;">=</span> privateKeyEntry<span style="color: #808030;">.</span>getPrivateKey<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
signatureAlgorithm<span style="color: #808030;">.</span>initSign <span style="color: #808030;">(</span>privateKey<span style="color: #808030;">)</span><span style="color: purple;">;</span>
signatureAlgorithm<span style="color: #808030;">.</span>update <span style="color: #808030;">(</span>message<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977;">byte</span><span style="color: #808030;">[</span><span style="color: #808030;">]</span> signature <span style="color: #808030;">=</span> signatureAlgorithm<span style="color: #808030;">.</span>sign<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: dimgrey;">// verification</span>
<span style="color: #bb7977; font-weight: bold;">Certificate</span><span style="color: #808030;">[</span><span style="color: #808030;">]</span> chain <span style="color: #808030;">=</span> privateKeyEntry<span style="color: #808030;">.</span>getCertificateChain<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
X509Certificate certificate <span style="color: #808030;">=</span> <span style="color: #808030;">(</span>X509Certificate<span style="color: #808030;">)</span> chain<span style="color: #808030;">[</span>chain<span style="color: #808030;">.</span>length<span style="color: #808030;">-</span><span style="color: #008c00;">1</span><span style="color: #808030;">]</span><span style="color: purple;">;</span>
<span style="color: #bb7977; font-weight: bold;">PublicKey</span> publicKey <span style="color: #808030;">=</span> certificate<span style="color: #808030;">.</span>getPublicKey<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
signatureAlgorithm<span style="color: #808030;">.</span>initVerify<span style="color: #808030;">(</span>publicKey<span style="color: #808030;">)</span><span style="color: purple;">;</span>
signatureAlgorithm<span style="color: #808030;">.</span>update <span style="color: #808030;">(</span>data<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977;">boolean</span> verified <span style="color: #808030;">=</span> signatureAlgorithm<span style="color: #808030;">.</span>verify<span style="color: #808030;">(</span>signature<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
</pre>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-2413676057662034312012-02-23T18:10:00.000+01:002020-06-13T21:58:03.350+02:00Maven: Creating Executable JAR with Shade PluginI was pleasantly surprised by versatility of Maven <a href="http://maven.apache.org/plugins/maven-shade-plugin/index.html">shade plugin</a>. Creating a custom-named executable JAR and bundle only the dependencies you really need is a piece of cake. The documentation is partly is online, partly in the plugin's help and provides all necessary information. <br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.apache.maven.plugins<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>maven-shade-plugin<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.5<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">executions</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">execution</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">phase</span><span style="color: #a65700;">></span>package<span style="color: #a65700;"></</span><span style="color: #5f5035;">phase</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">goals</span><span style="color: #a65700;">></span><span style="color: #a65700;"><</span><span style="color: #5f5035;">goal</span><span style="color: #a65700;">></span>shade<span style="color: #a65700;"></</span><span style="color: #5f5035;">goal</span><span style="color: #a65700;">></span><span style="color: #a65700;"></</span><span style="color: #5f5035;">goals</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">configuration</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><b><span style="color: #5f5035;">outputFile</span></b><span style="color: #a65700;">></span>target/tool.jar<span style="color: #a65700;"></</span><b><span style="color: #5f5035;">outputFile</span></b><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactSet</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><b><span style="color: #5f5035;">includes</span></b><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">include</span><span style="color: #a65700;">></span>org.springframework:spring-core<span style="color: #a65700;"></</span><span style="color: #5f5035;">include</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">include</span><span style="color: #a65700;">></span>org.springframework:spring-beans<span style="color: #a65700;"></</span><span style="color: #5f5035;">include</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><b><span style="color: #5f5035;">includes</span></b><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactSet</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">transformers</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">transformer</span>
<span style="color: #274796;">implementation</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">org.apache.maven.plugins.shade.resource.ManifestResourceTransformer</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><b><span style="color: #5f5035;">mainClass</span></b><span style="color: #a65700;">></span>org.bithill.example.Tool<span style="color: #a65700;"></</span><b><span style="color: #5f5035;">mainClass</span></b><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">transformer</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">transformers</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">configuration</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">execution</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">executions</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
</pre>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-33430399909310206902011-12-05T01:23:00.000+01:002020-06-13T21:58:03.350+02:00Maven: The Aggregator vs. The ParentI have recently realized that even professionals working with Maven for extended period do not fully grasp the differences of Maven's aggregators and parents. The reason for that is probably that both terms are related to <b>multi-module</b> projects and that both approaches often 'meet' in single file.<br />
<br />
Multi-module projects usually have rather flat structure with a single top-level <span style="font-family: "Courier New",Courier,monospace;">pom.xml</span> file. That file than lists sub-modules and defines versions of dependencies and/or plugins inherited in these sub-modules. This is well-known thing - what is less known is that these roles of <span style="font-family: "Courier New",Courier,monospace;">pom.xml</span> can be separated.<br />
<br />
<span style="font-size: large;">Aggregator</span><br />
A top-level module serving for <b>joining multiple modules under one roof </b>is called <b><a href="http://maven.apache.org/pom.html#Aggregation">aggregator</a></b>. Its purpose is only represent more or less independently existing modules as a parts of a greater whole. <br />
<br />
Example of aggreator <span style="font-family: "Courier New",Courier,monospace;">pom.xml</span>:<br />
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">project</span> <span style="color: #666616;">xmlns</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #40015a;">...</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">modelVersion</span><span style="color: #a65700;">></span>4.0.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">modelVersion</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.bithill<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>aggregator<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">packaging</span><span style="color: #a65700;">></span>pom<span style="color: #a65700;"></</span><span style="color: #5f5035;">packaging</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>Project Aggregator<span style="color: #a65700;"></</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">modules</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">module</span><span style="color: #a65700;">></span>project1<span style="color: #a65700;"></</span><span style="color: #5f5035;">module</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">module</span><span style="color: #a65700;">></span>project2<span style="color: #a65700;"></</span><span style="color: #5f5035;">module</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">modules</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">project</span><span style="color: #a65700;">></span>
</pre><br />
<span style="font-size: large;">Parent</span><br />
<br />
As you see, aggegator does not include any information about dependencies. The <b>source of to-be-inherited information about libraries and plugins</b> is known as a <b>parent POM</b>. It includes all the properties, dependencyManagement and pluginManagement sections stating versions of projects dependencies and plugins and some plugin configurations when it comes handy. Ideally this information should be de-duplicated and inherited by plugins is sub-modules, but that does not apply to reporting plugins.<br />
<br />
Example of parent <span style="font-family: "Courier New",Courier,monospace;">pom.xml</span>:<span style="color: #a65700;"> </span><br />
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">project</span> <span style="color: #666616;">xmlns</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"...</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">modelVersion</span><span style="color: #a65700;">></span>4.0.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">modelVersion</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.bithill<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>parent<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">packaging</span><span style="color: #a65700;">></span>pom<span style="color: #a65700;"></</span><span style="color: #5f5035;">packaging</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>shared parent<span style="color: #a65700;"></</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">properties</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">java.version</span><span style="color: #a65700;">></span>1.6<span style="color: #a65700;"></</span><span style="color: #5f5035;">java.version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">spring.version</span><span style="color: #a65700;">></span>3.0.2.RELEASE<span style="color: #a65700;"></</span><span style="color: #5f5035;">spring.version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">properties</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependencyManagement</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependencies</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.slf4j<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>slf4j-api<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.6.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.springframework<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>spring-context<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>${spring.version}<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.springframework<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>spring-aop<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>${spring.version}<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependencies</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependencyManagement</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">build</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">pluginManagement</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">plugins</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.apache.maven.plugins<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>maven-compiler-plugin<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>2.3.2<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">configuration</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">source</span><span style="color: #a65700;">></span>${java.jdk.version}<span style="color: #a65700;"></</span><span style="color: #5f5035;">source</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">target</span><span style="color: #a65700;">></span>${java.jdk.version}<span style="color: #a65700;"></</span><span style="color: #5f5035;">target</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">configuration</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugins</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">pluginManagement</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">build</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">project</span><span style="color: #a65700;">></span>
</pre><br />
<span style="font-size: large;">Using Aggregator and Parent POM Together</span><br />
<br />
So we showed that we can have two different artificial POM files serving two different roles - aggregation and inheritance. <br />
<br />
<br />
Diagram of relationships in a project consisting of two sub-modules: <br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitMlT6v06HkfWBxlQBx-U4uktPDFivK1MsCCQDv-tjXEpoWps5peC1IU43Ybb53DkMUJVZSWusjE2q63AKv5UknRUWaN8mwY4r2RNtr_CO2aJtnrUB1LRojP2vjvHAby9z0-wwf8Ymc4px/s1600/aggregatoevsparent.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitMlT6v06HkfWBxlQBx-U4uktPDFivK1MsCCQDv-tjXEpoWps5peC1IU43Ybb53DkMUJVZSWusjE2q63AKv5UknRUWaN8mwY4r2RNtr_CO2aJtnrUB1LRojP2vjvHAby9z0-wwf8Ymc4px/s1600/aggregatoevsparent.png" /></a></div><br />
The last missing thing in the picture is an example of sub-module's <span style="font-family: "Courier New",Courier,monospace;">pom.xml</span>. As you see, no dependency or build plugin need to define their version - that is inherited from parent POM. Parent's <span style="font-family: "Courier New",Courier,monospace;">pom.xml</span> is deployed in Maven repository, but Maven's default relative path to parent is ".." - to avoid aggregator being used as parent, property <b>relativePath must be set empty</b>, this is probably the only trick here.<br />
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">project</span> <span style="color: #666616;">xmlns</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #40015a;">...</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">modelVersion</span><span style="color: #a65700;">></span>4.0.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">modelVersion</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.bithill<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>project1<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">packaging</span><span style="color: #a65700;">></span>pom<span style="color: #a65700;"></</span><span style="color: #5f5035;">packaging</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.6-SNAPSHOT<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>Project #1<span style="color: #a65700;"></</span><span style="color: #5f5035;">name</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">parent</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.bithill<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>parent<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.0<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<b><span style="color: #a65700;"><</span><span style="color: #5f5035;">relativePath</span><span style="color: #a65700;">/></span></b>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">parent</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependencies</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.springframework<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>spring-context<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.springframework<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>spring-aop<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependencies</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">build</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">plugins</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.apache.maven.plugins<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>maven-compiler-plugin<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugins</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">build</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">project</span><span style="color: #a65700;">></span>
</pre>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com6tag:blogger.com,1999:blog-3388693861049579757.post-88003478169009050652011-11-20T19:01:00.185+01:002020-06-13T21:58:03.351+02:00Book Review: Apache Maven 3 CookbookI have decided to review new book about Maven from Packt Publishing: <a href="http://www.packtpub.com/apache-maven-3-0-cookbook/book">Apache Maven 3 Cookbook</a> by Srirangan promising on its cover "Quick anwers to common problems".<br />
<br />
The book is divided to nine chapters:<br />
<ol>
<li>basics<br />
Maven installation and environment settings. Generating, compiling and testing simple project. POM structure, build lifecycle and profiles.</li>
<li>software engineering techniques<br />
Modularization, dependency management, static code analysis, JUnit, Selenium.</li>
<li>agile team collaboration<br />
Nexus, Hudson, version control, offline mode.</li>
<li>reporting and documentation<br />
Mvn site, javadocs, test and code quality reports, dahsboard.</li>
<li>Java development<br />
Building and running web application (jetty), JEE, Spring, Hibernate, Seam.</li>
<li>Google development<br />
Android, GWT, App Engine.</li>
<li>Scala, Groovy and Flex</li>
<li>IDE integration<br />
Eclipse, NetBeans, Intellij IDEA</li>
<li>extending Maven<br />
plugin development basics</li>
</ol>
The book is certainly not material for beginners. Some terms are used without former definition or even explaining. Experienced Maven users will already know or will be able to find the missing pieces but beginners must be terribly confused. I think providing at least a description of Maven's standard directory layout for project or repository would be beneficial. <br />
<br />
It is not so much about Maven as I expected, and says nothing about what is new in Maven 3. It should be exhaustive at least in the purely Maven parts, but even there is not enough information to make me happy. I would expect a description of template languages in the part dedicated to site plugin. <br />
<br />
If you like puzzles and do not mind to use internet to search for missing pieces or you just cannot recall some setting covered in the book, you will like the book. It can also be used as a good starting point to show what tools, frameworks or languages can be used from/with Maven - do you like Maven and wanted to try GWT or Scala ? The book helps to lower entrance barrier by providing examples how to get working "playground" project in no time.<br />
<br />
Would I buy it ? No. My bookcase has limited capacity and since the necessity to use internet to fill the gaps or correct bugs (although not many) in the book, I will be better with the online sources only.Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com2tag:blogger.com,1999:blog-3388693861049579757.post-27033031844962470542011-11-06T17:00:00.000+01:002020-06-13T21:51:21.260+02:00Shortcuts in Eclipse / Intellij Idea<span style="font-size: small;">I decided to publish this long ago started list of keyboard shortcuts for Eclipse and Intellij Idea to make the transition from one IDE to the other one easier for my colleague. I hope it will be useful for other developers in similar situation too. Where you see only one shortcut in the list, it means it is identical in both IDEs. </span><br />
<br />
<span style="font-weight: bold;"><span style="font-size: 130%;">List Shortcuts:</span></span><span style="font-size: 100%;"> Ctrl+Shift+L / ? (Help - Default Keymap Reference)</span><br />
<span style="font-weight: bold;"><span style="font-size: 130%;">Search Actions:</span></span><span style="font-size: 100%;"> ? / </span>Ctrl+Shift+A<br />
<span style="font-size: 130%;"> <span style="font-weight: bold;"><br />
Editor</span></span><br />
<br />
<span style="font-weight: bold;">Select All</span>: Ctrl+A<br />
<span style="font-weight: bold;">Reformat</span>: Ctrl+Shift+F / Ctrl+Alt+L<br />
<span style="font-weight: bold;">Open File By Name</span>: Ctrl+Shift+R / Ctrl+Shift+N<br />
<span style="font-weight: bold;">Open Class By Name</span>: Ctrl+Shift+T / Ctrl+N<br />
<b>Go to Matching Bracket</b>: Ctrl+Shift+P / Ctrl+{, Ctrl+}<br />
<b>Paste from Clipboard Stack</b>: ? / Ctrl+Shift+V<br />
<b>Vertical Blocks</b>: ? / Alt+Shift+Insert <br />
<br />
<span style="font-size: 130%;"><span style="font-weight: bold;">Code Navigation and Manipulation</span></span><br />
<br />
<b>Navigate Forward in History:</b> Alt+right arrow / Ctrl+Alt+right arrow<br />
<b>Navigate Backward in History:</b> Alt+left arrow / Ctrl+Alt+left arrow <br />
<br />
<b>Go to Line:</b> Ctrl+L / Ctrl+G<br />
<br />
<b>Delete Line:</b> Ctrl+D / Ctrl+Y<br />
<br />
<span style="font-weight: bold;">Open Documentation:</span> "mouse over" / Ctrl+Q<br />
<span style="font-weight: bold;">Open Declaration:</span> F3 / Ctrl+B<br />
<span style="font-weight: bold;">Open Hierarchy:</span> F4 / Ctrl+H<br />
<span style="font-weight: bold;">Find Implementation</span>: ? / Ctrl+Alt+ B<br />
<br />
<span style="font-weight: bold;">Find Usages:</span> Ctrl+Alt+G / Alt+F7<br />
<b>Usages Pop-Up</b>: ? / Ctrl-Alt-F7<br />
<br />
<span style="font-weight: bold;">Code Completion:</span> Ctrl+Space<br />
<span style="font-weight: bold;">Optimize Imports:</span> Ctrl+Shift+O / Ctrl+Alt+O<br />
<span style="font-weight: bold;">List of Methods to Override/Implement:</span> ? / Ctrl+O<br />
<span style="font-weight: bold;">Generate...:</span> Ctrl+Shift+G / Alt+Insert <br />
<br />
<b>Comment Line</b>: <span class="key">Ctrl + /</span><br />
<span class="key"><b>Comment Block</b>: </span><span class="key">Ctrl + Shift + /</span><span class="key"> </span><br />
<br />
<span class="key"><b>Code Fold</b>: </span><span class="key">Ctrl+"numpad +" / or Ctrl+"+"</span><span class="key"> </span><br />
<span class="key"><b>Code Unfold</b>: </span><span class="key">Ctrl+"numpad -" / Ctrl+"-"</span><span class="key"> </span><br />
<br />
<span class="key"><b>Move Code Up</b>: Alt+Up / Ctrl+Shift+Up</span><br />
<span class="key"><b>Move Code Down</b>: Alt+Down / Ctrl+Shift+Down</span><span class="key"> </span><br />
<br />
<span class="key"></span> <span class="key"><b>Create Test</b>: ? / Ctrl+Shift+T</span><span class="key"><br />
</span><br />
<span style="font-size: 130%;"><span style="font-weight: bold;">Refactoring</span></span><br />
<br />
<span style="font-weight: bold;">Rename:</span> Alt+Shift+R / Shift+F6<br />
<span style="font-weight: bold;">Extract Method:</span> Alt+Shift+M / Ctrl+Alt+M<br />
<span style="font-weight: bold;">Introduce Variable:</span> Ctrl+Shift+M / Ctrl+Alt+V<br />
<span style="font-weight: bold;"></span><br />
<span style="font-size: 130%;"><span style="font-weight: bold;">Search</span></span><br />
<br />
<span style="font-weight: bold;">In Current File:</span> Ctrl+F<br />
<span style="font-weight: bold;">In All Files</span>: Ctrl+H / Ctrl+Shift+F<br />
<br />
<span style="font-size: large;"><b>Version Control</b></span><br />
<br />
<b>Commit Changes</b>: Alt+C / Ctrl+K<br />
<b>Update</b>: Alt+U / Ctrl+T <br />
<b>VCS Popup</b>: ? / Alt+` (back qoute) <br />
<br />
<span style="font-size: 130%;"><span style="font-weight: bold;">Windows</span></span><br />
<br />
<span style="font-weight: bold;">Maximize:</span> Ctrl+M / Ctrl+Shift+F12<br />
<br />
<span style="font-size: 130%; font-weight: bold;">Debugging</span><br />
<br />
<span style="font-weight: bold;">Debug</span>: F11 / Shif+F9<br />
<span style="font-weight: bold;">Step Into</span>: F5 / F7<br />
<span style="font-weight: bold;">Selective/smart Step Into</span>: Ctrl+F5 / Shift+F7 <br />
<span style="font-weight: bold;">Step Over</span>: F6 / F8<br />
<span style="font-weight: bold;">Step Out</span>: F7 / Shift+F8<br />
<span style="font-weight: bold;">Resume</span>: F8 / F9<br />
<br />
<b>Evaluate Expression</b>: Ctrl+Shift+I / Alt+F8<br />
<br />
<span style="font-weight: bold;">Jump To Caller:</span> ? / Ctrl+Alt+F7<br />
<span style="font-weight: bold;">Show the Caller Hierarch</span>y: ? / Ctrl+Alt+H <br />
<br />
<span style="font-size: 100%;">I want to continually update this list depending on what IDE I use - if you have anything that should be added to the list or you know replacement for some question mark in it, let me know. Thanks to all who already contributed.</span>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-90671323612418280342011-10-17T18:21:00.002+02:002020-06-13T21:49:05.989+02:00Remarkable Changes in Past Versions of Selenium 2 WebDriverFor a long time I kept the code base of our tests running on Selenium 2.0a6. The reasons for not upgrading were different for different Selenium 2 versions - perceived stability problems in InternetExplorer or Firefox, changes being not to enough beneficial for our tests and sometimes even lack of time for the change.<br />
<br />
Now it seems<b> Selenium 2.8 is a good candidate for upgrade</b>. Following enumeration summarizes the changes we waited for and I want to use it as a thanks to all the Selenium 2 developers who participated in the effort. I also hope it wil help to anybody upgrading or considering the upgrade to a newer Selenium 2 .<br />
<br />
1/ RenderedWebElement deprecated and removed in 2.0rc3, method <b>isDisplayed()</b> was moved to WebElement class.<br />
<br />
2/ <b>Mouseover </b>works since 2.0 RC2:<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">openqa</span><span style="color: #808030;">.</span><span style="color: #004a43;">selenium</span><span style="color: #808030;">.</span><span style="color: #004a43;">interactions</span><span style="color: #808030;">.</span><span style="color: #004a43;">Actions</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">openqa</span><span style="color: #808030;">.</span><span style="color: #004a43;">selenium</span><span style="color: #808030;">.</span><span style="color: #004a43;">interactions</span><span style="color: #808030;">.</span><span style="color: #004a43;">Action</span><span style="color: purple;">;</span>
Actions builder = new Actions(driver)<span style="color: #808030;">;</span>
Action hoverAction = builder.moveToElement(mouseOverElement).build()<span style="color: #808030;">;</span>
hoverAction.perform()<span style="color: #808030;">;</span>
</pre><br />
3/ For some time it was necessary to send Enter to a button in MSIE to press it,<br />
but since version 2.2 <b>clicking on buttons</b> (WebElement.click()) seems to work flawlessly.<br />
<br />
4/ Version 2.3 brought the nice<b> Alert class</b> for confirmation and alert dialogs, rendering thus JavaScript workarounds obsolete:<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: maroon; font-weight: bold;">package</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">openqa</span><span style="color: #808030;">.</span><span style="color: #004a43;">selenium</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">interface</span> Alert
<span style="color: purple;">{</span>
<span style="color: #bb7977;">void</span> dismiss<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977;">void</span> accept<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977; font-weight: bold;">String</span> getText<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: #bb7977;">void</span> sendKeys<span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">String</span> keysToSend<span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
</pre><br />
the usage:<br />
<br />
<pre style="background: #ffffff; color: black;">Alert prompt = driver.switchTo().alert()<span style="color: #808030;">;</span>
<span style="color: dimgrey;">// some short sleep here</span>
log.debug( prompt.getText() )<span style="color: #808030;">;</span>
prompt.sendKeys("AAA")<span style="color: #808030;">;</span>
<span style="color: dimgrey;">// some short sleep here</span>
prompt.accept()<span style="color: #808030;">;</span>
</pre><br />
5/ And finally, since 2.8 important parts of the advanced interactions, <b>double-click and right-click</b>, work both for MSIE end FF (since 2.5for MSIE):<br />
<br />
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;">Actions builder = new Actions(driver)<span style="color: #808030;">;</span>
Action doubleClick = builder.doubleClick(element).build()<span style="color: #808030;">;</span>
doubleClick.perform()<span style="color: #808030;">;</span>
Actions builder = new Actions(driver)<span style="color: #808030;">;</span>
Action rightClick = builder.contextClick(element).build()<span style="color: #808030;">;</span>
rightClick.perform()<span style="color: #808030;">;</span>
</pre>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-1720033870526533882011-10-12T14:38:00.001+02:002020-06-13T21:58:03.350+02:00Java Applets - Building with Maven, Communicating with JavaScriptI have recently realized that I've not written any applet for some time and need to refresh my know-how. I hope writing it here will save some time for you if you are in similar situation. <br />
<br />
The example will show the communication of Java Applet with Javascript in both ways - Java-to-JS and JS-to-Java.<br />
<br />
<span style="font-size: large;">Building Applet with Maven</span><br />
<br />
To help Maven to find applet classes and compile the applet, you need to add Java plugin dependency:<br />
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>sun.plugin<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>plugin<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>1.6<span style="color: #a65700;"></</span><span style="color: #5f5035;">version</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">scope</span><span style="color: #a65700;">></span>system<span style="color: #a65700;"></</span><span style="color: #5f5035;">scope</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">systemPath</span><span style="color: #a65700;">></span>${java.home}/lib/plugin.jar<span style="color: #a65700;"></</span><span style="color: #5f5035;">systemPath</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">dependency</span><span style="color: #a65700;">></span>
</pre><br />
You'll also want to include content of your manifest file as the default genreated one does not contain Main-Class property/header:<br />
<pre style="background: #ffffff; color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">build</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">plugins</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>org.apache.maven.plugins<span style="color: #a65700;"></</span><span style="color: #5f5035;">groupId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>maven-jar-plugin<span style="color: #a65700;"></</span><span style="color: #5f5035;">artifactId</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">configuration</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">archive</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">manifestFile</span><span style="color: #a65700;">></span>src/main/resources/META-INF/MANIFEST.MF<span style="color: #a65700;"></</span><span style="color: #5f5035;">manifestFile</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">archive</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">configuration</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugin</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">plugins</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"></</span><span style="color: #5f5035;">build</span><span style="color: #a65700;">></span>
</pre><br />
Example of the manifest:<br />
<pre style="background: #ffffff; color: black;">Manifest-Version: 1.0
Main-Class: org.bithill.SimpleApplet
</pre><br />
<span style="font-size: large;">Deployment</span><br />
<br />
<span style="font-size: large;"><span style="font-size: small;">One of things that changed significantly since writing my last applet is an introduction of the <a href="http://download.oracle.com/javase/6/docs/technotes/guides/jweb/deployment_advice.html#deplToolkit">deployment toolkit</a> - a JavaScript library for including an applet into a web page. </span></span><span style="font-size: large;"><span style="font-size: small;"> It looks like <span style="font-size: small;">a marvel when </span></span></span><span style="font-size: large;"><span style="font-size: small;">compared to the tedious and error-prone applet or object tag creation and checking of the browser differences.<span style="font-size: small;"></span></span></span><br />
<br />
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"><span style="color: #a65700;"><</span><span style="color: #5f5035;">script</span> <span style="color: #274796;">src</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"</span><span style="color: #0000e6;">deployJava.js</span><span style="color: #0000e6;">"</span><span style="color: #a65700;">></span><span style="color: #a65700;"></</span><span style="color: #5f5035;">script</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: #5f5035;">script</span><span style="color: #a65700;">></span>
var attributes =
{
id: 'simpleApplet',
codebase:'../../../target', // directory with the jar
code:'org.bithill.SimpleApplet.class',
archive:'SimpleApplet-1.0.jar',
width: 100, height: 50,
boxbgcolor: '#eeeeee'
};
var parameters = {};
var version = '1.6';
deployJava.runApplet(attributes, parameters, version);
<span style="color: #a65700;"></</span><span style="color: #5f5035;">script</span><span style="color: #a65700;">></span> </pre><span style="font-size: large;">The Applet and Its Iteraction with JavaScript</span><span style="color: maroon; font-weight: bold;"> </span><br />
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"><span style="color: maroon; font-weight: bold;">package</span><span style="color: #004a43;"> org</span><span style="color: #808030;">.</span><span style="color: #004a43;">bithill</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> static java</span><span style="color: #808030;">.</span><span style="color: #004a43;">lang</span><span style="color: #808030;">.</span><span style="color: #004a43;">System</span><span style="color: #808030;">.</span><span style="color: #004a43;">out</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> netscape</span><span style="color: #808030;">.</span><span style="color: #004a43;">javascript</span><span style="color: #808030;">.</span><span style="color: #004a43;">JSException</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> netscape</span><span style="color: #808030;">.</span><span style="color: #004a43;">javascript</span><span style="color: #808030;">.</span><span style="color: #004a43;">JSObject</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">applet</span><span style="color: #808030;">.</span><span style="color: #004a43;">Applet</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">import</span><span style="color: #004a43;"> java</span><span style="color: #808030;">.</span><span style="color: #004a43;">util</span><span style="color: #808030;">.</span><span style="color: #004a43;">Date</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: maroon; font-weight: bold;">class</span> SimpleApplet <span style="color: maroon; font-weight: bold;">extends</span> Applet
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">private</span> JSObject js<span style="color: purple;">;</span> <span style="color: dimgrey;">// object for communication with JavaScript</span>
<span style="color: #3f5fbf;">/** Evaluates given JavaScript expression.</span>
<span style="color: #3f5fbf;"> </span><span style="color: #7f9fbf; font-weight: bold;">*</span><span style="color: #3f5fbf;"> </span><span style="color: #7f9fbf; font-weight: bold;">@param</span><span style="color: #3f5fbf;"> jsExpression expression</span>
<span style="color: #3f5fbf;"> */</span>
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: #bb7977; font-weight: bold;">String</span> jsEval<span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">String</span> jsExpression<span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">try</span> <span style="color: purple;">{</span> js<span style="color: #808030;">.</span>eval<span style="color: #808030;">(</span>jsExpression<span style="color: #808030;">)</span><span style="color: purple;">;</span> <span style="color: purple;">}</span>
<span style="color: maroon; font-weight: bold;">catch</span> <span style="color: #808030;">(</span>JSException ex<span style="color: #808030;">)</span> <span style="color: purple;">{</span> ex<span style="color: #808030;">.</span>printStackTrace<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span> <span style="color: purple;">}</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: maroon; font-weight: bold;">new</span> <span style="color: #bb7977; font-weight: bold;">Date</span><span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">+</span> <span style="color: #0000e6;">" | "</span> <span style="color: #808030;">+</span> jsExpression<span style="color: purple;">;</span>
<span style="color: purple;">}</span>
<span style="color: #3f5fbf;">/** Initializes the applet.</span>
<span style="color: #3f5fbf;"> </span><span style="color: #7f9fbf; font-weight: bold;">*</span><span style="color: #3f5fbf;"> It's called only once before the applet is started.</span>
<span style="color: #3f5fbf;"> */</span>
<span style="color: #808030;">@</span>Override
<span style="color: maroon; font-weight: bold;">public</span> <span style="color: #bb7977;">void</span> init<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">try</span> <span style="color: purple;">{</span> js <span style="color: #808030;">=</span> JSObject<span style="color: #808030;">.</span>getWindow<span style="color: #808030;">(</span><span style="color: maroon; font-weight: bold;">this</span><span style="color: #808030;">)</span><span style="color: purple;">;</span> <span style="color: purple;">}</span>
<span style="color: maroon; font-weight: bold;">catch</span> <span style="color: #808030;">(</span>JSException ex<span style="color: #808030;">)</span> <span style="color: purple;">{</span> ex<span style="color: #808030;">.</span>printStackTrace<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span> <span style="color: purple;">}</span>
<span style="color: purple;">}</span>
<span style="color: purple;">}</span>
</pre><br />
The applet gets reference to JSObject for interacting with JavaScript engine instance in the page. It is then used in jsEval() method which also return time-stamped input to demonstrate reading of the method's rerurn value. In page you need only several lines of JavaScript to connect the things together:<br />
<br />
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"><span style="color: #a65700;"><</span><span style="color: maroon; font-weight: bold;">script</span><span style="color: #a65700;">></span><span style="color: maroon; font-weight: bold;">function</span> getAlertExpression<span style="color: #808030;">(</span>msg<span style="color: #808030;">)</span> <span style="color: purple;">{</span> <span style="color: maroon; font-weight: bold;">return</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">alert('</span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> msg <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">')</span><span style="color: maroon;">"</span><span style="color: purple;">;</span> <span style="color: purple;">}</span><span style="color: #a65700;"></</span><span style="color: maroon; font-weight: bold;">script</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: maroon; font-weight: bold;">button</span><span style="color: #274796;"> </span><span style="color: #074726;">onclick</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"document.getElementById('msgbox').innerText = ( simpleApplet.jsEval( getAlertExpression('HI') ) )"</span><span style="color: #a65700;">></span>
show alert
<span style="color: #a65700;"></</span><span style="color: maroon; font-weight: bold;">button</span><span style="color: #a65700;">></span>
<span style="color: #a65700;"><</span><span style="color: maroon; font-weight: bold;">div</span><span style="color: #274796;"> </span><span style="color: #074726;">id</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"msgbox"</span><span style="color: #a65700;">></span>-- last action --<span style="color: #a65700;"></</span><span style="color: maroon; font-weight: bold;">div</span><span style="color: #a65700;">></span>
</pre>How does it work? The button has JavaScript onclick handler that calls the applet's the jsEval() method and puts its retrurn value to prepared msgbox div. Notice that applet's id is used as reference. Method jsEval() evalueates JavaScript expression in the page -that results in showing an alert dialog.Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com1tag:blogger.com,1999:blog-3388693861049579757.post-15098059639950601012011-09-18T00:44:00.002+02:002020-06-13T21:46:03.208+02:00Using Smart Card as Keystore in Java, setup<div style="font-family: Arial,Helvetica,sans-serif;">
Using a smart card as a key store promises stronger security compared to storing keys or certificates on a disk. This can be further improved by using a card reader with a PIN pad, an effective counter-measure against key loggers.<br />
<br />
This article should provide basic information <b>how to use smart card as key store for Java applications</b>. You do not need an expensive card for such application - a cheaper, specialized crypto-card will do. The installation instructions in this article focus on Linux, as it is my preferred platform and the setup a bit more complicated than on Windows.</div>
<br />
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: large;">The stack</span></div>
<br />
<pre> application
|
java.security.Keystore
|
JVM
|
PKCS11 provider
|
PC/SC middleware
|
CCID
|
USB smart card reader
|
smart card </pre>
<br />
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: large;">Installing Software</span></div>
<ol style="font-family: Arial,Helvetica,sans-serif;">
<li>Download a driver for your smart card reader from its producer's page and install it.</li>
<li>Download and install <a href="http://en.wikipedia.org/wiki/PC/SC">PC/SC</a> middleware - <a href="http://pcsclite.alioth.debian.org/">PCSC-Lite</a>. It does not require any configuration if you use USB reader.<br />
</li>
<li>Get <a href="http://en.wikipedia.org/wiki/PKCS11">PKCS11</a> provider for your card. You can use open-source (<a href="http://www.opensc-project.org/opensc">OpenSC</a>) or producer 's implementation, depending on which one works better with Java.</li>
</ol>
<br />
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-size: large;">Setting PKCS11 Token for Java</span><span style="font-family: Arial,Helvetica,sans-serif;"> </span></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<br /></div>
<div style="font-family: Arial,Helvetica,sans-serif;">
<span style="font-family: Arial,Helvetica,sans-serif;">Fi</span>rst you have to <b>configure PKCS11 provider</b> for Java. Open <span style="font-family: "Courier New",Courier,monospace;">$JAVA_HOME/jre/lib/security/java.security</span> and look for registered security providers - find lines starting with text <span style="font-family: "Courier New",Courier,monospace;">security.provider</span>. Add a new security provider by adding line<span style="font-family: "Courier New",Courier,monospace;"> security.provider.9=sun.security.pkcs11.SunPKCS11 /etc/pkcs11_java.cfg</span> . Sun PKCS#11 provider allows integration of PKCS11 tokens with Java platform
by interfacing a native library, usually delivered by the token producer.<br />
<br />
The configuration file following the provider's fully qualified name may contain various PKCS11 settings. It usually contains only the three lines we can see in this setting for OpenSC:<br />
<br />
<div style="font-family: "Courier New",Courier,monospace;">
name = OpenSC-PKCS11<br />
description = SunPKCS11 via OpenSC<br />
library = /usr/lib/opensc-pkcs11.so</div>
<br />
The entry <span style="font-family: "Courier New",Courier,monospace;">name</span> serves as name of the PKCS11 provider and <span style="font-family: "Courier New",Courier,monospace;">description</span> is AFAIK optional. The most important is the <span style="font-family: "Courier New",Courier,monospace;">library</span> property, it contains a path to the PKCS11 implementation we want to use. <br />
<br />
Depending on environment in which the application will be used we would need need to create a custom <b>security policy</b>, the name of the provider is prefixed with "SunPKCS11-" :<br />
<br />
<div style="font-family: "Courier New",Courier,monospace;">
grant { </div>
<div style="font-family: "Courier New",Courier,monospace;">
permission java.security.SecurityPermission<br />
"authProvider.SunPKCS11-OpenSC-PKCS11";<br />
};</div>
<br />
<br />
In the second part we will see how to create key and certificate, load them into the card and use the key on card to sign and verify.</div>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com2tag:blogger.com,1999:blog-3388693861049579757.post-73494465562972423282011-09-16T00:24:00.000+02:002011-09-16T00:24:50.762+02:00Basic Key/Certificates Manipulation by OpenSSL<h2>Getting Server's SSL/TLS Certificate Chain</h2><br />
<div style="font-family: "Courier New",Courier,monospace;">openssl s_client -connect some_hostname:443 -showcerts</div>X.509 certificates are dumped as base64-encoded strings between <span style="font-family: "Courier New",Courier,monospace;">-----BEGIN CERTIFICATE----- </span>and <span style="font-family: "Courier New",Courier,monospace;">-----END CERTIFICATE-----</span> headers. They should be (together with the headers) stored in files with <b>.pem </b>suffix.<br />
<br />
We can look at the certificate information then:<br />
<span style="font-family: "Courier New",Courier,monospace;">openssl x509 -in cert.pem -inform PEM -noout -text</span><br />
<ul></ul><h2>Conversion of Key and Certificate Formats</h2><h3 style="font-weight: normal;">Keys</h3><ul><li> <i>PKCS1 – PEM to DER</i> <div class="file-or-command"><span style="font-family: "Courier New",Courier,monospace;">openssl rsa -in key.pem -out key.der -inform pem -outform der </span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;">The key format is reflected in the header (of the key.pem):</span></span><br />
<ul><li>PKCS#1 - <i>BEGIN RSA PRIVATE KEY, BEGIN RSA PUBLIC KEY</i> </li>
<li>PKCS#8 - <i>BEGIN PRIVATE KEY</i>,<i> BEGIN ENCRYPTED PRIVATE KEY</i></li>
</ul></div></li>
</ul><h3 style="font-weight: normal;">Certificates</h3><ul><li> <i>PEM to P12</i><br />
<span style="font-family: "Courier New",Courier,monospace;">openssl pkcs12 -export -out cert.p12 -in cert.pem -inkey key.pem </span> </li>
<li> <i>PEM to DER</i> <div class="file-or-command"><span style="font-family: "Courier New",Courier,monospace;">openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER</span></div></li>
</ul>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0tag:blogger.com,1999:blog-3388693861049579757.post-68573112621570158612011-09-13T00:53:00.001+02:002020-06-13T21:49:05.989+02:00Setting Firefox Preferences via Selenium 2 (WebDriver API)I wanted to run Firefox from WebDriver with custom preferences. So I looked into the well-known <b>about:config</b> for name of the option and, just to be sure, consulted<b> <a href="http://kb.mozillazine.org/About:config_entries">About:config entries</a></b> section of Mozilla Wiki.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiBO7UX7aRqTMxDbRXRRn0JOEyvhpNLNj1nIEL0sIg97QCBzGW_jKjyLmQGLaOnXckrYGZf4SBOKZ6ctIuaROctE03EtTszQVQ2Q64ioitP9JjOIIxfqDT3-npvatYkRTZb6KQDBJLCwtr/s1600/aboutconfig.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiBO7UX7aRqTMxDbRXRRn0JOEyvhpNLNj1nIEL0sIg97QCBzGW_jKjyLmQGLaOnXckrYGZf4SBOKZ6ctIuaROctE03EtTszQVQ2Q64ioitP9JjOIIxfqDT3-npvatYkRTZb6KQDBJLCwtr/s400/aboutconfig.png" width="378" /></a></div><br />
With the name of desired config option to change, the rest is a pieceof cake:<br />
<br />
<pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;">FirefoxProfile profile = new FirefoxProfile()<span style="color: #808030;">;</span>
profile.setPreference("dom.event.contextmenu.enabled",false)<span style="color: #808030;">;</span>
WebDriver webDriver = new FirefoxDriver(profile)<span style="color: #808030;">;</span>
</pre>Rostislav Matlhttp://www.blogger.com/profile/01298732927177956071noreply@blogger.com0