23 Mart 2022 Çarşamba

Thread Dump

Giriş
Burada bazı notlar var

IBM Thread and Monitor Dump Analyzer for Java (TMDA)
Bir örnek burada

BLOCKED THREAD
Çıktı şuna benzer. Burada thread'in bir şeyi beklediği yani bloke olduğu görülebilir.
"[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'" waiting for lock

CompletableFuture.completedFuture - İşin Belirtilen Değer İle Bitmesini Sağlar

Giriş
Factory metodudur. "Completed" bir CompletableFuture nesnesi döner yani isDone () metodu true olur. Açıklaması şöyle.
Creates an already completed CompletableFuture with a predefined result. Usually, this may act as the starting stage in your computation.
CompletableFuture.completed() ile aynı şeydir. Farklı olarak bu metod CompletableFuture döner. complete() metodunun imzası şöyle
public boolean complete(T value)
completedFuture () metodunun imzası şöyle
public static <U> CompletableFuture<U> completedFuture(U value)
Örnek
Şöyle yaparız.
List<String> userList = ...
CompletableFuture<List<String>> f = CompletableFuture.completedFuture(userList);
Örnek
Bir Stream'i kendi ExecutorService nesnemiz ile paralel olarak çalıştırmak için şöyle yaparız.
public static CompletableFuture<Void> performAllItemsBackup(Stream<Item> items) {
  ExecutorService pool = Executors.newFixedThreadPool(3);
  try {
    return CompletableFuture.allOf(
      items.map(CompletableFuture::completedFuture)
           .map(f -> f.thenAcceptAsync(performSingleItemBackup, pool))
           .toArray(CompletableFuture<?>[]::new));
  } finally {
    pool.shutdown();
  }
}
Örnek
Feign Client çağrılarını asenkron yapmak için şöyle yaparız. Elimizde senkron bir Feign Client olsun
@FeignClient(url = "${external.resource.base}", name = "external")
public interface ExternalFeignClient {

  @GetMapping(value = "${external.resource.records}", produces = "application/json")
  @Headers({ACCEPT_APPLICATION_JSON, CONTENT_TYPE_APPLICATION_JSON})
  ResponseWrapper<Record> getRecords(@RequestHeader Map<String, String> header,
                                     @RequestParam Map<String, String> queryMap,
                                     @RequestParam("limit") Integer limit,
                                     @RequestParam("offset") Integer offset);


}

@Service
public class ExternalFeignClientAsync {
  
  @Awtowired
  private ExternalFeignClient externalFeignClient;

  @Async
  CompletableFuture<ResponseWrapper<Record>> getRecordsAsync(Map<String, String> header,
                                                             Map<String, String> header,
                                                             Integer limit,
                                                             Integer offset){
    CompletableFuture.completedFuture(externalFeignClient.getRecords(header,header,
      limit,offset));
  }
}
Hepsini asenkron çağırmak için şöyle yaparız
@Service
public class ExternalService {
  
  @Autowired
  private ExternalFeignClientAsync externalFeignClientAsync;
  
  List<Record> getAllRecords() {
    
    final AtomicInteger offset = new AtomicInteger();
    int pageSize = properties.getPageSize(); // set this as you wish
    int batches = (totalCount / pageSize) + (totalCount % pageSize > 0 ? 1 : 0);
    return IntStream.range(0, batches)
      .parallel()
      .mapToObj(i -> {
        final int os = offset.getAndAdd(pageSize);
        return externalFeignClientAsync.getRecordsAsync(requestHeader, queryMap,
          fetchSize, os);
      })
      .map(CompletableFuture::join)
      .map(ResponseWrapper::getItems)
      .flatMap(List::stream)
      .toList();
  }
}



JEP 408: Simple Web Server - jwebserver komutu

Giriş
CGI veya servlet gibi şeyler desteklemez. Sadece öğrenme amaçlıdır. Java 18 ile geliyor. Açıklaması şöyle
Only idempotent HEAD and GET requests are served. Any other requests receive a 501 — Not Implemented or a 405 — Not Allowed response. The Simple Web Server supports HTTP/1.1 only. There is no HTTPS support.
Örnek
Şöyle yaparız. loopback ağ arayüzüne dinler ve port olarak 8000 kullanır.
$ jwebserver
Binding to loopback by default. For all interfaces use “-b 0.0.0.0” or “-b ::”.
Serving /cwd and subdirectories on 127.0.0.1 port 8000
URL: http://127.0.0.1:8000/
-b seçeneği
bind için kullanılacak ağ arayüzünü gösterir.
Örnek
Şöyle yaparızTüm ağ arayüzüne dinler ve port olarak 8000 kullanır.
$ jwebserver -b 0.0.0.0
Serving /cwd and subdirectories on 0.0.0.0 (all interfaces) port 8000
URL: http://123.456.7.891:8000/
-p seçeneği
port belirtmek içindir. Açıklaması şöyle
Simply put, Java 18 adds a new command line tool named jwebserver.

Usage example: jwebserver -p 9000

Running the command fires up a simple web server that serves static files from the current directory. You can define a custom port via -p and a custom directory via -d.

Right now the server is only intended for education, experiments, testing and similar, it’s not intended for the production usage.



21 Mart 2022 Pazartesi

Pattern match for switch - Java 17 İle Geliyor

Giriş
Açıklaması şöyle. Burada switch expressions kısmı önemli. Yani "switch block" ve "switch expression" farklı şeyler. Switch Expressions yazısına bakabilirsiniz.
The final new language feature that was added to Java 17 is pattern matching for switch expressions. Note that this is a preview version. This is the second occurrence of pattern matching in the language after it has been introduced via the instanceof operator.

In its most simple form, pattern matching is performed on the type of variable that is supplied. Compare this to a classical switch expression/statement where the value is used. Also note that there is a special handling for the null values. Normally, a null value would lead to a NullPointerException (NPE) so it would require an additional check. Thanks to the special handling of the null value this is no longer required. Finally, also notice that the required casting is again performed automatically by the compiler.
1. Genel Kullanım
Örnek

Şöyle yaparız
String printValue(Object obj) {
  return switch (obj) {
    case Integer i -> String.format("It is an integer with value %d", i);
    case Long l -> String.format("It is a Long with value %d", l);
    case String s -> String.format("It is a String with value %s", s);
    case null -> new String("You can't pass in a null value!");
    default -> String.format("Dunno the type, but the value is %s", obj.toString());
  };
}
2. Guarded Pattern
Örnek
Şöyle yaparız
String printValue(Object obj) {
return switch (obj) { case null -> new String("You can't pass in a null value!"); case String s && s.length() > 10 -> String.format("Long String with value %s", s); case String s -> String.format("Not so long String with value %s", s); default -> String.format("Dunno the type, but the value is %s", obj.toString()); }; }
Açıklaması şöyle
In the example above, a distinction can be made between strings with a length of up to 10 characters and strings with more than 10 characters.
Örnek
Şöyle yaparız
return switch (obj) {
case Integer i -> "It is an integer"; case String s -> "It is a string"; case Employee employee && employee.getDept().equals("IT") -> "IT Employee"; default -> "It is none of the known data types"; };
3. Parenthesised pattern
Açıklaması şöyle
Basically, this is when you use additional parenthesis to prevent an invalid outcome of a pattern predicate
Örnek
Şöyle yaparız
boolean printValue(Object obj) {
return switch (obj) { case String s && s.length() >= 2 && (s.contains("@") || s.contains("!")) -> true; default -> false; }; }


14 Mart 2022 Pazartesi

Eclipse Memory Analyzer Tool - MAT

Giriş
Eclipse MAT buradan indirilir. Kullanım için bazı notlar burada. Notlar şöyle

1. Eclipse MAT – heap size :  İncelenen heapdump büyüklüğünden, 1 GB daha fazla bellek kullanmak lazım
2. Enable ‘keep unreachable objects’ : Bu seçeneği etkinleştirmek lazım
3. Smart Data Settings : Bu seçenek ile bellek büyüklükleri KB, MB, GB ile gösteriliyor

Keep Unreachable Object Seçeneği
Bu seçenek normalde kapalı. Çünkü GC unreachable nesneleri silebileceğini varsayıyor. Ancak bazen 
java.lang.OutOfMemoryError: GC Overhead limit exceeded error hatası alıyoruz. Bu GC'nin çalıştığını ama temizlik yapamadığını gösterir. Bu durumda Keep unreachable object seçeneği ile silinmesi gereken ama henüz bellekte olan nesneleri de görebiliriz. Açıklaması şöyle
In order to enable unreachable objects in MAT, you need to go to the Window → Preferences
Then go to the memory analyzer section, select the Keep unreachable object tick, and click apply.
Açıklaması şöyle
Also, after enabling the unreachable objects, if you go to the dominator tree, it will show the unreachable objects along with the live objects.

Object Query Language

Leak Suspects Menüsü
Problem Suspect 1
Problem Suspect 2 
şeklinde listeler. Problem Suspect 1 için açıklaması şöyle
This will show you the biggest objects and their retained sizes, which is the amount of memory that will be freed if this object is garbage collected.
Bu listedeki adresleri takip edebiliriz. Açıklaması şöyle
Now we have an address in yellow section.
0x7ff78b9c0
When we search this address from search icon in top section, a very detailed screen will appear.