Saturday, October 31, 2015

Oracle Service Bus'da Dinamik Yönlendirme (=Dynamic Routing)

Oracle'ın Orta Katman Platformu üzerinde Servis Odaklı Mimari (SOM, =Service Oriented Architecture) uygulaması geliştirilmek istenirse, karşımıza üç ayrı çözüm ve iki ayrı ürün ailesi çıktığını görüyoruz:
1. Oracle SOA and BPM Suite 11g
    Business Process Execution Language (BPEL)
    Business Process Modeling Notation (BPMN)
2. Oracle Service Bus 11g
   Enterprise Service Bus (EBS)
11g sürümünde ürünlerin biri birinden bağımsız olduğunu görüyoruz, OSB orta katmanın ikinci sınıf vatandaşı gibi duruyor. Bu durumu, Enterprise Manager'a baktığımızda görebiliyoruz:
Şekil-1 Oracle Enterprise Manager 11g'de sadece Oracle SOA Suite'deki Karma Uygulamaları yönetebiliyoruz
Oracle Enterprise Manager 12c'de SOA başlığı altında hem Karma Uygulamaları (=Composite Applications) hem de OSB uygulamalarını yönetebiliyoruz:
Şekil-2 Oracle Enterprise Manager 12c'de hem Oracle SOA Suite'deki Karma Uygulamaları hem de OSB 12c uygulamalarını aynı çatı altında yönetebiliyoruz
OSB 11g'de geliştirme yapmak için iki araç bulunuyor:
1. Web tabanlı bir uygulama: OSB Console
Şekil-3 Oracle OSB 11g'de web tabanlı tasarım konsolu
2. Oracle Enterprise Pack for Eclipse    
Şekil-4 Oracle Enterprise Pack for Eclipse ile OSB 11g projesi geliştirmek
Oracle orta katmanda uygulama geliştirmek için diğer tüm ürünlerinde JDeveloper kullanıyoruz. Nihayet OSB 12c'de geliştirme aracı olarak JDeveloper kullanıyoruz:
Şekil-5 JDeveloper 12c ile OSB 12c projesi geliştirmek
SOM'da farklı türde uygulamalar geliştirebiliriz:
1. Tümleştirme Uygulamaları
Kurumlarda farklı platformlarda koşan farklı programlama dili ya da farklı uygulama geliştirme çatısı kullanılarak geliştirilmiş kurumsal uygulamalar bulunur. Bu uygulamaların bir kısmı kurum tarafından geliştirilmiş, bir kısmı satın alınmış, bir kısmı da dışarıya ihale edilerek geliştirilmiş olabilir. Tümleştirmeden amaç bu uygulamaların bir iş sürecini destekleyecek şekilde yeniden yazılmalarına gerek kalmadan değişen ihtiyaçlara karşılık verecek şekilde birlikte çalışmalarını sağlamaktır. Tümleştirme uygulamalarını BPEL ya da ESB kullanarak gerçekleştirebiliriz. Hangi durumda BPEL hangi durumda ESB kullanmalıyız? Bu soruyu Oracle SOA Suite ve Oracle Service Bus ürünü özelinde cevaplamaya çalışalım:
  • Eğer süreçte yer alan çağrılar kısa soluklu ve senkron servisler ise OSB tercih edilmelidir.
  • Eğer süreçte yer alan çağrılar uzun soluklu ve asenkron servislerden oluşuyor ise BPEL tercih edilmelidir.
2. İş Süreç Yönetimi
İş süreçlerini otomatikleştirmek, verimini arttırmak, kaynak kullanımı iyileştirmek ve maliyetleri azaltmak amacıyla iş süreçlerini yazılımla destekliyoruz. İş süreçlerini BPEL ya da BPMN kullanarak gerçekleştirebiliriz. Hangi durumda BPEL hangi durumda BPMN kullanmalıyız?
  • Eğer iş sürecinin iş mantığı karmaşık programlama yapıları içeriyorsa BPEL tercih edilmelidir.
  • Eğer süreç ağırlıklı olarak onay mekanizması içeriyor ve yoğun İş Kuralı (=Business Rule) kullanımı varsa BPMN tercih edilmelidir. 
Oracle OSB'de Yönlendirme
Oracle OSB gelen istek paketinin içeriğine ve ya başlığına göre yönlendirme yapabilir. Oracle OSB, farklı yönlendirme örüntülerini destekler:
1. Statik yönlendirme
Vekil servis (ProcessOrderServicePS) içinden isteği her zaman dışarıdaki sabit bir iş servisine (ProcessOrderServiceBS) yönlendirmek istiyoruz:
Şekil-6 Statik yönlendirme
2. Yönlendirme Tablosu
Sipariş mesajı içindeki kargo şirketi seçimine göre, seçilen kargo şirketinin web servisini çağırmak istiyoruz:
Şekil-7 Yönlendirme Tablosu ile tasarım
Projede (Shipping), kargo şirketlerinin web servisleri, birer İş Servisi olarak Shipping/Business Services dizini altında tanıtılmış durumda:
Şekil-8 Shipping projesindeki kargo şirketlerine ait İş Servisi tanımları
3. Dinamik yönlendirme
İkinci yöntemde (yönlendirme tablosu) yeni kargo şirketleri eklendiğinde, geliştirme yapmak gerekir. Dinamik yönlendirmede ise İş Servisinin isimlendirilmesinde bir sistematik kurularak, İş Servisinin adı XQuery ifadesi yardımıyla yürütme zamanında oluşturularak, yönlendirme dinamik olarak gerçekleştirilebilir:
Şekil-9 DynamicRoutingPS isimli vekil servisin (=Proxy Service) akışı (=Flow)

Şekil-10 Dinamik yönlendirmeden önce routing değişkeni, XQuery ifadesi ile çağrılacak İş Servisinin URI'yı ile dolduruluyor
Şekil-11 routing değişkenini ilklendirmekte kullanılan XQuery ifadesi

Şekil-12 routing değişkeni ile dinamik yönlendirme 
 Her kargo şirketinin kendi web servisi bulunuyor. Bu servislerin beklediği SOAP zarfının içeriği farklı olacaktır. Servisleri çağırmadan önce servisin beklediği mesaja dönüştürmek gerekecektir. Bu dönüşümü de dinamik olarak OSB'de gerçekleştirmek mümkündür:
Şekil-13 Oracle OSB'de dinamic XQuery uygulaması
DynamicRoutingPS isimli vekil servisi test edelim. İstek dokümanında kargo şirketi olarak UPS'yi seçiyoruz:
 Execute butonuna bastığımızda istek vekile ulaşıyor ve akışa göre Shipping/Business Service/UPSShippingService isimli servise yönlendirilmesi gerekir:
Bir test daha gerçekleştirelim. Bu kez istek dokümanında kargo şirketi olarak FedEx'i seçelim:
Execute butonuna bastığımızda istek vekile ulaşıyor ve akışa göre Shipping/Business Service/FedExShippingService isimli servise yönlendirilmesi gerekir:
Yukarıdaki testlerde hem içeriğe göre yönlendirme hem de dinamik olarak XQuery ile dönüşüm yapıyoruz. ShippingType elemanının içeriği UPS değerine sahipken UPSShippingService servisine yönlendirme gerçekleşirken, çağrıda dinamik XQuery ile dönüştürülen <ser:upsOrder> dokümanı kullanılmıştır. ShippingType elemanının içeriği FedEx değerine sahipken FedExShippingService servisine yönlendirme gerçekleşirken, çağrıda dinamik XQuery ile dönüştürülen <ser:fedExOrder> dokümanı kullanılmıştır.

Saturday, October 3, 2015

JDK 9'da Process API'deki Yenilikler

JDK 9'un çıkmasına daha henüz çok var, yaklaşık bir yıl:
2015/12/10Feature Complete
2016/02/04All Tests Run
2016/02/25Rampdown Start
2016/04/21Zero Bug Bounce
2016/06/16Rampdown Phase 2
2016/07/21Final Release Candidate
2016/09/22General Availability
JDK 9'daki yenilikler yine JDK 8'de olduğu gibi Oracle firmasına önerilen ve kabul edilen JEP (JDK Enhancement Proposal) üzerinden gerçekleşiyor. Şu ana kadar kabul edilen JEP'ler aşağıda listelenmiştir:
102: Process API Updates
110: HTTP 2 Client
143: Improve Contended Locking
158: Unified JVM Logging
165: Compiler Control
193: Variable Handles
197: Segmented Code Cache
199: Smart Java Compilation, Phase Two
201: Modular Source Code
211: Elide Deprecation Warnings on Import Statements
212: Resolve Lint and Doclint Warnings
213: Milling Project Coin
214: Remove GC Combinations Deprecated in JDK 8
215: Tiered Attribution for javac
216: Process Import Statements Correctly
217: Annotations Pipeline 2.0
219: Datagram Transport Layer Security (DTLS)
220: Modular Run-Time Images
221: Simplified Doclet API
222: jshell: The Java Shell (Read-Eval-Print Loop)
223: New Version-String Scheme
224: HTML5 Javadoc
225: Javadoc Search
226: UTF-8 Property Files
227: Unicode 7.0
228: Add More Diagnostic Commands
229: Create PKCS12 Keystores by Default
230: Microbenchmark Suite
231: Remove Launch-Time JRE Version Selection
232: Improve Secure Application Performance
233: Generate Run-Time Compiler Tests Automatically
235: Test Class-File Attributes Generated by javac
236: Parser API for Nashorn
237: Linux/AArch64 Port
238: Multi-Release JAR Files
240: Remove the JVM TI hprof Agent
241: Remove the jhat Tool
243: Java-Level JVM Compiler Interface
244: TLS Application-Layer Protocol Negotiation Extension
245: Validate JVM Command-Line Flag Arguments
246: Leverage CPU Instructions for GHASH and RSA
247: Compile for Older Platform Versions
248: Make G1 the Default Garbage Collector
249: OCSP Stapling for TLS
250: Store Interned Strings in CDS Archives
251: Multi-Resolution Images
252: Use CLDR Locale Data by Default
253: Prepare JavaFX UI Controls & CSS APIs for Modularization
254: Compact Strings
255: Merge Selected Xerces 2.11.0 Updates into JAXP
256: BeanInfo Annotations
257: Update JavaFX/Media to Newer Version of GStreamer
258: HarfBuzz Font-Layout Engine
Bu yazıda listenin ilk sırasındaki Process API'ye getirilmesi planlanan yeniliklere göz atacağız. İşletim sisteminde çalışan uygulamalar proses olarak adlandırılır. JDK, 1.0 sürümünden itibaren proseslerle çalışmak için bize java.lang.Process soyutlaması sunmuş olsa da, prosesin kimlik bilgisini (PID, Process ID) elde etmek gibi basit bir işlem için bile içinde bir çözüm bulamıyoruz. Çalışan uygulamanın PID değerini, çok dolaylı bir yoldan, sorunlu bir şekilde elde etmek durumunda kalırız:
package com.example.process;

import java.lang.management.ManagementFactory;

/**
 *   @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class GetPID {

   private static final int PID = 0;
   private static final int HOST = 1;

   public static void main(String[] args) {
      String name = ManagementFactory.getRuntimeMXBean().getName();
      String[] parts = name.split("@");
      int pid = Integer.parseInt(parts[PID]);
      String host = parts[HOST];
      System.out.println("PID : " + pid);
      System.out.println("Host: " + host);
   }
}
Java 9'da ProcessHandle sınıfı ile tanışıyoruz. Bu sınıfı kullanarak, örneğin, çalışan uygulamanın PID değerine basit ve sorunsuz bir şekilde ulaşabiliriz:
package com.example.java9;

/**
 *
 * @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class GetPID {

    public static void main(String[] args) {
        System.err.println("PID: " + ProcessHandle.current().getPid());
    }

}
ProcessHandle sınıfı kullanılarak, işletim sistemindeki tüm proses bilgilerine ulaşılabilinir. Aşağıda bu yeni sınıf yardımı ile neler yapabileceğimize bir bakalım. Java 9 API'leri elbette Java 8 ile gelen tüm yeniliklerden yararlanıyor: Stream API, Lambda ifadeleri, MapReduce çatısı, Optional, CompletableFuture, Time API ve diğerleri.
  • İşletim sisteminde çalışan proseslerin sayısı
package com.example.java9;

/**
 *
 * @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class PrintNumberOfProcesses {

    public static void main(String[] args) {
        long numberOfProcesses = ProcessHandle.allProcesses().count();
        System.out.println("Number of processes: " + numberOfProcesses);
    }
}
  • İşletim sisteminde çalışan prosesleri yaratan komutların listesi
package com.example.java9;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Consumer;

/**
 *
 * @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class ListAllCommands {

 public static void main(String[] args) {
    Consumer<String> printCommand
         = command -> {
             Path path = Paths.get(command);
             System.out.println(path.getFileName());
         };
    ProcessHandle.allProcesses()
           .filter( p -> p.info().command().isPresent() )
           .map( p -> process.info().command().get() )
           .distinct()
           .sorted()
           .forEach(printCommand);
 }
}
Örnek ekran çıktısı:
acrotray.exe
chrome.exe
vmware-tray.exe
ETDCtrl.exe
ipoint.exe
itype.exe
Nimi Places.exe
RAVBg64.exe
RAVCpl64.exe
livecomm.exe
WWAHost.exe
GWX.exe
RuntimeBroker.exe
SettingSyncHost.exe
SkyDrive.exe
conhost.exe
hkcmd.exe
igfxpers.exe
igfxsrvc.exe
mspaint.exe
rundll32.exe
taskhostex.exe
explorer.exe
splwow64.exe
notepad++.exe
java.exe
netbeans64.exe
TSVNCache.exe
TOTALCMD64.EXE
VBoxSVC.exe
VirtualBox.exe
  • İşletim sistemindeki tüm proseslerin listesi
package com.example.java9;

import java.util.function.Consumer;
import static java.lang.ProcessHandle.Info;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;

/**
 *
 * @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class ListAllProcesses {

    public static void main(String[] args) {
        DateTimeFormatter formatter
                = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss")
                .withZone(ZoneId.systemDefault());
        Consumer<String> printUser = user -> {
            System.out.println("User: " + user);
        };
        Consumer<String> printCmd = cmd -> {
            System.out.println("Command: " + cmd);
        };
        Consumer<String> printCmdLine = cmdln -> {
            System.out.println("Command line: " + cmdln);
        };
        Consumer<String[]> printArgs = arguments -> {
            System.out.println("Arguments: " + Arrays.toString(arguments));
        };
        Consumer<Instant> printInstant = inst -> {
            System.out.println("Start time: " + formatter.format(inst));
        };
        Consumer<Duration> printCpu = duration -> {
            System.out.println("CPU time (millisec): " + duration.toMillis());
        };
        Consumer<Info> printInfo
                = info -> {
                    info.user().ifPresent(printUser);
                    info.command().ifPresent(printCmd);
                    info.commandLine().ifPresent(printCmdLine);
                    info.arguments().ifPresent(printArgs);
                    info.startInstant().ifPresent(printInstant);
                    info.totalCpuDuration().ifPresent(printCpu);
                    System.out.println();
                };

        ProcessHandle.allProcesses()
                .filter(p -> p.isAlive())
                .map(p -> p.info())
                .forEach(printInfo);
    }
}
Uygulamanın örnek ekran çıktısı:
run:
User: OMEGACW\bkurt
Command: C:\Program Files\Microsoft Mouse and Keyboard Center\itype.exe
Start time: 2015-09-28-00:40:25
CPU time (millisec): 77953

User: OMEGACW\bkurt
Command: C:\Program Files\Microsoft Mouse and Keyboard Center\ipoint.exe
Start time: 2015-09-28-00:40:25
CPU time (millisec): 166984

User: OMEGACW\bkurt
Command: C:\Windows\System32\taskhostex.exe
Start time: 2015-09-28-00:40:25
CPU time (millisec): 9265

User: OMEGACW\bkurt
Command: C:\Windows\explorer.exe
Start time: 2015-09-28-00:40:25
CPU time (millisec): 640453

User: OMEGACW\bkurt
Command: C:\Windows\System32\GWX\GWX.exe
Start time: 2015-09-28-00:40:41
CPU time (millisec): 2437

User: OMEGACW\bkurt
Command: C:\Windows\System32\SettingSyncHost.exe
Start time: 2015-09-28-00:41:25
CPU time (millisec): 55937

User: OMEGACW\bkurt
Command: C:\Windows\System32\SkyDrive.exe
Start time: 2015-09-28-00:41:37
CPU time (millisec): 4796

User: OMEGACW\bkurt
Command: C:\opt64\tortoisesvn\bin\TSVNCache.exe
Start time: 2015-09-28-00:41:42
CPU time (millisec): 1562

User: OMEGACW\bkurt
Command: C:\Windows\System32\igfxsrvc.exe
Start time: 2015-09-28-00:41:50
CPU time (millisec): 10718

User: OMEGACW\bkurt
Command: C:\Windows\System32\hkcmd.exe
Start time: 2015-09-28-00:41:50
CPU time (millisec): 93

User: OMEGACW\bkurt
Command: C:\Windows\System32\igfxpers.exe
Start time: 2015-09-28-00:41:50
CPU time (millisec): 2593

User: OMEGACW\bkurt
Command: C:\Program Files\Realtek\Audio\HDA\RAVCpl64.exe
Start time: 2015-09-28-00:41:51
CPU time (millisec): 515

User: OMEGACW\bkurt
Command: C:\Program Files\Realtek\Audio\HDA\RAVBg64.exe
Start time: 2015-09-28-00:41:52
CPU time (millisec): 578

User: OMEGACW\bkurt
Command: C:\Program Files\Realtek\Audio\HDA\RAVBg64.exe
Start time: 2015-09-28-00:41:53
CPU time (millisec): 281

User: OMEGACW\bkurt
Command: C:\Program Files\Elantech\ETDCtrl.exe
Start time: 2015-09-28-00:41:54
CPU time (millisec): 100109

User: OMEGACW\bkurt
Command: C:\Windows\System32\rundll32.exe
Start time: 2015-09-28-00:41:55
CPU time (millisec): 312

User: OMEGACW\bkurt
Command: C:\Program Files\Nimi Places\Nimi Places.exe
Start time: 2015-09-28-00:41:57
CPU time (millisec): 52453

User: OMEGACW\bkurt
Command: C:\Program Files (x86)\VMware\VMware Workstation\vmware-tray.exe
Start time: 2015-09-28-00:42:03
CPU time (millisec): 671

User: OMEGACW\bkurt
Command: C:\Program Files (x86)\Adobe\Acrobat 9.0\Acrobat\acrotray.exe
Start time: 2015-09-28-00:42:08
CPU time (millisec): 500

User: OMEGACW\bkurt
Command: C:\opt64\totalcmd\TOTALCMD64.EXE
Start time: 2015-09-28-00:43:05
CPU time (millisec): 21906

User: OMEGACW\bkurt
Command: C:\opt32\npp\notepad++.exe
Start time: 2015-09-28-00:43:43
CPU time (millisec): 36015

User: OMEGACW\bkurt
Command: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Start time: 2015-09-28-00:48:07
CPU time (millisec): 3633578

User: OMEGACW\bkurt
Command: C:\opt64\totalcmd\TOTALCMD64.EXE
Start time: 2015-09-28-09:14:35
CPU time (millisec): 564062

User: OMEGACW\bkurt
Command: C:\Windows\splwow64.exe
Start time: 2015-09-28-19:19:34
CPU time (millisec): 6578

User: OMEGACW\bkurt
Command: C:\opt64\virtualbox\VirtualBox.exe
Start time: 2015-10-01-13:56:31
CPU time (millisec): 86531

User: OMEGACW\bkurt
Command: C:\opt64\virtualbox\VBoxSVC.exe
Start time: 2015-10-01-13:56:32
CPU time (millisec): 192718

User: OMEGACW\bkurt
Command: C:\opt64\virtualbox\VirtualBox.exe
Start time: 2015-10-01-13:57:01
CPU time (millisec): 62

User: OMEGACW\bkurt
Command: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Start time: 2015-10-01-21:55:51
CPU time (millisec): 31000

User: OMEGACW\bkurt
Command: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Start time: 2015-10-01-22:11:35
CPU time (millisec): 24671

User: OMEGACW\bkurt
Command: C:\opt64\netbeans-dev-jdk9-201506180405\bin\netbeans64.exe
Start time: 2015-10-01-22:12:00
CPU time (millisec): 2255062

User: OMEGACW\bkurt
Command: C:\opt64\java\jdk1.9.0\bin\java.exe
Start time: 2015-10-03-07:20:24
CPU time (millisec): 328

User: OMEGACW\bkurt
Command: C:\Windows\System32\conhost.exe
Start time: 2015-10-03-07:20:24
CPU time (millisec): 0
  • İşletim sisteminde şu an çalışan prosesler arasında en uzun süredir çalışan proses
package com.example.java9;

import java.lang.ProcessHandle.Info;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Consumer;

/**
 *
 * @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class LongestRunningProcess {

    public static void main(String[] args) {
        DateTimeFormatter formatter
                = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss")
                .withZone(ZoneId.systemDefault());
        Consumer<String> printUser = user -> {
            System.out.println("User: " + user);
        };
        Consumer<String> printCmd = cmd -> {
            System.out.println("Command: " + cmd);
        };
        Consumer<String> printCmdLine = cmdln -> {
            System.out.println("Command line: " + cmdln);
        };
        Consumer<String[]> printArgs = arguments -> {
            System.out.println("Arguments: " + Arrays.toString(arguments));
        };
        Consumer<Instant> printInstant = inst -> {
            System.out.println("Start time: " + formatter.format(inst));
        };
        Consumer<Duration> printCpu = duration -> {
            System.out.println("CPU time (millisec): " + duration.toMillis());
        };
        Consumer<Info> printInfo
                = info -> {
                    info.user().ifPresent(printUser);
                    info.command().ifPresent(printCmd);
                    info.commandLine().ifPresent(printCmdLine);
                    info.arguments().ifPresent(printArgs);
                    info.startInstant().ifPresent(printInstant);
                    info.totalCpuDuration().ifPresent(printCpu);
                    System.out.println();
                };        
        Instant now= Instant.now();
        Optional<Info> processInfo= 
                ProcessHandle.allProcesses()
                    .map( p -> p.info() )
                    .filter(info -> info.startInstant().isPresent())
                    .max( (p,q) -> q.startInstant().orElse(now)
                        .compareTo(p.startInstant().orElse(now)));
        processInfo.ifPresent(printInfo);
    }
}
Uygulamanın örnek ekran çıktısı:
run:
User: OMEGACW\bkurt
Command: C:\Program Files\Microsoft Mouse and Keyboard Center\itype.exe
Start time: 2015-09-28-00:40:25
CPU time (millisec): 78156

BUILD SUCCESSFUL (total time: 0 seconds)
  • İşletim sisteminde şu an çalışan prosesler arasında en çok işlemci zamanını kullanan proses
package com.example.java9;

import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Consumer;

/**
 *
 * @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class MostCpuConsumingProcess {

    public static void main(String[] args) {
        DateTimeFormatter formatter
                = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss")
                .withZone(ZoneId.systemDefault());
        Consumer<String> printUser = user -> {
            System.out.println("User: " + user);
        };
        Consumer<String> printCmd = cmd -> {
            System.out.println("Command: " + cmd);
        };
        Consumer<String> printCmdLine = cmdln -> {
            System.out.println("Command line: " + cmdln);
        };
        Consumer<String[]> printArgs = arguments -> {
            System.out.println("Arguments: " + Arrays.toString(arguments));
        };
        Consumer<Instant> printInstant = inst -> {
            System.out.println("Start time: " + formatter.format(inst));
        };
        Consumer<Duration> printCpu = duration -> {
            System.out.println("CPU time (millisec): " + duration.toMillis());
        };
        Consumer<ProcessHandle.Info> printInfo
                = info -> {
                    info.user().ifPresent(printUser);
                    info.command().ifPresent(printCmd);
                    info.commandLine().ifPresent(printCmdLine);
                    info.arguments().ifPresent(printArgs);
                    info.startInstant().ifPresent(printInstant);
                    info.totalCpuDuration().ifPresent(printCpu);
                    System.out.println();
                };
        Optional<ProcessHandle.Info> processInfo
                = ProcessHandle.allProcesses()
                .map(p -> p.info())
                .filter(info -> info.totalCpuDuration().isPresent())
                .max((p, q) -> p.totalCpuDuration().orElse(Duration.ZERO)
                    .compareTo(q.totalCpuDuration().orElse(Duration.ZERO)));
        processInfo.ifPresent(printInfo);
    }
}
Uygulamanın örnek ekran çıktısı:
run:
User: OMEGACW\bkurt
Command: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Start time: 2015-09-28-00:48:07
CPU time (millisec): 3667093

BUILD SUCCESSFUL (total time: 0 seconds)
  • proses adı verilen tüm prosesleri sonlandıralım
package com.example.java9;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Predicate;

/**
 *
 * @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class KillProcess {

    public static void main(String[] args) {
        if (args.length==0){
            System.out.println("Usage: ");
            System.out.println("ProcessKill <list of process names>");
            System.out.println("Example: \n\tProcessKill calc.exe mspaint.exe");
        }
        Predicate<ProcessHandle> processCriteria
                = p -> {
                    Optional<String> cmd = p.info().command();
                    if (cmd.isPresent()) {
                        Path path = Paths.get(cmd.get());
                        return Arrays.stream(args)
                               .anyMatch( arg -> path.getFileName().toString().equals(arg) );
                    }
                    return false;
                };
        ProcessHandle.allProcesses()
                .filter(p -> p.isAlive())
                .filter(processCriteria)
                .forEach(ProcessHandle::destroyForcibly);
    }
}
  • Verilen komutu çalıştıran ve bekçi köpeği olarak izleyen uygulama
package com.example.java9;

import java.util.concurrent.CompletableFuture;

/**
 *
 * @author Binnur Kurt (binnur.kurt@gmail.com)
 */
public class WatchDog {

    public static void main(String[] args) throws Exception {
        String cmd = args[0];
        do {
            Process process = Runtime.getRuntime().exec(cmd);
            ProcessHandle ph = process.toHandle();
            CompletableFuture<ProcessHandle> onExit = ph.onExit();
            onExit.get();
            System.err.println("Exit value: "+process.exitValue());
        } while (true);
    }
}
Yukarıdaki örnek uygulamaları çalıştırabilmek ve Java 9 ile gelen yenilikler ile tanışmak için makinanıza öncelikle JDK 9 kurmanız gerekir. JDK 9, şu an "Early Access" olarak erişime açık. Bu bağlantıdan elinizdeki platform için kurulum dosyalarına ulaşabilirsiniz. Java 9'da kod geliştirebilmek için uygun bir IDE bulmakta zorlanabilirsiniz. Yukarıdaki kodları "NetBeans Java 9" ile çalışabilirsiniz. 
Java 9 ile gelen yenilikleri ilerideki yazılarda incelemeye devam edeceğiz.