středa 21. září 2022

Download Maven artifact with version range

Download Maven artifact with version range

Download Maven artifact with version range

The task is simple - download maven artifact using version range - e.g. [2, 3)
This can be useful for example in CI jobs.

Suprisingly I don’t have trivial solution.

One possible solution

Is described in my repository:
https://github.com/bugs84/download-maven-dependency-with-version-range

You have to create dummy file. pom.xml (which is in repository)
and then run command. e.g.

mvn dependency:copy-dependencies -DoutputDirectory=./downloaded-dependencies -Ddep.group="org.apache.logging.log4j" -Ddep.artifact="log4j-api" -Ddep.version="[2.17.1,)"

pondělí 1. listopadu 2021

Git How to add Branch name into commit message

Git - add Branch name into commit message.

Git - How to add Branch name into commit message.

Why

Because search something in git history can be very frustrating, because git branches are just “floating labels, which will simply move elsewhere or dissapear”.

How

Using git hook

Into file .git\hooks\prepare-commit-msg add this:

#!/bin/sh  
#  
# Automatically adds branch name and branch description to every commit message.  
#  
NAME=$(git branch | grep '*' | sed 's/* //')  
DESCRIPTION=$(git config branch."$NAME".description)  
TEXT=$(cat "$1" | sed '/^#.*/d')  
  
if [ -n "$TEXT" ]  
then  
  printf "$(cat "$1" | sed '/^#.*/d')\nBranch: $NAME" > "$1"  
  if [ -n "$DESCRIPTION" ]  
    then  
  echo "" >> "$1"  
  echo $DESCRIPTION >> "$1"  
  fi  
else  
  echo "Aborting commit due to empty commit message."  
  exit 1  
fi

And that’s it. Your commits will contain a branch name.

Sharing git hooks with others

Sharing git hooks inside a project is not supported by git. There are a few workarounds, but none of them is perfect.

e.g.

  • add directory <your repo>/.githooks/ create file prepare-commit-msg there and commit it.
  • set property git config --local core.hooksPath=.githooks
  • somehow ensure, that everyone will execute git config --local core.hooksPath=.githooks on every clone of your repo :(

https://stackoverflow.com/questions/5894946/how-to-add-gits-branch-name-to-the-commit-message

https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/

sobota 1. února 2020

I invented Agile Testing

I invented Agile Testing.md

I invented Agile Testing

For a couple of last years, I saw issues in our processes and in the way we work. I managed to do some changes and change how people think about testing.

And do you know what I now found?

It is always the same. You invent something new and then you found, that somebody else already did the same thing. In my case, these principles have already its own (buzz)word called “Agile Testing”
https://reqtest.com/testing-blog/agile-testing-principles-methods-advantages/

These principles are very very similar to the thinks I discovered myself and I believe, that works best in most situations.

Maybe that the best name of the article should be “My way to Agile Testing”.

neděle 5. ledna 2020

Kotlin Extendable Tests

Kotlin Extendable Tests

Kotlin Extendable Tests

Imagine, that you have a lot of System/Functional tests. And a lot of these test have some common code. E.g. One code clean your system data. Another starts your testing HttpServer. etc.

This code often end up in some class, lets call it “TestBase”, and all tests inherit from this TestBase. As time goes on this class is bigger and bigger. And a lot of tests, which doesn’t need clean system data are doing so, because this code is part of TestBase.

Solution is split this TestBase somehow. But Splitting it can be quite tricky.

In Groovy(link) this can be easyli done by using Traits (link). And each functionality became own Trait and only tests which need this functionality will implement this trait.

In Kotlin we do not have traits, but it is possilbe to use Interfaces and Delegation to easily implement something with similar capabilities.

Example

You can easily write tests, which use your extensions.

import ... Extendable
import ... ExtendableImpl
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import java.net.HttpURLConnection
import java.net.URL

class ExtensionSampleTest : Extendable by ExtendableImpl() {
    // Here is used our extenssion, which start and stop http server
    val server = register(HttpServerExtension())

    @Test
    fun `test using extension`() {
        // given
        val con = URL("http://localhost:${server.port}/test").openConnection() as HttpURLConnection
        con.setRequestMethod("GET")

        // when
        val response = String(con.inputStream.readAllBytes())

        // then
        assertThat(response).isEqualTo("This is the response")
    }

}

Extension which starts http server. Can look like this:

import com.sun.net.httpserver.HttpServer
import ... Extension
import java.net.InetSocketAddress


class HttpServerExtension(val port: Int = 8000) : Extension {

    lateinit var server: HttpServer

    override fun extBeforeEach() {
        start()
    }

    override fun extAfterEach() {
        stop()
    }

    private fun start() {
        server = HttpServer.create(InetSocketAddress(port), 0).apply {
            createContext("/test") { t ->
                val response = "This is the response"
                t.sendResponseHeaders(200, response.length.toLong())
                t.responseBody.apply {
                    write(response.toByteArray())
                    close()
                }
            }
            start()
        }
    }

    private fun stop() {
        server.stop(1)
    }
    
}

Implementation of extessions for jUnit5

  
import org.junit.jupiter.api.*  
import org.junit.jupiter.api.TestInstance.Lifecycle  
  
/**  
 * Be Aware! Implementing this Interface make the test @TestInstance(Lifecycle.PER_CLASS)
 * It means one test instance is used to run all tests!
 */
@TestInstance(Lifecycle.PER_CLASS)  
interface Extendable {  
  
    val extensions: MutableList<Extension>  
  
    fun <T : Extension> register(extension: T): T {  
        extensions.add(extension)  
        return extension  
    }  
  
    @BeforeAll  
    fun extendableBeforeAll() {  
        extensions.forEach(Extension::extBeforeAll)  
    }  
  
    @BeforeEach  
    fun extendableBeforeEach() {  
        extensions.forEach(Extension::extBeforeEach)  
    }  
  
    @AfterEach  
    fun extendableAfterEach() {  
        extensions.asReversed().forEach(Extension::extAfterEach)  
    }  
  
    @AfterAll  
    fun extendableAfterAll() {  
        extensions.asReversed().forEach(Extension::extAfterAll)  
    }  
}  
  
open class ExtendableImpl : Extendable {  
    override val extensions = mutableListOf<Extension>()  
}  
  
interface Extension {  
    fun extBeforeAll() {}  
    fun extBeforeEach() {}  
    fun extAfterEach() {}  
    fun extAfterAll() {}  
}

úterý 1. ledna 2019

Kotlin - Use spaces in name of tests.md

Kotlin - Use spaces in name of tests.md

Kotlin - Use spaces in name of tests

Kotlin allow us to use any characters in method names (even with spaces). If we enclose it in backticks.:
fun `method - name`() {}

It can be very convenient for name of tests. And I think, that we should definitely make use of this opportunity.

Then we can have descriptive names of tests like for example
Spock
have.

Example

We can figure out a lot of example, but will show you just one :)

Consider this simple test:

@Test  
fun `multiplyExact of zero integer should return zero`() {  
    //when  
    val result = Math.multiplyExact(10, 0)  
      
    //then  
    assertThat(result).isEqualTo(0)  
}

It is easier to understand name of test above, than following one:

@Test  
fun multiplyExactOfZeroIntegerShouldReturnZero() { ... }

Where ends the name of method and where starts test description?

Experience

I have never found any problem with method named like this.
IDE (IntelliJ IDEA) have no problem with methods named like this.
And jUnitRunner have no difficulties with this methods as well.

So there is no excuse for writing less readable test names.

pondělí 17. prosince 2018

Equivalent closures in Groovy and Kotlin

Equivalent closures in Groovy and Kotlin.md

Equivalent closures in Groovy and Kotlin

Closures in Groovy and Kotlin are very similar, but have different names. Here is is list with few of them.

Project with samples is here:
https://github.com/bugs84/samples/tree/master/kotlin-groovy-closures

Groovy Kotlin
each forEach
collect map
findAll filter
find find
groupBy groupBy
eachWithIndex forEachIndexed
with run, let
with :-/ apply, also

Note: Not every think is absolutely same, but it’s at least quite similar.

each vs. forEach

def sum = 0
[1, 2, 3].each { sum += it }
assert sum == 6
var sum = 0  
listOf(1, 2, 3).forEach { sum += it }  
assertThat(sum).isEqualTo(6)

collect vs. map

List<String> result = [1, 2, 3].collect { "S-" + it }  
assert result == ["S-1", "S-2", "S-3"]
val result = listOf(1, 2, 3).map { "S-" + it }  
assertThat(result).isEqualTo(listOf("S-1", "S-2", "S-3"))

findAll vs. filter

assert [1, 2, 3, 4, 5].findAll { it < 3 } == [1, 2]
assertThat(
        listOf(1, 2, 3, 4, 5).filter { it < 3 }
).isEqualTo(
        listOf(1, 2)
)

find vs. find

assert [1, 2, 3, 4, 5].find { it < 3 } == 1
assertThat(  
        listOf(1, 2, 3, 4, 5).find { it < 3 }  
).isEqualTo(
        1
)

groupBy vs. groupBy

Map<Integer, List<Integer>> groupBy = [1, 2, 3, 4, 5, 6, 7].groupBy { it % 3 }  
assert groupBy == [  
        0: [3, 6],  
        1: [1, 4, 7],  
        2: [2, 5]  
]
val groupBy: Map<Int, List<Int>> = listOf(1, 2, 3, 4, 5, 6, 7).groupBy { it % 3 }  
assertThat(groupBy).isEqualTo(
    mapOf(  
        0 to listOf(3, 6),  
        1 to listOf(1, 4, 7),  
        2 to listOf(2, 5)  
    ))

eachWithIndex vs. forEachIndexed

def result = ""  
["A", "B"].eachWithIndex { entry, index ->  
    result += "$index:$entry, "  
}  
assert result == "0:A, 1:B, "
var result = ""  
listOf("A", "B").forEachIndexed { index, entry ->  
  result += "$index:$entry, "  
}  
assertThat(result).isEqualTo("0:A, 1:B, ")

Note: entry and index are in different order

with vs. run

assert "string".with {  
    length()  
} == 6
assertThat(  
    "string".run {  
        length  
    }  
).isEqualTo(6)

with/run can be used just for for creating an scope:

assert with {  
    "AAA"  
} == "AAA"
assertThat(  
        run {  
            "AAA"  
        }  
).isEqualTo("AAA")

In Groovy with works as Kotlin let as well. See next example:

with vs. let

assert "string".with {  
    it.length()  
} == 6
assertThat(  
        "string".let {  
            it.length  
        }  
).isEqualTo(6)

with vs. apply

assert "string".with {  
    println length()  
    it //  :-/  
} == "string"
assertThat(  
        "string".apply {  
            println(length)  
        }
).isEqualTo("string")

with vs. also

assert "string".with {  
    println it.length()  
    it //  :-/  
} == "string"
assertThat(  
        "string".also {  
            println(it.length)  
        }  
).isEqualTo("string")

středa 9. května 2018

Kotlin - Append to StringBuilder using "+" "plus" instead of append() method

Kotlin - Override plus operator for StringBuilder

Kotlin - Append to StringBuilder using “+” “plus” instead of append() method

In Kotlin you can easily override operator. I will show simple example how can this help you to write more readable code.

At first we will override “plus” operator on for StringBuilder class

operator fun StringBuilder.plus(str: String): StringBuilder {
    append(str)
    return this
}

If you define this function as private. It will be accessible only in file, where it is defined. Or public and then it can be used anywhere in project.

And from this code:

sb.append("function ").append(generatedClassName).append("() {").append("\n")
functions.forEach { function: Function ->
    sb.append(indent).append("this.").append(function.name).append(" = undefined;").append("\n")
}
sb.append("}").append("\n")
sb.append("var ").append(name).append(" = new ").append(generatedClassName).append("();").append("\n")

we can remove all ‘append’ words and we get this code:
=>

sb + "function " + generatedClassName + "() {" + "\n"
functions.forEach { function: Function ->
    sb + indent + "this." + function.name + " = undefined;" + "\n"
}
sb + "}" + "\n"
sb + "var " + name + " = new " + generatedClassName + "();" + "\n"

Very simple, code is shorter and more readable.

úterý 1. května 2018

Gradle Kotlin DSL - Tipy

Gradle Kotlin DSL - Tipy

IntelliJ IDEA build by Gradle

build projektu u nás nedělá přímo IntelliJ IDEA ale deleguje to na Gradle

Idea Settings-> Gradle -> Runner -> Checkbox ‘Delegate IDE build/run actions to gradle’
enter image description here

Poznámky:
  • při buildu idea spouští tyhle tasky z gradlu :classes :testClasses

Jak Debugovat

  1. gradlew.bat <task> --no-daemon -Dorg.gradle.debug=true
  2. pak se připojit remote debuggerem na port 5005
    • Příklad nastavení v IntelliJ IDEA:
      Remote debugger - IntelliJ IDEA configuration example

ALE pozor! - build nejde spustit, pokud už předtím daemon běží

  • v tom potřeba je potřeba ho vypnout gradlew.bat --stop (to zastaví daemony)
Kam jde dát breakpoint:
  • jde do buildSrc
  • nešlo mi dát přímo do tasku v build.gradle.kts
  • nešlo mi dát do metody v build.gradle.kts (to v groovy gradlu fungovalo)

Parallelní build

používáme parallelní build java org.gradle.parallel=true
Proto pozor tasky, které na sobě nejsou závislé se spustí parallelně to znamená:
gradlew test uploadTestResults zde je nutné mít nastavenou závislost mezi tasky např:

tasks {
    val test by tasks.getting  
      
    val uploadTestResults by tasks.creating {  
        dependsOn(test)
        doLast {  
            ... process test resutls ...
        }  
    }
}

exclude task

V případě, vyjímečně chci spustit task bez jeho závislostí (např. když ho píšu) lze

gradlew uploadTestResults -x test - spustí ‘uploadTestResults’ bez tasku ‘test’

V konfiguraci tasku jde upravit jakékoliv parametry např:
gradle.startParameter.excludedTaskNames += "myTaskToExclude"

Logování v build scriptu

V build.gradle.kts je k dispzici variabla logger.
Gradle přidává novou logovací uroveň lifecycle a quiet
error, quiet, warning, lifecycle, info, debug
Výchozí úroven logovaní NENI info, ale LIFECYCLE !!!

gradlew <myTask> --info   - spusti příkaz s urovní info

Detaily zde: Gradle Logging

Jak získat logger uvnit buildSrc

val logger = Logging.getLogger(this.javaClass)
kde Logging je: import org.gradle.api.logging.Logging

Pak lze už normálně logovat:

logger.lifecycle("My log message")

Nastavení tasku

Vše patří do build.gradle.kts sekce tasks { ... }

Získání existujícího tasku:
val test by tasks.getting
Vytvoření nového tasku:
val jasmineResultsParser by tasks.creating {  
    doLast {  
      ... what task should do ...
    }  
}
validator, který zjistí zda je task “up to date”:
mytask {
    outputs.upToDateWhen { myFile.exists() }
}
Spouštět task jen v případě, že se spustí jiný task (=není excludovaný)
onlyIf{ 
   gradle.taskGraph.hasTask("mySubModule:test")
}

Další

Dependencies
  • gradlew :nuc-common:dependencies --configuration testCompile
    • vypíše strom závislostí pouze pro podprojekt ‘nuc-common’ a pouze pro konfiguraci ‘testCompile’
zjistit co se spusti

gradlew <myTask> --dry-run - nespustí příkazy, jen ukáže co by se spustilo

v IntelliJ IDEA nefunguje moc dobře navigace mezi fily

může pomoct plugin ‘Gradle/Maven Navigation’
enter image description here

Dependency management

Zavislosti se vyhodnocují jinak než v Mavenu. Gradle použije vždy nejnovější.

dependencyManagement {
    overriddenByDependencies(false)
}

úterý 3. října 2017

Jak naformátovat usb flash na FAT32

Potřeboval jsem kamarádovi naformátovat 64GB flasku na FAT32. Překvapilo mě, že to není zas tak jednodnoduché spousta způsobů nezabere. A protože se mi kamarád vždycky jednou za rok ozve a já už nevím jak jsem to dělal, tak si to tu napíšu:

Zabralo mi tohle:
Odsud http://www.ridgecrop.demon.co.uk/ stáhnout"FAT 32 Formatter".
Odkaz přímo na download: http://www.ridgecrop.demon.co.uk/download/fat32format.zip
a pak staci spustit:

fat32format.exe -c64 X:

X - je pismeno svazku
Příště to snad už najdu snáz.

středa 30. srpna 2017

Hg - Mercurial how to remove unwanted merge - using backout of backout

Issue
We have branches: "default" and "myB"
Into branch "default" was by mistake merged branch "myB".

Solution
One possible solution to solve this is:
Simple description: We will backout merge in "default" branch. Then we merge this backout into "myB" and then we will do "backout of this backout" in "myB" branch.

Exact way how to do it:

${merge} - revision with unwanted merge
${default_parent} - revision of parent changeset of ${merge} changeset in "default" branch
${myB_parent} - revision of parent changeset of ${merge} changeset in "myB" branch

commands:

hg update ${merge}
hg revert --all -r ${default_parent}
hg commit -m "backout of unwanted merge"   


hg update ${myB_parent}

hg merge tip
hg ci -m "merge backout into branch"

hg revert --all -r ${myB_parent}
hg commit -m "backout of backout"  



This is inspired by: https://www.mercurial-scm.org/pipermail/mercurial/2017-January/050172.html

         

Example of such revert in log:

sobota 25. února 2017

Maven - Jak spustit testy na všech modulech i když některé testy padají.

Maven buildi jednotlive moduly. A ihned jak v některém spadne test, tak build skončí, protože všechny ostatní moduly přeskočí.

  • mvn test
    - Build běží jen k modulu s prvním padajícím testem. A zbytek modulů přeskočí.
  • mvn test --fail-at-end
    - Pokud modul spadne, tak přeskočí jen moduly, které na tomto modulu zavísí.
  • mvn test --fail-never
    - Spouští všechny moduly - žádné nepřeskočí. I když některé popadají.

mvn test

Příklad:

[INFO] Reactor Summary:
[INFO] 
[INFO] smpl ................................................ SUCCESS [  1.166 s]
[INFO] smpl-test ........................................... SUCCESS [  4.077 s]
[INFO] smpl-common ......................................... SUCCESS [ 29.367 s]
[INFO] smpl-data ........................................... SUCCESS [  9.442 s]
[INFO] smpl-persistence .................................... SUCCESS [ 27.131 s]
[INFO] smpl-core ........................................... FAILURE [01:24 min]
[INFO] smpl-icm-persistence ................................ SKIPPED
[INFO] smpl-ips ............................................ SKIPPED
[INFO] smpl-sys-info ....................................... SKIPPED
[INFO] smpl-gmc-cloud ...................................... SKIPPED
[INFO] smpl-workflow ....................................... SKIPPED
[INFO] smpl-cluster ........................................ SKIPPED
[INFO] smpl-engine ......................................... SKIPPED
[INFO] smpl-definitions .................................... SKIPPED
[INFO] smpl-statistics-report-creator ...................... SKIPPED
[INFO] smpl-upgrade ........................................ SKIPPED
[INFO] smpl-monitoring ..................................... SKIPPED
[INFO] smpl-webserver ...................................... SKIPPED
[INFO] smpl-webserver-core ................................. SKIPPED
[INFO] smpl-node ........................................... SKIPPED
[INFO] smpl-icm-package-creator ............................ SKIPPED
[INFO] smpl-doc-exporter ................................... SKIPPED
[INFO] smpl-i18n-converter ................................. SKIPPED
[INFO] smpl-stopper ........................................ SKIPPED
[INFO] smpl-bobril ......................................... SKIPPED
[INFO] smpl-frontend ....................................... SKIPPED
[INFO] smpl-webserver-app .................................. SKIPPED
[INFO] smpl-sample-app ..................................... SKIPPED
[INFO] smpl-installer ...................................... SKIPPED
[INFO] smpl-incubator ...................................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:35 min
[INFO] Finished at: 2017-01-19T09:38:42+01:00
[INFO] Final Memory: 54M/1044M
[INFO] ------------------------------------------------------------------------

mvn test --fail-at-end

Příklad:

[INFO] Reactor Summary:
[INFO] 
[INFO] smpl ................................................ SUCCESS [  1.443 s]
[INFO] smpl-test ........................................... SUCCESS [  5.906 s]
[INFO] smpl-common ......................................... SUCCESS [ 32.095 s]
[INFO] smpl-data ........................................... SUCCESS [ 13.179 s]
[INFO] smpl-persistence .................................... SUCCESS [ 28.213 s]
[INFO] smpl-core ........................................... FAILURE [01:27 min]
[INFO] smpl-icm-persistence ................................ SKIPPED
[INFO] smpl-ips ............................................ SKIPPED
[INFO] smpl-sys-info ....................................... SKIPPED
[INFO] smpl-gmc-cloud ...................................... SUCCESS [  1.289 s]
[INFO] smpl-workflow ....................................... SKIPPED
[INFO] smpl-cluster ........................................ SKIPPED
[INFO] smpl-engine ......................................... SKIPPED
[INFO] smpl-definitions .................................... SUCCESS [  0.693 s]
[INFO] smpl-statistics-report-creator ...................... SUCCESS [  1.108 s]
[INFO] smpl-upgrade ........................................ FAILURE [ 18.500 s]
[INFO] smpl-monitoring ..................................... SKIPPED
[INFO] smpl-webserver ...................................... SUCCESS [  0.630 s]
[INFO] smpl-webserver-core ................................. SKIPPED
[INFO] smpl-node ........................................... SKIPPED
[INFO] smpl-icm-package-creator ............................ SUCCESS [  1.222 s]
[INFO] smpl-doc-exporter ................................... SUCCESS [  1.074 s]
[INFO] smpl-i18n-converter ................................. SUCCESS [  1.342 s]
[INFO] smpl-stopper ........................................ SUCCESS [  0.833 s]
[INFO] smpl-bobril ......................................... SUCCESS [ 30.465 s]
[INFO] smpl-frontend ....................................... SUCCESS [01:42 min]
[INFO] smpl-webserver-app .................................. SKIPPED
[INFO] smpl-sample-app ..................................... SUCCESS [ 14.232 s]
[INFO] smpl-installer ...................................... SKIPPED
[INFO] smpl-incubator ...................................... SUCCESS [  0.620 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 05:42 min
[INFO] Finished at: 2017-01-19T09:27:37+01:00
[INFO] Final Memory: 65M/1149M

mvn test --fail-never

Příklad:

[INFO] Reactor Summary:
[INFO] 
[INFO] smpl ................................................ SUCCESS [  1.272 s]
[INFO] smpl-test ........................................... SUCCESS [  5.089 s]
[INFO] smpl-common ......................................... SUCCESS [ 32.105 s]
[INFO] smpl-data ........................................... SUCCESS [  9.521 s]
[INFO] smpl-persistence .................................... SUCCESS [ 27.626 s]
[INFO] smpl-core ........................................... FAILURE [01:25 min]
[INFO] smpl-icm-persistence ................................ FAILURE [ 10.546 s]
[INFO] smpl-ips ............................................ SUCCESS [ 13.612 s]
[INFO] smpl-sys-info ....................................... SUCCESS [  5.811 s]
[INFO] smpl-gmc-cloud ...................................... SUCCESS [  1.094 s]
[INFO] smpl-workflow ....................................... SUCCESS [ 31.439 s]
[INFO] smpl-cluster ........................................ SUCCESS [ 13.137 s]
[INFO] smpl-engine ......................................... FAILURE [01:31 min]
[INFO] smpl-definitions .................................... SUCCESS [  0.560 s]
[INFO] smpl-statistics-report-creator ...................... SUCCESS [  1.038 s]
[INFO] smpl-upgrade ........................................ FAILURE [ 16.010 s]
[INFO] smpl-monitoring ..................................... FAILURE [ 30.710 s]
[INFO] smpl-webserver ...................................... SUCCESS [  0.580 s]
[INFO] smpl-webserver-core ................................. SUCCESS [ 46.682 s]
[INFO] smpl-node ........................................... FAILURE [  6.602 s]
[INFO] smpl-icm-package-creator ............................ SUCCESS [  1.033 s]
[INFO] smpl-doc-exporter ................................... SUCCESS [  1.010 s]
[INFO] smpl-i18n-converter ................................. SUCCESS [  1.097 s]
[INFO] smpl-stopper ........................................ SUCCESS [  0.570 s]
[INFO] smpl-bobril ......................................... SUCCESS [ 14.878 s]
[INFO] smpl-frontend ....................................... SUCCESS [01:38 min]
[INFO] smpl-webserver-app .................................. SUCCESS [  2.341 s]
[INFO] smpl-sample-app ..................................... SUCCESS [ 13.023 s]
[INFO] smpl-installer ...................................... SUCCESS [ 17.248 s]
[INFO] smpl-incubator ...................................... SUCCESS [  0.557 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 09:41 min
[INFO] Finished at: 2017-01-19T09:50:06+01:00
[INFO] Final Memory: 77M/1483M
[INFO] ------------------------------------------------------------------------

pondělí 20. února 2017

Jak nadefinovat vlastní MBean ve Springu

Do svého aplikačního contextu přidat

    
    <context:mbean-export/>
(context je tento namespace xmlns:context="http://www.springframework.org/schema/context")

Pak již lze nadefinovat vlastní Mbean. (Příklad je v Kotlinu)

import org.springframework.jmx.export.annotation.ManagedOperation
import org.springframework.jmx.export.annotation.ManagedResource
import org.springframework.stereotype.Component

@Component
@ManagedResource(objectName = "MyApplicationName" + ":name=HelloMBeanWorld")
class HelloMBeanWorld {

    //Its component - you can simply autowire anything
    //@Autowired
    //private MyBean myBean

    @ManagedOperation(description = "My hello world MBean")
    fun getHelloMBeanWorld(): String {
        return "Hello MBean world!!!"
    }

}

A pak stačí spustit aplikaci a přistupovat ke své MBean třeba pomocí JConsole. Spring už pořeší, registrovaní a hlavně taky odregistrování bean a vše. Díky Springu!

Další možnosti jsou krásně popsané v dokumentaci springu: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jmx.html

pondělí 12. září 2016

Run Groovy Project Without Compilation Using Gradle

Run Groovy Project Without Compilation Using Gradle

To be honest it is automatically compiled by Gradle. All changes made into "buildSrc/src/main/groovy" are automatically compiled during startup.

Key feature of Gradle is how nicely it manages "buildSrc" directory.

Here is sample project https://bitbucket.org/bugs_/samples/src/default/RunGroovyProjectWithoutCompilationUsingGradle/

sobota 30. července 2016

čtvrtek 28. července 2016

Count number bytes in UTF-8 for Java String

https://bitbucket.org/bugs_/utils/src/default/CoreUtils/src/main/java/cz/vondr/coreutils/utf/Utf8LengthUtil.java

  • Problem 1: You have Java String variable. And you need get number of bytes in UTF-8
  • Problem 2: You need split String into multiple Strings, in the way that each of them have exact number of bytes. (expect last part of course :) )

Thanks to stackoverflow.com

úterý 15. března 2016

MXBeans ovládání z command line

MX Beany jsem vždy ovládal pomoci JConsole. To ale nejde bez grafického prostředí

Tady je jeden ze způsobů, jak něco spustit z command line
http://wiki.cyclopsgroup.org/jmxterm/download.html

stáhnout jmxterm-1.0-alpha-4-uber.jar

java.exe -jar jmxterm-1.0-alpha-4-uber.jar    (potřebuje to JDK ne jen JRE)

prikaz "jvms"
  (vylistuje jvm procesy)

prikaz "open "
  (se pripoji k procesu)

prikaz "run -d MyApp -b MyApp:name=MyBean nameOfMethod"
  (se spustí danou metodu na dane beane)

pondělí 19. října 2015

Gradle - Get Hg Mercurial revision

Here is part of build.gradle file, which get mercurial revision and define task "revision", which print it to output.

It uses javahg to get revision number and that's why it needs Mercurial installation. We could use hg4j to remove this requirement. Anyway this script can be improved a lot, but for me it did it's work.

pátek 9. října 2015

Gradle - How to get Mercurial revision in gradle build file.

This part of gradle.build file add task "revision", which writes Mercurial changeset hash.

It can be improved, but ...

úterý 16. června 2015

Jak otestovat změnu času

Když je v testech potřeba posouvat čas. Bývá to poměrně pracné většinou člověk skončí s tím že píše nějaký "DateProvider", který se pak dá namockovat.

Ve spoustě případů se dá použít jednoduchá alternativa a využít Joda Time

Joda Time nabízí funkci DateTimeUtils.setCurrentMillisProvider(MillisProvider millisProvider) (a i další funkce setCurrentMillisFixed, setCurrentMillisOffset), kterými jde snadno říct, jak se má čas v testech chovat.
Po testu se musí čas zase vrátit do normálu!!! :) funkcí DateTimeUtils.setCurrentMillisSystem() V kódu se musí samozřejmě zjištovat čas přes Joda Time (např. new DateTime()).

A to je ve stručnosti vše.

úterý 12. května 2015

Maven Timeline Plugin - změření časů všech fází u konkrétního modulu.

Maven vypisuje časy buildu jednotlivých modulů. Jak ale zjistit proč konkrétní modul trvá tak dlouho...?

Narazil jsem na jednoduchý Maven Timeline Plugin, který vygeneruje jednoduché html s vizualizací časů.
Takto vypadá: http://blog.javabien.net/2014/04/22/maven-timeline-plugin/
A takto se používá: https://github.com/dgageot/maven-timeline