JPoint 2020
Interesting outtakes
Microservices made easy with MicroProfile OpenJ9 Open Liberty and OpenShift
Presented by Jamie Coleman.
MicroProfile - OS-commnity specification for Enterprise Java microservices; A community of individuals, organizations and vendors, collaborating within an open souce platform.
MicroProfile vendors/implementations: OpenLiberty, MicroPayara, Thorntail, Apache TomEE, Hammock, kumuluzEE.
MicroProfile 3.3 stack: Open Tracing, Health Check, Metrics, Open API, Fault Tolerante, JWT Propagation, Config, JAX-RS, CDI, JSON-P, JSON-B, Rest Client.
JAX-RS: @Path
, CDI: @Inject
, JSON-B / -P: @Consumer(MediaType.APPLICATION_JSON)
, Open API - based on Swagger, JWT: @RolesAllowed({...})
, Fault Tolerance: @Retry
, Health: @Health
, implements HealthCheck
, Metrics: @Counted
, Open Tracing: @Traced
.
Containers & Cubernetes -> Config (@ConfigProperty(name=...)
)
Testcontainers: integration tests that are easy to setup, write and run - same way service is run in production.
Markdown Renderer?
Demo 1:
@MicroShedTest public class X {
@Container
public static ApplicationContainer app = new ApplicationContainer().withAppContextRoot("/").withReadinessPath("/health/ready");
@RESTClient public static PersonService personService;
@Test
public void test() {
assertNotNull(personService.createPerson("A", 1));
}
}
OpenLiberty - application server, focus on code, easy to make fast and iterative changes, easy to write tests, true-to-production testing (as much as possible), ready for containers, not-in-your-way tools and flexibility.
Jakarta EE - Jakarta EE is emerging as the second place cloud native framework, with Spring loosing its positions.
Open Libertty suits best on a range [Macroservice … Microservice]. Not monolyth, not functions.
OpenLiberty starts faster than onther services, J9 starts faster than Hotspot.
CRIU - hibernate your JVM application when not in use.
Life beyond Java 8
Most of companies still use Java 8.
Starting from Java 9 onwards a new version of Java each March and September. LTS - Java 8, 11, 17 - Oracle version.
Use free OpenJDK - but upgrade every 6 month, use Oracle LTS - but pay for production JVMs. Good alternative - AdoptOpenJDK.
- Java 11:
- introduced JShell - ability to try out Java from the command line (don’t even need to write semicolon at the end);
- var keyword - be careful, not to overuse it, don’t erase type information;
- Convenience factory methods for Collections;
- Collecting to Unmodifiable Collections;
- New methods on Stream API
- Mew methods on Optional - isEmpty(), ifPresentOrElse()
- Built in Http Client
- Multi release Jar File
- Jigsaw - java module system
- JLink - bundle just stuff from Java that we use
- Java 14:
- Skipped for now, not relevant.
From cozy Java to brutal Native code or There and Back Again
Presented by Ivan Ugliansky
static native void goNative();
Java -> goNative() -> C/C++
Java -> goThere(Callback) -> C/C++ -> callback() -> Java
Reasons: native libraries, like OpenGL, DirectX, Tensorflow, Cuda. WinAPI. Questionable reason: performance boost.
Going Native:
- Where JVM gets natives?
- How to work with Java from native?
- How GC should perform?
JNI - Java Native Interface - unified interface for all native interfaces.
public class JavaToNative {
static native void goThere(Callback andBackAgain);
}
javac JavaToNative.java -h .
=> JavaToNative.h
=> JNIEXPORT void JNICALL Java_JavaToNative_goThere(JNIEnv *, jclass, jobject);
JNIEnv - pointer towards JNINativeInterface(214 functions). Useful include: NewObject, GetObjectClass, CallObjectMethod, CallStaticObjectMethod, GetObjectField, SetObjectField, CallMethod, CallStaticMethod, GetField, Throw, ThrowNew.
method() {
printf("Ok\n");
jclass cls = (*env)->GetObjectClass(env, andBackAgain);
jmethodId method = (*env) -> GetMethodID(env, cls, "call", "()V");
}
nokee plugins - used with Gradle, cross-platform building?
-Xcheck=jni => more verbosity with failures + warnings.
Garbage collector: no safe-points, native code keeps working. jobject is safe for GC time, won’t be cleaaned up, will work even if GC moves file.
DeleteLocalRef - to delete object, be careful with references.
Local reference - lives no longer than native method call. Global Reference - live until freed. Weak Global Reference - live until freed, but GC can collect Java object.
Perforamce Java => Java vs Java => Native method call, calling native is ~3 times (Java 8 or 6 times Java 11) slower. Java => Native => Java is ~10 times slower.
State transition is slow due to:
- GC sync before call
- Wrapping params to Local References
- Results handling + exception check
- Params pushing
- For compiler - no inlining
- Outtakes:
- javac -h for .h files
- nokee.dev for building
- -Xcheck:jni
- Careful with JNI references + JNI GetXCritical
- State transition is sloooow!
From comments: IPC is also a good alternative to JNI
Libraries: JNA, JNR, JavaCPP, …
JNA - normal C, in Java extends Library
, INSTANCE = Native.load("name", ClassName.class)
.
JNA supports return by value, pointers, c-like arrays, c-like strings, pointers towards functions, struct & union, varargs.
JNA is even slower: x8.5 slower than JNI! It trashes memory with wrapper objects - even worse for GC.
JNR: a bit faster than JNA, still slower than JNI.
JavaCPP - works with C++, won’t learn C++, so don’t care.
Project Panama looks promising, already faster than JNI.
GraalVM - completely different approach - Java & Native code under the same roof. Still not as performant as it could be (can’t inline Java / native methods), but is faster than JNI - for calling empty methods. In some cases Sulong can be even slower than JNI, but it’s a work in progress. Sulong also needs a long warmup.
Conclusion: try to avoid native code, learn your framework, native <=> managed transitions are still open question.
Андрей Паньгин — Safepoint — и пусть весь мир подождёт
GC stops threads in “safepoints”, where it is known that GC won’t break anything. Where is it? In JVM - on each instruction bytecode, in compiled code - on each method call, at the end of a cycle, upon calling VM runtime.
JNI handles: jobject -> refX -> HEAP. JNI functions in_native -> safepoint? -> in_vm.
Тагир Валеев — Ещё немного маленьких оптимизаций
Java TreeMap is made using red-black trees.
Overall interesting presentation, Tagis is always very enthusiastic and lively.
Bootiful Kotlin
Presented by Josh Long
“We should not use someting old like Java 8, right guys, right, right?”
Spring framework 5 supports Kotlin.