Home » Java Basics

Archiv der Kategorie: Java Basics

Java Runnable (EXE) erstellen / Runnable JAR erstellen

Wie erstelle ich ein Java-Programm, das ich mal einfach so einem Kollegen senden kann, das dieser dann auf seinen Computer kopiert und per Doppelklick ausführt.

(Java Web Start wäre wohl eine gute Wahl dafür gewesen, doch diese Technologie existiert seit Java 11 nicht mehr.)

Hat das Programm ein GUI (oder präziser: Braucht es keine Kommandozeile für die User-Interaktion) kann man ein „Doppelklickbares“ JAR aus dem Code erstellen.

Ausführbare JAR Datei erstellen

Eine doppelklickbare JAR Datei kann wie folgt erstellt werden.
Dies ist nicht zielführend mit Kommandozeilenprogrammen, die (ad hoc) Parameter verlangen. Nützlich ist diese Option hingegen für GUI Programme.

Main Klasse in Manifest referenzieren

Im MANIFEST.MF soll diese Zeile stehen:

Main-Class: ch.meine.MainKlasse
Dies kann erreicht werden indem dem pom.xml diese Plugin-Definition hinzugefüt wird:
<build>
        <plugins>

            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>ch.meine.MainKlasse</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>

Nun muss das Projekt gebildet werden:

mvn clean package assembly:single

Das entstande JAR-File kann mittels Doppelklick gestartet werden.
Wenn das Programm kein GUI ist wird es kaum sichtbar sein, weil es wohl anläuft aber potentiell sehr schnell wieder verschwindet.

Alternativ kann das JAR gestartet werden mit:

java -jar MeinProgramm.jar <parameters>

Auf Kommandozeile ausführen

Ein (wie oben beschrieben) ausführbar gemachtes JAR kann wie folgt ausgeführt werden:

java -jar MeinProgramm.jar <parameters>

Selbstverständlich kann dieser Aufruf in Shortcuts oder in (Power)Shell/Bat Scripts eingabaut werden (und eventuell so als ZIP dem Kunden geliefert werden).

Vordefinierte Java Functional Interfaces – Welches kann ich benutzen?

ParameterFunctional Interface
keineRunnable
1 inputConsumer
1 outputSupplier
1 input / 1 outputFunction
2 inputBiConsumer

Mehrfach-Join in CriteriaAPI

Beachte, dass bei den Joins sowohl in richtung n:1 als auch in Richtung 1:n (mit _ATTR_excludedPosList) referenziert wird!

    Set<String> getBusinessTypesWithExclusions(UniqueId businessExecutionId) {
        CriteriaBuilder criteriaBuilder = daoProvider.getEntityManager().getCriteriaBuilder();
        CriteriaQuery<HpsBusiness> query = criteriaBuilder.createQuery(HpsBusiness.class);
        Root<HpsBusiness> root = query.from(HpsBusiness.class);
        Join<HpsBusiness, HpsBusinessExec> joinBusiness = root.join(HpsBusiness._ATTR_businessExec, JoinType.INNER);        // <-- n : 1
        Join<HpsBusiness, HpsExcludedPos> joinExcludedPos  = root.join(HpsBusiness._ATTR_excludedPosList, JoinType.INNER);  // <-- 1 : n 

        query.select(root).where(criteriaBuilder.and(criteriaBuilder.equal(joinBusiness.get(HpsBusinessExec._ATTR_id), businessExecutionId),
                criteriaBuilder.equal(joinExcludedPos.get(HpsExcludedPos._ATTR_exclusionReasonType), ExclusionReasonType.EXCLUDED.name())));

        return daoProvider.getHpsBusinessDao().find(query).stream().map(HpsBusiness::getBusinessCd).collect(Collectors.toSet());
    }

JVM Heap / MethodArea / Stack

JVM Tuning: Heapsize, Stacksize and Garbage Collection Fundamental

Stack-Size:

What is the default stack size, can it grow, how does it work with garbage collection?

Default Stack Size

Mockito.when(null) – Return basierend auf equality zu gegebenem Input

Mockito.mock(null)

Weshalb sollte das sinn machen?

Mockito.when(null).thenReturn(meinObjekt)

bedeutet eigentlich: Liebes Mockito. Nimm den letzten Aufruf auf irgend einem Mock. Wenn irgendwann derselbe Aufruf mit denselben Parametern gemacht werden sollte, dann gib „meinObjekt“ zurück.

Dies wird unten demonstriert.

import org.mockito.Mockito;

import java.util.Objects;

/**
 * Demonstrates how Mockito.when(null) can be used to tell Mockito to 
 * return a given value if  objects equals to given ones are passed to the mocked method 
 */
public class HPTest {
    public static void main(String[] args) {
        MyObj mockedObject = Mockito.mock(MyObj.class);
        
        /* Tell Mockito, that if get1() is called, then return "super cool string 1.1"*/
        mockedObject.get1();
        Mockito.when(null).thenReturn("super cool string 1.1");
        mockedObject.get2();
        Mockito.when(null).thenReturn("super cool string 2");
        System.out.println(mockedObject.get1());
        System.out.println(mockedObject.get1());
        System.out.println(mockedObject.get2());
        System.out.println(mockedObject.toString());


        /* Tell Mockito, that if return1("1") is called, then return "Return 1" */
        mockedObject.return1("1");
        Mockito.when(null).thenReturn("Return 1");

        /* but if return1("2") is called, then return "Return 2" */
        mockedObject.return1("2");
        Mockito.when(null).thenReturn("Return 2");

        System.out.println(mockedObject.return1("1"));
        System.out.println(mockedObject.return1("2"));
        System.out.println(mockedObject.return1("2"));
        System.out.println(mockedObject.return1("1"));

        mockedObject.returnOnObj(new Bohne("A"));
        Mockito.when(null).thenReturn("On Obj A");

        mockedObject.returnOnObj(new Bohne("B"));
        Mockito.when(null).thenReturn("On Obj B");

        System.out.println(mockedObject.returnOnObj(new Bohne("A")));
        System.out.println(mockedObject.returnOnObj(new Bohne("B")));
        System.out.println(mockedObject.returnOnObj(new Bohne("B")));
        System.out.println(mockedObject.returnOnObj(new Bohne("A")));
    }

}
class MyObj {
    public String get1(){return "not mocked 1";}
    public String get2(){return "not mocked 2";}
    public String return1(String in){return  "not mocked";}
    public String returnOnObj(Bohne in){return  "not mocked";}
}
class Bohne {
    public String id;

    public Bohne(String id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Bohne)) return false;
        Bohne bohne = (Bohne) o;
        return Objects.equals(id, bohne.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
/*
Output:
super cool string 1.1
super cool string 1.1
super cool string 2
Mock for MyObj, hashCode: 650023597
Return 1
Return 2
Return 2
Return 1
On Obj A
On Obj B
On Obj B
On Obj A

Process finished with exit code 0
 */

 

Set mit einem einzigen Element erstellen

 

UniqueId instrumentId = new UniqueId();
new HashSet<>(Arrays.asList(instrumentId))

Static Method and Concurrency (MultyThrading) / Java Memory Model

Clarification by user Selig on stackoverflow:

„Memory in java is split up into two kinds – the heap and the stacks. The heap is where all the objects live and the stacks are where the threads do their work. Each thread has its own stack and can’t access each others stacks. Each thread also has a pointer into the code which points to the bit of code they’re currently running.

When a thread starts running a new method it saves the arguments and local variables in that method on its own stack. Some of these values might be pointers to objects on the heap. If two threads are running the same method at the same time they will both have their code pointers pointing at that method and have their own copies of arguments and local variables on their stacks. They will only interfere with each other if the things on their stacks point to the same objects on the heap. In which case all sorts of things might happen. But as Hans points out, Strings are immutable (cannot be changed) so we’re safe if this is the only object being „shared“.

So many threads can be running the same method. They might not be running at the same time – it depends how many cores you have on your machine as the JVM maps Java threads to OS threads, which are scheduled onto hardware threads. You therefore have little control over the way these threads interleave without using complex synchronisation mechanisms.“