So stellt es der Artikel https://www.infoworld.com/article/3407781/a-plan-to-bring-java-to-ios.html vor.
Kerngedanke: Das Projekt OpenJDK Mobile wieder aktivieren, GraalVM ahead-of-time Compiler nutzen.
So stellt es der Artikel https://www.infoworld.com/article/3407781/a-plan-to-bring-java-to-ios.html vor.
Kerngedanke: Das Projekt OpenJDK Mobile wieder aktivieren, GraalVM ahead-of-time Compiler nutzen.
Änderungen laut https://github.com/google/guava/releases/tag/v28.0:
collect
: Added Duration
-based overloads to some Queues
methods. (21d06cf)net
: Added MediaType
for „application/geo+json“. (36cd5cf)net
: Added a number of constants to HttpHeaders
.concurrent
: Removed deprecated CheckedFuture
and related utilities. (3dd22fe)concurrent
: Added Duration
-based overloads to many methods.concurrent
: Removed @Beta
from setFuture
. (5ec1360)concurrent
: Added deprecated FluentFuture.from(FluentFuture)
to point out redundant code. (f9f2807)graph
: Added GraphBuilder.immutable()
,ValueGraphBuilder.immutable()
and NetworkBuilder.immutable()
for building immutable graphs in a fluent way.ImmutableMap.entrySet()
. (74fc49f)Details siehe https://spring.io/blog/2019/07/04/explore-the-project-on-start-spring-io
Details bei Red Hat unter https://www.redhat.com/en/blog/announcing-general-availability-red-hat-jboss-enterprise-application-platform-72
Stichwörter:
22.–26. Oktober 2018 (KW 43), 12.–16. November 2018 (KW 46)
Java für Fortgeschrittene (›JAVA2‹)
8.–12. Oktober 2018 (KW 41), 26.–30. November 2018 (KW 48)
15.–17. Oktober 2018 (KW 42), 5.–7. November 2018 (KW 45), 3.–5. Dezember 2018 (KW 49)
JavaScript für Web-Entwickler (›JAVASCRIPT‹)
15.–17. Oktober 2018 (KW 42), 5.–7. November 2018 (KW 45), 3.–5. Dezember 2018 (KW 49)
Das javadoc-Tool hat die Aufgabe, den Java-Quellcode auszulesen und die Javadoc-Kommentare zu extrahieren. Was dann mit den Daten passiert, ist die Aufgabe eines Doclets. Das Standard-Doclet von Oracle erzeugt die bekannte Struktur auf verlinkten HTML-Dateien, aber es lassen sich auch eigene Doclets schreiben, um etwa in Javadoc-Kommentaren enthaltene Links auf Erreichbarkeit zu prüfen oder UML-Diagramme aus den Typbeziehungen zu erzeugen. Hervorzuheben ist JDiff (http://javadiff.sourceforge.net/), was Differenzen in unterschiedlichen Versionen der Java-Dokumentation – wie neu hinzugefügte Methoden – erkennt und meldet.
Die Doclet-API ist Teil vom JDK, und deklariert Typen und Methoden, mit denen sich Module, Pakete, Klassen, Methoden usw. und deren Javadoc-Texte erfragen lassen. Allerdings gibt es zwei Doclet-APIs:
Im folgenden Beispiel wollen wir ein kleines Doclet schreiben, das Klassen, Attribute, Methoden und Konstruktoren ausgibt, die das Javadoc-Tag @since 10 tragen. So lässt sich leicht ermitteln, was in der Version Java 10 alles hinzugekommen ist. Doclets werden normalerweise von der Kommandozeile aufgerufen und dem javadoc-Tool übergeben, doch da es mit der Tool-Schnittstelle auch selbst geht, können wir ein Programm mit main(…)-Methode schreiben, das die Neuerungen auf der Konsole ausgibt.
package com.tutego.insel.tools; import java.io.IOException; import java.nio.file.*; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; import javax.tools.*; import com.sun.javadoc.*; @SuppressWarnings( "deprecation" ) public class FindSinceTagsInJavadoc { public static class TestDoclet { public static boolean start( RootDoc root ) { Arrays.stream( root.classes() ).forEach( TestDoclet::processClass ); return true; } private static void processClass( ClassDoc clazz ) { Predicate<Doc> hasSinceTag = doc -> Arrays.stream( doc.tags( "since" ) ) .map( Tag::text ).anyMatch( "10"::equals ); if ( hasSinceTag.test( clazz ) ) System.out.printf( "%s -- Neuer Typ%n", clazz ); Arrays.stream( clazz.fields() ).filter( hasSinceTag ) .forEach( f -> System.out.printf( "%s -- Neues Attribut%n", f ) ); Arrays.stream( clazz.methods() ).filter( hasSinceTag ) .forEach( m -> System.out.printf( "%s -- Neue Methode%n", m ) ); Arrays.stream( clazz.constructors() ).filter( hasSinceTag ) .forEach( c -> System.out.printf( "%s -- Neuer Konstruktor%n", c ) ); } } public static void main( String[] args ) throws IOException { Path zipfile = Paths.get( System.getProperty( "java.home" ), "lib/src.zip" ); try ( FileSystem srcFs = FileSystems.newFileSystem( zipfile, null ) ) { Predicate<Path> filesToIgnore = p -> p.toString().endsWith( ".java" ) && ! p.toString().startsWith( "/javafx" ) && ! p.toString().startsWith( "/jdk" ) && ! p.toString().endsWith( "module-info.java" ) && ! p.toString().endsWith( "package-info.java" ); List<Path> paths = Files.walk( srcFs.getPath( "/" ) ) .filter( filesToIgnore ).collect( Collectors.toList() ); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); try ( StandardJavaFileManager fm = tool.getStandardFileManager( null, null, null ) ) { Iterable<? extends JavaFileObject> files = fm.getJavaFileObjectsFromPaths( paths ); tool.getTask( null, fm, null, TestDoclet.class, List.of( "-quiet" ), files ).call(); } } } }
Unsere main(…)-Methode bindet zunächst das ZIP-Archiv vom JDK mit den Quellen als Dateisystem ein. Im nächsten Schritt durchsuchen wir das Dateisystem nach den passenden Quellcodedateien und sammeln sie in eine Liste von Pfaden. Jetzt kann das DocumentationTool mit unserem Doclet konfiguriert und aufgerufen werden. call() startet das Parsen aller Quellen und führt anschließend zum Aufruf von start(RootDoc) unseres Doclets.
In unserer start(…)-Methode laufen wir über alle ermittelten Typen und rufen dann processClass(ClassDoc) auf. Dort passiert der eigentliche Test. Die Metadaten kommen dabei über diverse XXXDoc-Typen. Ein Predicate zieht den Tag-Test heraus.
Kurz nach Eclipse Photon basiert nun auch die STS auf der aktuellsten Eclipse-Version:
Der www.rheinwerk-verlag.de ist auf der Suche nach einem Überarbeiter für das Administrationshandbuch zu MySQL (https://www.rheinwerk-verlag.
nicht mehr die Zeit. Interessierte Autoren mögen sich bitte unter melden bei:
Christoph Meister, Lektor Computing
Rheinwerk Verlag GmbH | Rheinwerkallee 4 | 53227 Bonn
Telefon +49 228 42150-45
christoph . meister @ rheinwerk –
Oftmals nutzen die Beispiele im Internet Spring, oder — noch spezieller — Thymeleaf wird als Template-Engine in Spring MVC eingesetzt, daher jetzt nackt, so einfach es geht.
In unsere POM kommt:
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.0.9.RELEASE</version> </dependency>
Wir schreiben das Template demo.html:
<!DOCTYPE html> <html> <body> <p>Hey <span data-th-text="${name}">CHRISTIAN</span></p> </body> </html>
Und dann kann ein Java-Programm name füllen:
import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.templateresolver.FileTemplateResolver; public class ThymeleafDemo { public static void main( String[] args ) { FileTemplateResolver resolver = new FileTemplateResolver(); resolver.setCharacterEncoding( "UTF-8" ); TemplateEngine templateEngine = new TemplateEngine(); templateEngine.setTemplateResolver( resolver ); Context ctx = new Context(); ctx.setVariable( "name", "tutego" ); String result = templateEngine.process( "demo.html", ctx ); System.out.println( result ); } }
Details unter https://docs.gradle.org/4.6/release-notes.html
Infos unter http://wildfly.org/news/2018/02/28/WildFly12-Final-Released/. Wie auch Java 10 gibt es zeitbasierte Releasese: http://lists.jboss.org/pipermail/wildfly-dev/2017-December/006250.html.
Infos darüber unter https://netbeans.apache.org/download/nb90/index.html.
Allerdings frage ich mich, wer NB noch verwendet, ihr? Ich halte den NB-Zug für abgefahren. In den Insel kommen die Anmerkungen zu NB raus und IntelliJ stattdessen rein.
Die 9er Version kann kein Java 10, und die Entwickler freuen sich über Java 9-Support, wow, 1/2 Jahr nach dem Java 9 Release. In 2 Wochen kommt Java 10.
Präsentation und Code verlinkt unter https://blogs.oracle.com/java/jdbc-next%3a-a-new-asynchronous-api-for-connecting-to-a-database
Sehr spannend!
Siehe https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes und https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide.
Es knarrzt an einigen Stellen, ich musste zum Beispiel meine CRUD-Implementierungen anpassen, die Methodennamen haben sich geändert. Wie sind eure Erfahrungen?
Sich einen Iterator von einem Stream geben zu lassen ist nützlich, weil dann der Zeitpunkt des Konsumierens vom Zeitpunkt des Stream-Aufbaus getrennt werden kann. Es ist nicht einfach mehrere Streams gleichzeitig abzulaufen, doch mit Iteratoren funktioniert das. Zudem lässt sich in Stream mit einer Generator-Funktion einfach aufbauen, in Iterator aber nicht.
Beispiel: Aus zwei Streams sollen jeweils alterrnierend das nächste Element konsumiert und ausgegeben werden.
Iterator<Integer> iterator1 = Stream.of( 1, 3, 5 ).iterator(); Iterator<Integer> iterator2 = Stream.of( 2, 4, 6, 7, 8 ).iterator(); while ( iterator1.hasNext() || iterator2.hasNext() ) { if ( iterator1.hasNext() ) System.out.println( iterator1.next() ); if ( iterator2.hasNext() ) System.out.println( iterator2.next() ); }
Iterator ist ein Datentyp, der häufig in der Rückgabe verwendet wird, seltener als Parametertyp. Mit stream.iterator() ist es aber möglich, die Daten vom Stream genau an solchen Stellen zu übergeben. Einen Stream in einen Iterator zu konvertieren, um diesen dann mit hasNext()/next() abzulaufen, ist wenig sinnvoll, hierfür bietet sich genauso gut forEach(…) auf dem Stream an.
Der Typ Stream bietet eine Methode iterator(), erweitert jedoch die Schnittstelle Iterable nicht. In der Javadoc ist bei iterator() die Bemerkung „terminale Operation“ vermerkt, denn der Iterator saugt den Stream leer, sodass ein zweiter iterator()-Aufruf auf einem Stream nicht möglich ist. Bei Klassen, die Iterable implementieren, muss ein Aufruf von iterator() beliebig oft möglich sein. Bei Streams ist das nicht gegeben, da die Streams selbst nicht für die Daten stehen wie eine Collection, die daher Iterable ist.
Ist auf der anderen Seite ein Iterator gegeben, lässt sich dieser nicht direkt in einen Stream bringen. Iteratoren können wie Streams unendlich sein, und es gibt keinen Weg, die Daten eines Iterators als Quelle zu benutzen. Natürlich ist es möglich, den Iterator abzulaufen und daraus einen neuen Stream aufzubauen, dann muss der Iterator aber endlich sein.
Beispiel: Die Methode ImageIO.getImageReadersBySuffix(String) liefert einen Iterator von ImageReader-Objekten – sie sollen über einen Strom zugänglich sein:
Builder<ImageReader> builder = Stream.builder(); for ( Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix( "jpg" ); iter.hasNext(); ) builder.add( iter.next() ); Stream<ImageReader> stream = builder.build(); System.out.println( stream.count() ); // 1
Einen anderen Weg geht StreamSupport.
Ist eine alte Enumeration gegeben, hilft Collections.list(enumeration).stream(), denn list(…) liefert eine ArrayList mit allen Einträgen; list(Iterator) gibt es da hingegen nicht.
Die Schnittstelle Stream deklariert keine abstrakte iterator()-Methode, sondern bekommt die Methode vom Obertyp BaseStream vererbt. BaseStream ist insgesamt Basistyp von:
Alle diese drei Typen haben damit iterator()-Methdoden, doch die Rückgaben sind unterschiedlich:
Typ | iterator()-Methdoden und Rückgabe |
Stream<T> | Iterator<T> iterator() |
DoubleStream | PrimitiveIterator.OfDouble iterator() |
IntStream | PrimitiveIterator.OfInt iterator() |
LongStream | PrimitiveIterator.OfInt iterator() |
Unterschiedliche Rückgaben der Iteratoren
PrimitiveIterator ist eine Schnittstelle aus dem Paket java.util mit eben drei inneren statischen Schnittstellen: OfDouble, OfInt und OfLong, die PrimitiveIterator erweiten. Jeder dieser drei inneren Typen hat eigene, aber symmetrische Methoden:
Statt WrapperTyp und PrimitiverTyp ist dann Double, Integer, Long und double, int, double einzusetzen.
Beispiel: Ein vom Stream abgeleiter Iterator besorgt Zahlen. Diese werden in einem anderen Stream eingesetzt.
PrimitiveIterator.OfInt counter = IntStream.iterate( 1, Math::incrementExact ).iterator(); Stream.of( "Telegram", "WhatsApp", "Facebook Messenger", "Insta" ) .map( s -> counter.nextInt() + ". " + s ) .forEach( System.out::println );
Details zu den Neuerungen unter https://junit.org/junit5/docs/5.1.0/release-notes/index.html#release-notes-5.1.0
Das bedeutet, es gibt Syntaxerweiterungen, aber die sind erst mal zum Testen.
http://openjdk.java.net/jeps/12
An incubating language or VM feature is a new feature of the Java SE Platform that is fully specified, fully implemented, and yet impermanent. It is available in a JDK feature release to provoke developer feedback based on real world use; this may lead to it becoming permanent in a future Java SE Platform.
In der Mailliste fragen die Eclipse-Bauer schon nach, ob das verpflichtend ist … es wäre blöd, wenn man sich bei den JDT viel Mühe gibt, und dann wird das doch nicht übernommen: http://mail.openjdk.java.net/pipermail/jdk-dev/2018-February/000642.html
JEP-12 ist allerdings noch nicht bestätigt.
Alle Details unter https://www.eclipse.org/eclipse/news/4.8/M5/.
Der Formatter ist eines der großen Änderungen.
Auch das Behandeln von Testfällen-Code.