31 Mart 2023 Cuma

ANSI Colors

Örnek
Şöyle yaparız
public static final String ANSI_RESET = "\u001B[0m";
public static final String ANSI_BLACK = "\u001B[30m";
public static final String ANSI_RED = "\u001B[31m";
public static final String ANSI_GREEN = "\u001B[32m";
public static final String ANSI_YELLOW = "\u001B[33m";
public static final String ANSI_BLUE = "\u001B[34m";
public static final String ANSI_PURPLE = "\u001B[35m";
public static final String ANSI_CYAN = "\u001B[36m";
public static final String ANSI_WHITE = "\u001B[37m";

String str = ANSI_GREEN + "green " +  ANSI_RESET + ANSI_BLUE + "blue" + ANSI_RESET;
System.out.println(str);


29 Mart 2023 Çarşamba

Testcontainers CouchbaseContainer Sınıfı

Örnek
Şöyle yaparız
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.couchbase.BucketDefinition;
import org.testcontainers.couchbase.CouchbaseContainer;

private static final String BUCKET_NAME = "mybucket";

public static final CouchbaseContainer container = new CouchbaseContainer("couchbase/server:7.1.1")
  .withBucket(new BucketDefinition(BUCKET_NAME));
  .withBucket(new BucketDefinition(BUCKET_NAME))
  .withStartupTimeout(Duration.ofSeconds(120))
  .withFileSystemBind("target/couchbase-logs", "/opt/couchbase/var/lib/couchbase/logs")
  .withLogConsumer(new Slf4jLogConsumer(LOGGER).withPrefix("Docker"));


28 Mart 2023 Salı

ServerSocketFactory Sınıfı

Giriş
Şu satırı dahil ederiz.
import javax.net.ServerSocketFactory;
Soyut bir sınıftır.Kalıtım şöyle
ServerSocketFactory 
  javax.net. DefaultServerSocketFactory 
  javax.net.ssl.SSLServerSocketFactory
  org.apache.commons.net.ftp.FTPSServerSocketFactory
  org.apache.commons.net.ftp.FTPSServerSocketFactory
  

createServerSocket metodu - port + backlog + bind address
Örnek
Şöyle yaparız.
int port = 31_003;
ServerSocket serverSocket = ServerSocketFactory.getDefault()
  .createServerSocket(port, 1, InetAddress.getLocalHost());

ServerSocket Sınıfı İçin Boş Port Bulma

Giriş
İki yöntem var
1. Rastgele (Ephemeral) port kullanılır. İşletim sistemi boş bir port kullanmayı garanti eder
2. Deneyerek kullanılmayan port bulunur

1. Rastgele (Ephemeral) Port Kullanma
Örnek
Şöyle yaparız. Burada bind() çağrısına 0 değeri veriliyor
ServerSocket serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
// Bind to an ephemeral port
serverSocket.bind(new InetSocketAddress(0));
InetSocketAddres localAddress = (InetSocketAddress) serverSocket.getLocalSocketAddress();
Örnek
Şöyle yaparız. Burada sonradan bind() yerine direkt constructor içine 0 değeri veriliyor. spawn() yeni bir thread başlatıyor. uncheckRun() ise fırlatılan exception'ları @SneakThrows gibi yapıyor
 try (ServerSocket socket = new ServerSocket(0) ) {
  int localPort = socket.getLocalPort();
  ...
}
2. Portları Deneyerek Bulma
Bir yazı burada
Örnek
Şöyle yaparız. Bu kodu Spring'in TestSocketUtils sınıfından devşirdim. Rastgele bir port bulmayı 5 kere deniyor
import static org.junit.Assert.fail;

public class TestSocketUtils {
  static final int PORT_RANGE_MIN = 1024;
  static final int PORT_RANGE_MAX = 65535;
  private static final int PORT_RANGE = PORT_RANGE_MAX - PORT_RANGE_MIN + 1;
  private static final int MAX_ATTEMPTS = 5;
  private static final Random random = new Random(System.nanoTime());
  private static final TestSocketUtils INSTANCE = new TestSocketUtils();

  public static int findAvailableTcpPort() {
    return INSTANCE.findAvailableTcpPortInternal();
  }

  int findAvailableTcpPortInternal() {
    int candidatePort;
    int attemptCounter = 0;
    do {
      if (++attemptCounter > MAX_ATTEMPTS) {
        String message = "Could not find an available TCP port";
        fail(message);
      }
      candidatePort = PORT_RANGE_MIN + random.nextInt(PORT_RANGE);
    }
    while (!isPortAvailable(candidatePort));

    return candidatePort;
  }
}
port'u kontrol eden kod şöyle. Burada createServerSocket() çağrısına backlog olarak 1 geçiliyor. Yani sadece 1 client bekleyebilir
boolean isPortAvailable(int port) {
  try {
    ServerSocket serverSocket = ServerSocketFactory.getDefault()
      .createServerSocket(port, 1, InetAddress.getByName("localhost"));
    serverSocket.close();
    return true;
  } catch (Exception ex) {
    return false;
  }
}
Örnek
Bir başka örnek burada. basePort numarasından başlayarak belirtilen sayı kadar boş port bulmaya çalışıyor. Burada hem TCP hem de UDP portlarına bakıyor. Biraz gereksiz olmuş
public static int getAvailablePort(int basePort) {
  return getAvailablePorts(basePort, 1).get(0);
}

public static List<Integer> getAvailablePorts(int basePort, int portCount) {
  List<Integer> availablePorts = new ArrayList<>();
  int port = basePort;
  for (int i = 0; i < portCount; i++) {
    while (!isPortAvailable(port)) {
      port++;
    }
    availablePorts.add(port++);
  }
  return availablePorts;
}

public static boolean isPortAvailable(int port) {
  ServerSocket ss = null;
  DatagramSocket ds = null;
  try {
    ss = new ServerSocket(port);
    ss.setReuseAddress(true);
    ds = new DatagramSocket(port);
    ds.setReuseAddress(true);
    return true;
  } catch (IOException e) {
    return false;
  } finally {
    if (ds != null) {
      ds.close();
    }
    try {
      if (ss != null) {
        ss.close();
      }
    } catch (IOException e) {
     ignore(e);
    }
  }
}


24 Mart 2023 Cuma

Bucket4J Kullanımı

Giriş
Şu satırı dahil ederiz
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.ConsumptionProbe;
import io.github.bucket4j.Refill;
Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>com.bucket4j</groupId>
  <artifactId>bucket4j-core</artifactId>
  <version>8.1.1</version>
</dependency>
Bucket Arayüzü
Açıklaması şöyle
Bucket is the Interface that defines the behavior of a rate-limiter — based on the Token Bucket algorithm. 
A bucket is created using a builder pattern.

Bucket bucket = Bucket.builder()
  .addLimit(...)
  .build();

To add a Limit to the bucket, we define a Bandwidth denoted by the following terms.

Capacity specifies how many tokens your bucket has.

Refill specifies how fast tokens can be refilled after being consumed from a bucket.

If we choose the interval refill, the bucket will wait until the whole period is elapsed before regenerating the whole token amount.

// generates 10 tokens each minute
Refill.intervally(10, Duration.ofMinutes(1));
Örnek
Elimizde şöyle bir kod olsun
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {

  @Autowired
  RateLimitInterceptor rateLimitInterceptor;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(rateLimitInterceptor);
  }
}
Şöyle yaparız
@Component
public class RateLimitInterceptor implements HandlerInterceptor {
  private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
  private long capacity = 10;
  private long tokens = 10;

  Bucket defaultBucket = Bucket.builder()
      .addLimit(Bandwidth.classic(capacity, 
                                  Refill.intervally(tokens, Duration.ofMinutes(1))))
      .build();

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler) throws Exception {
    String clientIP = getClientIP(request);
    logger.info(clientIP);

    Bucket bucketByClientIP;
    if (buckets.containsKey(clientIP)) {
      bucketByClientIP = buckets.get(clientIP);
    } else {
      bucketByClientIP = this.defaultBucket;
      buckets.put(clientIP, bucketByClientIP);
    }
    ConsumptionProbe probe = bucketByClientIP
      .tryConsumeAndReturnRemaining(1);
    if (probe.isConsumed()) {
      response.addHeader("X-Rate-Limit-Remaining",
          Long.toString(probe.getRemainingTokens()));
      return true;
    }
    response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value()); // 429
    response.addHeader("X-Rate-Limit-Retry-After-Milliseconds",
        Long.toString(TimeUnit.NANOSECONDS.toMillis(probe.getNanosToWaitForRefill())));

    return false;
  }
}
Açıklaması şöyle
The magic of this library is in the isConsumed() method. After asking the bucket to consume a token from the basket, we test whether the token was consumed. If true, the limit was not exceeded, and the API allows the client to consume the endpoint. Otherwise, the limit was exceeded, and we rejected the request, returning an HTTP error code of 429 to the client.
IP bulma kodu şöyledir
private String getClientIP(HttpServletRequest request) {
    String ip = request.getHeader("X-FORWARDED-FOR");

    if (ip == null || ip.isEmpty()) {
      ip = request.getRemoteAddr();
    }
    return ip;
  }


ClassGraph Kullanımı

Giriş
Şu satırı dahil ederiz
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
Açıklaması şöyle
The cool thing is that Classgraph is fast, as it works on the byte-code level, meaning the inspected classes are not loaded to the JVM, and it doesn't use reflection for processing.
Açıklaması şöyle
ClassGraph has the ability to "invert" the Java class and/or reflection API, or has the ability to index classes and resources. For example, the Java class and reflection API can tell you the superclass of a given class, or the interfaces implemented by a given class, or can give you the list of annotations on a class; ClassGraph can find all classes that extend a given class (all subclasses of a given class), or all classes that implement a given interface, or all classes that are annotated with a given annotation. The Java API can load the content of a resource file with a specific path in a specific ClassLoader, but ClassGraph can find and load all resources in all classloaders with paths matching a given pattern.
Açıklaması şöyle
ClassGraph is a Java library that can be used to scan the classpath and/or module path for classes, annotations, and resources. It is a very fast and lightweight library, and it can be used for a variety of tasks, such as:

- Finding all classes with a particular annotation.
- Finding all classes that extend a specific class.
- Finding all resources that match a specific pattern.
- Creating a graph of the class dependencies.

Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>io.github.classgraph</groupId>
  <artifactId>classgraph</artifactId>
  <version>4.8.157</version>
</dependency>
ClassGraph Sınıfı
enableAllInfo
enableAnnotationInfo
enableClassInfo()
ignoreClassVisibility
whitelistPackages
whitelistPaths
gibi ayarlar atandıktan sonra scan() metodu çağrılır. scan() sonucunda bir ScanResult nesnsi elde edilir


ScanResult Sınıfı
Tüm marifet bu sınıfta. Belirtilen paket, dizin ve anotasyonları arayan metodlar sunar

getClassesImplementing metodu
Bir arayüzü gerçekleştiren tüm sınıfları bulur
Örnek
Şöyle yaparız
List<String> classNames = new ClassGraph()
  .enableClassInfo()
  .scan()
  .getClassesImplementing(FooInterface.class)
  .stream()
  .map(ClassInfo::getName)
  .collect(Collectors.toList());
getAllClasses metodu
ClassInfo listesi döner
Örnek
Şöyle yaparız. Burada belirtilen paket veya dizindeki sınıflar listeleniyor.
ClassGraph classGraph = new ClassGraph()
  .whitelistPackages("com.hazelcast.jet.config")
  .whitelistPaths("com/hazelcast/jet/config")
  .ignoreClassVisibility();
try (ScanResult scanResult = classGraph.scan()) {
  scanResult.getAllClasses().stream().map(classInfo -> ...)
  ...
}
getClassesWithAnnotation metodu
Örnek
Belirtilen paketteki tüm sınıfları tarayıp, belirli bir anotasyona sahip sınıfları bulmak için şöyle yaparız
try (ScanResult result = new ClassGraph().enableClassInfo().enableAnnotationInfo()
  .whitelistPackages(...).scan()) {
    
  ClassInfoList classInfos = result
    .getClassesWithAnnotation(FooAnnotation.class.getName());
    
  assertThat(classInfos).extracting(ClassInfo::getName)
    .contains(FooWithAnnotation.class.getName());
}
getClassesWithFieldAnnotation metodu
Örnek
Belirtilen paketteki tüm sınıfları tarayıp, belirli bir anotasyona sahip üye alanları bulmak için şöyle yaparız
try (ScanResult result = new ClassGraph().enableAllInfo()
  .whitelistPackages(...).scan()) {
    
  ClassInfoList classInfos = result
    .getClassesWithFieldAnnotation(FooAnnotation.class.getName());
    
  assertThat(classInfos).extracting(ClassInfo::getName)
    .contains(FooWithAnnotation.class.getName());
}
getClassesWithMethodAnnotation metodu
Örnek
Belirtilen paketteki tüm sınıfları tarayıp, belirli bir anotasyona sahip metodları bulmak için şöyle yaparız
try (ScanResult result = new ClassGraph().enableAllInfo()
  .whitelistPackages(...).scan()) {
    
  ClassInfoList classInfos = result
    .getClassesWithMethodAnnotation(FooAnnotation.class.getName());
    
  assertThat(classInfos).extracting(ClassInfo::getName)
    .contains(FooWithAnnotation.class.getName());
}
getAllResources metodu
Örnek
Şöyle yaparız
ClassGraph classGraph = new ClassGraph()
  .whitelistPackages("com.hazelcast.jet.config")
  .whitelistPaths("com/hazelcast/jet/config")
  .ignoreClassVisibility();
try (ScanResult scanResult = classGraph.scan()) {
  ...
  //file:/hazelcast/target/test-classes/com/hazelcast/jet/config/package.properties
  Collection<URL> nonClasses = scanResult.getAllResources().nonClassFilesOnly().getURLs();
  ...
}
getResourcesWithExtension metodu
Örnek
src/test/resources/classgraph/my.config dosyası yaratalım ve içeriği my data olsun
şöyle yaparız
try (ScanResult result = new ClassGraph().whitelistPaths("classgraph").scan()) {
  ResourceList resources = result
    .getResourcesWithExtension("config");
  assertThat(resources).extracting(Resource::getPath)
    .containsOnly("classgraph/my.config");
  assertThat(resources.get(0).getContentAsString())
    .isEqualTo("my data");
}

Java Platform Module System - JPMS

Giriş
Açıklaması şöyle
The Java Platform Module System (JPMS) was introduced with Java 9. We can use JPMS to create our own custom JRE that is suitable for specific applications. For example, if an application does not use audio, image, or JavaBeans-related features, we can remove the java.desktop module entirely to free up space in our Docker image.

As previously stated, there is no separate JRE distribution from Java 11 onwards. That means that even if we just want to run a simple JVM-based application, we must install the entire JDK. This is due to the modularity introduced in Java 9. The main philosophy is that instead of providing a generic JRE that meets everyone’s needs, everyone should be able to create their own JRE. Many JDK image providers follow the same philosophy by omitting JRE distributions.
Custom JRE yaratmak için jlink komutu kullanılır

22 Mart 2023 Çarşamba

Log4j2 log4j2.xml İskelet

monitorInterval Alanı
Örnek
Şöyle yaparız
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
  <Properties>
    <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n</Property>
  </Properties>
 
  <Appenders>
    ...
  </Appenders>
 
  <Loggers>
    ...
  </Loggers>
</Configuration>
shutdownHook Alanı
Örnek
Şöyle yaparız
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30" shutdownHook="disable">
   ...
</Configuration>

SLF4J ve Log4J2 Backend

Giriş
Açıklaması şöyle. 3 tane bağımlılık lazım
log4j-slf4j-impl.jar – Log4j 2 SLF4J binding. It allows applications coded to the SLF4J API to use Log4j2 as the implementation.
log4j-api.jar – provides the adapter components required for implementers to create a logging implementation.
log4j-core.jar – core Log4j Implementation classes.
Maven
Örnek
Şöyle yaparız
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.15.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.15.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.15.0</version>
</dependency>
Örnek - eski
Şöyle yaparız
<!-- Depend on slf4j API -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.12</version>
</dependency>

<!-- Use log4j as the slf4j implementation during runtime (not test) -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.7.12</version>
   <scope>runtime</scope>
</dependency>
Gradle
Örnek
Şöyle yaparız
implementation 'org.apache.logging.log4j:log4j-slf4j-impl'
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'org.apache.logging.log4j:log4j-core'

17 Mart 2023 Cuma

Hidden Classes - Java 15 İle Geliyor

Giriş
Gizlice yüklenen sınıflar demek daha doğru olur. Çünkü byte code olunca artık saklamak mümkün değil.  Açıklaması şöyle
A hidden class is loaded into the JVM. When a class is in source code or byte code format, it cannot be "hidden." 
Bu sınıfları ismen bulmak mümkün olmadığı için ismi Hidden Class. Açıklaması şöyle
A class gets hidden when it is loaded in a particular way so that it remains secret in front of other code parts. Remaining hidden does not mean that other codes cannot use this class. They can so long as long they "know" about the secret. The big difference is that this class is not "advertised" because you cannot find it using the name.
Bazı özellikleri şöyle
  • Non-discoverable – a hidden class is not discoverable by the JVM during bytecode linkage, nor by programs making explicit use of class loaders. The reflective methods Class::forName, ClassLoader::findLoadedClass, and Lookup::findClass will not find them.
  • We can't use the hidden class as a superclass, field type, return type, or parameter type.
  • Code in the hidden class can use it directly, without relying on the class object.
  • final fields declared in hidden classes are not modifiable regardless of their accessible flags.
  • It extends the access control nest with non-discoverable classes.
  • It may be unloaded even though its notional defining class loader is still reachable.
  • Stack traces don't show the methods or names of hidden classes by default, however, tweaking JVM options can show them.
Yani
1. Hidden Class'ın canonical ismi yoktur. Açıklaması şöyle
When you call getName() or getSimpleName() on a variable referencing a hidden class, you will get some string. These are names for messages for humans and are irrelevant for the other classes. When a class refers to another class it needs the canonical name. getCanonicalName() returns null. The canonical name is the actual name of the class, which is non-existent in the case of hidden classes.
2. Cass Loader'dan bu sınıfa bir referans yoktur, çünkü sınıfın canonical ismi yok. Dolayısıyla hemen GC işlemine uğrayabilir. Açıklaması şöyle
Since the class cannot be found through the class loader without the canonical name, there is no reason for the loader to keep a reference to the class. Why would it keep a reference when it cannot give the class to anyone? Keeping a reference would have only one side effect: preventing the GC from unloading the class so long as the class loader is alive.

Since there is no reference from the class loader, the GC can unload the class object as soon as it is out of use.
2. JDK'nin bir parçasıdır. Açıklaması şöyle
It is not part of the language but part of the JDK. There is no language element to create hidden classes, but JDK methods and classes come to the rescue.
Örnek
Şöyle yaparız
// Create a Lookup object
// The Lookup::defineHiddenClass method creates the hidden class. 
// This method accepts an array of bytes.
MethodHandles.Lookup lookup = MethodHandles.lookup();

// Load class it into the input stream
Class<?> clazz = HiddenClass.class;
String className = clazz.getName();
String classAsPath = className.replace('.', '/') + ".class";
InputStream stream = clazz.getClassLoader()
    .getResourceAsStream(classAsPath);
byte[] bytes = IOUtils.toByteArray();

// Pass these constructed bytes into Lookup::defineHiddenClass:
Class<?> hiddenClass = lookup.defineHiddenClass(IOUtils.toByteArray(stream),
  true, ClassOption.NESTMATE).lookupClass();
Bu aslında iyi bir örnek değil. Burada Hidden.class isimli bir sınıf Lookup ile yükleniyor. Aslında bu sınıf normal ClassLoader ile de yüklenebilirdi. Açıklaması şöyle
Articles and tutorials showing how to load hidden classes use precompiled Java classes. These are usually part of the running application. The tutorial calculates the path to the .class file and reads the byte code.

Technically this is correct but does not demonstrate the basic need for hidden class loading: load dynamically created classes hidden. These classes are not dynamically created and could be loaded the usual way.




16 Mart 2023 Perşembe

Escape Analysis Optimization

Giriş
Escape Analysis Optimization nesneyi mümkünse heap'te yaratmamayı amaçlıyor. Amaç GC'nin mümkün olduğunca az çalışması. Açıklaması şöyle
In general, allocating objects, executing the new operator, is a very expensive thing. Not because you are allocating memory, allocators are often fast. But because you will burden the garbage collector. Then it will have to come and clean up that memory. In this way, you significantly increase its workload, so any virtual machine tries to avoid it. How can you do this?

The compiler has a wonderful Escape Analysis that will help you understand if your object is leaking, whether it is needed by someone outside the local method currently executing or not.
1. Scalar Replacement Optimization
Metodun dışına taşmayan nesnelerin alanlarını stack'e taşır.

Örnek
Şöyle yaparız
class Test {
  int a, b;
}

public void foo() {
  Test obj = new Test();
  obj.a = 42;
  obj.b = 10;

  System.out.println(obj.a + obj.b);
}
Açıklaması şöyle
Why allocate anything on the heap here? It will die right away, and the garbage collector will have to collect it. ...
Instead, the famous Scalar Replacement optimization will work, which will replace the use of this object with the use of its fields.
2. Stack Allocation Optimization
Burada nesne alanlarına bölünüp stack üzerinde yaratılamıyor çünkü o zaman bar() metoduna daha fazla parametre geçmek gerekiyor. Onun yerine nesne stack'te yaratılıyor

Örnek
Şöyle yaparız
class Test {
  int a, b;
}

public void bar(Test arg){
  arg.b = 10;
  System.out.println(arg.a + arg.b);
}

public void foo() {
  Test obj = new Test();
  obj.a = 42;
  bar(obj); 
}
Açıklaması şöyle
If we notice that our object is actually used locally, doesn’t leak anywhere, except for passing the call to some function and passing it there as an argument, where it is also good and doesn’t leak, then we can replace the allocation of such an object in the heap with an allocation on the stack.
Partial Escape Analysis
Nesne bir koşula bağlı olarak metoddan dışarıya sızabilir. Önce örneğin Scalar Replacement Optimization ile başlıyor. Eğer koşul gerçekleşirse nesne heap'te yaratılıyor.

Örnek
Şöyle yaparız. Burada nesne shouldEscape parametresine bağlı olarak dışarıya sızabilir. 
class Test {
  int a, b;
}

static Test t;

public void foo(boolean shouldEscape){
  Test obj = new Test();
  obj.a = 42;
  obj.b = 10;

  System.out.println(obj.a + obj.b);

  if (shouldEscape) {
    t = obj;
  }
}

keytool komutu İle TrustStore'a Keystore İthal Etme

Giriş

Örnek
Şöyle yaparız
# Generate a new RSA key pair with an alias mykey and 
# store it in a new keystore file mykeystore.jks.
keytool -genkeypair -alias mykey -keyalg RSA -keysize 2048 -keystore mykeystore.jks

# import the certificate of the key pair that you created in step 1 
# into a new trust store file mytruststore.jks.
keytool -import -alias mykey -file mycertificate.crt -keystore mytruststore.jks

15 Mart 2023 Çarşamba

java.time API Çevrimler

1. Kaynak Calendar İse
Örnek
Şöyle yaparız.
Calendar cal = Calendar.getInstance();
Instant instance = cal.toInstant();
Örnek
Şöyle yaparız.
Calendar cal = Calendar.getInstance();
LocalDateTime ldt = LocalDateTime.ofInstant (cal.toInstant(), 
                                            ZoneId.systemDefault());
2. Kaynak Epoch Milisaniye İse
Örnek
Şöyle yaparız
Date date = ...;
long timestamp = date.getTime();

Instance instance = Instant.ofEpochMilli(timestamp);
Örnek
Şöyle yaparız.
int seconds = ...;
int nanoSeconds = ...;
LocalDateTime ldt = LocalDateTime.ofEpochSecond(seconds, nanoSeconds, ZoneOffset.UTC);
Örnek
Şöyle yaparız. ofEpochSecond() daha iyi bir yöntem
Date date = ...;
long timestamp = date.getTime();

LocalDateTime ldt = LocalDateTime.ofInstant (Instant.ofEpochMilli(timestamp),
            ZoneId.systemDefault());
Örnek
Şöyle yaparız. Burada elimizde milisaniye ve nanosaniye değişkenleri var. Bunları kullanarak bir Instant yaratıyoruz. Daha sonra Instant nesnesinden LocalDateTime elde ediyoruz.
long epochMillis = ...;
long nanos = ...;

LocalDateTime actual = LocalDateTime.ofInstant(
Instant.ofEpochMilli(epochMillis).plusNanos(nanos), TimeZone.getDefault().toZoneId());
Örnek
Şöyle yaparız. Milisaniye değerini kullanarak bir Instant yaratıyoruz. Daha sonra Instant nesnesinden OffsetDateTime elde ediyoruz.
OffsetDateTime.ofInstant(Instant.ofEpochMilli(epochMillis), ZoneId.systemDefault());
3. Kaynak Instant İse
Örnek
Şöyle yaparız
Instant instant = ...
LocalDateTime ldt = LocalDateTime.from(instant);

Örnek
Şöyle yaparız
Instant instant = ...;
// If you want to convert it to OffsetDateTime
OffsetDateTime odt = instant.atOffset(ZoneOffset.UTC);

4. Kaynak LocalDate İse
Şöyle yaparız
Instant instant = LocalDate.of(2012, 9, 5).atStartOfDay(ZoneOffset.UTC).toInstant();
5. Kaynak LocalDateTime İse

Örnek
Şöyle yaparız
LocalDateTime ldt = ...;
long timestamp = ldt.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
6. Kaynak ZonedDateTime İse
Örnek
Şöyle yaparız
ZonedDateTime zdt = ...;
LocalDateTime dateTimeOfLoss = zdt.toLocalDateTime();
Örnek
Şöyle yaparız
ZonedDateTime zdt = ...;
long timestamp = zdt.withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli();
Örnek
ZonedDateTime başka zone'a çevrilebiliyor. Şöyle yaparız
ZonedDateTime zdt = ZonedDateTime.now();
ZonedDateTime utcZonedDateTime = zdt.withZoneSameInstant(ZoneOffset.UTC);
Eğer bu iki nesneyi yazdırırsam çıktı olarak şunu alırım
2021-05-26T10:44:45.655+03:00[Asia/Istanbul]
2021-05-26T07:44:45.655Z