Merge pull request #8125 from eugenp/revert-8119-BAEL-3275-2

Revert "BAEL-3275: Using blocking queue for pub-sub"
This commit is contained in:
Eric Martin
2019-10-31 20:43:47 -05:00
committed by GitHub
parent db85c8f275
commit 3225470df5
20543 changed files with 1642750 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
## Core Java JVM Cookbooks and Examples
This module contains articles about working with the Java Virtual Machine (JVM).
### Relevant Articles:
- [Method Inlining in the JVM](https://www.baeldung.com/jvm-method-inlining)
- [JVM Log Forging](https://www.baeldung.com/jvm-log-forging)
- [Guide to Java Instrumentation](https://www.baeldung.com/java-instrumentation)
- [Class Loaders in Java](https://www.baeldung.com/java-classloaders)
- [A Guide to System.exit()](https://www.baeldung.com/java-system-exit)
- [Guide to System.gc()](https://www.baeldung.com/java-system-gc)
+61
View File
@@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-jvm</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>core-java-jvm</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>${javaassist.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
<version>${esapi.version}</version>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${sun.tools.version}</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
<properties>
<assertj.version>3.6.1</assertj.version>
<!-- instrumentation -->
<javaassist.version>3.21.0-GA</javaassist.version>
<esapi.version>2.1.0.1</esapi.version>
<sun.tools.version>1.8.0</sun.tools.version>
</properties>
</project>
@@ -0,0 +1,32 @@
package com.baeldung.classloader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class CustomClassLoader extends ClassLoader {
@Override
public Class findClass(String name) throws ClassNotFoundException {
byte[] b = loadClassFromFile(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassFromFile(String fileName) {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(
fileName.replace('.', File.separatorChar) + ".class");
byte[] buffer;
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
int nextValue = 0;
try {
while ( (nextValue = inputStream.read()) != -1 ) {
byteStream.write(nextValue);
}
} catch (IOException e) {
e.printStackTrace();
}
buffer = byteStream.toByteArray();
return buffer;
}
}
@@ -0,0 +1,22 @@
package com.baeldung.classloader;
import com.sun.javafx.util.Logging;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
public class PrintClassLoader {
public void printClassLoaders() throws ClassNotFoundException {
System.out.println("Classloader of this class:" + PrintClassLoader.class.getClassLoader());
System.out.println("Classloader of Logging:" + Logging.class.getClassLoader());
System.out.println("Classloader of ArrayList:" + ArrayList.class.getClassLoader());
}
}
@@ -0,0 +1,19 @@
package com.baeldung.inlining;
public class ConsecutiveNumbersSum {
private long totalSum;
private int totalNumbers;
public ConsecutiveNumbersSum(int totalNumbers) {
this.totalNumbers = totalNumbers;
}
public long getTotalSum() {
totalSum = 0;
for (int i = 1; i <= totalNumbers; i++) {
totalSum += i;
}
return totalSum;
}
}
@@ -0,0 +1,16 @@
package com.baeldung.inlining;
public class InliningExample {
public static final int NUMBERS_OF_ITERATIONS = 15000;
public static void main(String[] args) {
for (int i = 1; i < NUMBERS_OF_ITERATIONS; i++) {
calculateSum(i);
}
}
private static long calculateSum(int n) {
return new ConsecutiveNumbersSum(n).getTotalSum();
}
}
@@ -0,0 +1,70 @@
package com.baeldung.instrumentation.agent;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class AtmTransformer implements ClassFileTransformer {
private static Logger LOGGER = LoggerFactory.getLogger(AtmTransformer.class);
private static final String WITHDRAW_MONEY_METHOD = "withdrawMoney";
/** The internal form class name of the class to transform */
private String targetClassName;
/** The class loader of the class we want to transform */
private ClassLoader targetClassLoader;
public AtmTransformer(String targetClassName, ClassLoader targetClassLoader) {
this.targetClassName = targetClassName;
this.targetClassLoader = targetClassLoader;
}
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
byte[] byteCode = classfileBuffer;
String finalTargetClassName = this.targetClassName.replaceAll("\\.", "/"); //replace . with /
if (!className.equals(finalTargetClassName)) {
return byteCode;
}
if (className.equals(finalTargetClassName) && loader.equals(targetClassLoader)) {
LOGGER.info("[Agent] Transforming class MyAtm");
try {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get(targetClassName);
CtMethod m = cc.getDeclaredMethod(WITHDRAW_MONEY_METHOD);
m.addLocalVariable("startTime", CtClass.longType);
m.insertBefore("startTime = System.currentTimeMillis();");
StringBuilder endBlock = new StringBuilder();
m.addLocalVariable("endTime", CtClass.longType);
m.addLocalVariable("opTime", CtClass.longType);
endBlock.append("endTime = System.currentTimeMillis();");
endBlock.append("opTime = (endTime-startTime)/1000;");
endBlock.append("LOGGER.info(\"[Application] Withdrawal operation completed in:\" + opTime + \" seconds!\");");
m.insertAfter(endBlock.toString());
byteCode = cc.toBytecode();
cc.detach();
} catch (NotFoundException | CannotCompileException | IOException e) {
LOGGER.error("Exception", e);
}
}
return byteCode;
}
}
@@ -0,0 +1,59 @@
package com.baeldung.instrumentation.agent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.instrument.Instrumentation;
public class MyInstrumentationAgent {
private static Logger LOGGER = LoggerFactory.getLogger(MyInstrumentationAgent.class);
public static void premain(String agentArgs, Instrumentation inst) {
LOGGER.info("[Agent] In premain method");
String className = "com.baeldung.instrumentation.application.MyAtm";
transformClass(className,inst);
}
public static void agentmain(String agentArgs, Instrumentation inst) {
LOGGER.info("[Agent] In agentmain method");
String className = "com.baeldung.instrumentation.application.MyAtm";
transformClass(className,inst);
}
private static void transformClass(String className, Instrumentation instrumentation) {
Class<?> targetCls = null;
ClassLoader targetClassLoader = null;
// see if we can get the class using forName
try {
targetCls = Class.forName(className);
targetClassLoader = targetCls.getClassLoader();
transform(targetCls, targetClassLoader, instrumentation);
return;
} catch (Exception ex) {
LOGGER.error("Class [{}] not found with Class.forName");
}
// otherwise iterate all loaded classes and find what we want
for(Class<?> clazz: instrumentation.getAllLoadedClasses()) {
if(clazz.getName().equals(className)) {
targetCls = clazz;
targetClassLoader = targetCls.getClassLoader();
transform(targetCls, targetClassLoader, instrumentation);
return;
}
}
throw new RuntimeException("Failed to find class [" + className + "]");
}
private static void transform(Class<?> clazz, ClassLoader classLoader, Instrumentation instrumentation) {
AtmTransformer dt = new AtmTransformer(clazz.getName(), classLoader);
instrumentation.addTransformer(dt, true);
try {
instrumentation.retransformClasses(clazz);
} catch (Exception ex) {
throw new RuntimeException("Transform failed for class: [" + clazz.getName() + "]", ex);
}
}
}
@@ -0,0 +1,46 @@
package com.baeldung.instrumentation.application;
import com.sun.tools.attach.VirtualMachine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Optional;
/**
* Created by adi on 6/10/18.
*/
public class AgentLoader {
private static Logger LOGGER = LoggerFactory.getLogger(AgentLoader.class);
public static void run(String[] args) {
String agentFilePath = "/home/adi/Desktop/agent-1.0.0-jar-with-dependencies.jar";
String applicationName = "MyAtmApplication";
//iterate all jvms and get the first one that matches our application name
Optional<String> jvmProcessOpt = Optional.ofNullable(VirtualMachine.list()
.stream()
.filter(jvm -> {
LOGGER.info("jvm:{}", jvm.displayName());
return jvm.displayName().contains(applicationName);
})
.findFirst().get().id());
if(!jvmProcessOpt.isPresent()) {
LOGGER.error("Target Application not found");
return;
}
File agentFile = new File(agentFilePath);
try {
String jvmPid = jvmProcessOpt.get();
LOGGER.info("Attaching to target JVM with PID: " + jvmPid);
VirtualMachine jvm = VirtualMachine.attach(jvmPid);
jvm.loadAgent(agentFile.getAbsolutePath());
jvm.detach();
LOGGER.info("Attached to target JVM and loaded Java agent successfully");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,14 @@
package com.baeldung.instrumentation.application;
/**
* Created by adi on 6/14/18.
*/
public class Launcher {
public static void main(String[] args) throws Exception {
if(args[0].equals("StartMyAtmApplication")) {
new MyAtmApplication().run(args);
} else if(args[0].equals("LoadAgent")) {
new AgentLoader().run(args);
}
}
}
@@ -0,0 +1,19 @@
package com.baeldung.instrumentation.application;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by adi on 6/11/18.
*/
public class MyAtm {
private static Logger LOGGER = LoggerFactory.getLogger(MyAtm.class);
private static final int account = 10;
public static void withdrawMoney(int amount) throws InterruptedException {
Thread.sleep(2000l); //processing going on here
LOGGER.info("[Application] Successful Withdrawal of [{}] units!", amount);
}
}
@@ -0,0 +1,19 @@
package com.baeldung.instrumentation.application;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyAtmApplication {
private static Logger LOGGER = LoggerFactory.getLogger(MyAtmApplication.class);
public static void run(String[] args) throws Exception {
LOGGER.info("[Application] Starting ATM application");
MyAtm.withdrawMoney(Integer.parseInt(args[2]));
Thread.sleep(Long.valueOf(args[1]));
MyAtm.withdrawMoney(Integer.parseInt(args[3]));
}
}
@@ -0,0 +1,28 @@
package com.baeldung.logforging;
import org.owasp.esapi.ESAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogForgingDemo {
private final Logger logger = LoggerFactory.getLogger(LogForgingDemo.class);
public void addLog(String amount) {
logger.info("Amount credited = {}", amount);
}
public static void main(String[] args) {
LogForgingDemo demo = new LogForgingDemo();
demo.addLog("300");
demo.addLog("300 \n\nweb - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully");
demo.addLog(encode("300 \n\nweb - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully"));
}
public static String encode(String message) {
message = message.replace('\n', '_').replace('\r', '_').replace('\t', '_');
message = ESAPI.encoder().encodeForHTML(message);
return message;
}
}
@@ -0,0 +1,33 @@
package com.baeldung.systemgc;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import static java.util.UUID.randomUUID;
public class DemoApplication {
private static final Map<String, String> cache = new HashMap<String, String>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
final String next = scanner.next();
if ("fill".equals(next)) {
for (int i = 0; i < 1000000; i++) {
cache.put(randomUUID().toString(), randomUUID().toString());
}
} else if ("invalidate".equals(next)) {
cache.clear();
} else if ("gc".equals(next)) {
System.gc();
} else if ("exit".equals(next)) {
System.exit(0);
} else {
System.out.println("unknown");
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,23 @@
package com.baeldung.classloader;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class CustomClassLoaderUnitTest {
@Test
public void customLoader() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
CustomClassLoader customClassLoader = new CustomClassLoader();
Class<?> c = customClassLoader.findClass(PrintClassLoader.class.getName());
Object ob = c.newInstance();
Method md = c.getMethod("printClassLoaders");
md.invoke(ob);
}
}
@@ -0,0 +1,14 @@
package com.baeldung.classloader;
import org.junit.Test;
import static org.junit.Assert.*;
public class PrintClassLoaderUnitTest {
@Test(expected = ClassNotFoundException.class)
public void givenAppClassLoader_whenParentClassLoader_thenClassNotFoundException() throws Exception {
PrintClassLoader sampleClassLoader = (PrintClassLoader) Class.forName(PrintClassLoader.class.getName()).newInstance();
sampleClassLoader.printClassLoaders();
Class.forName(PrintClassLoader.class.getName(), true, PrintClassLoader.class.getClassLoader().getParent());
}
}
@@ -0,0 +1,22 @@
package com.baeldung.inlining;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class ConsecutiveNumbersSumUnitTest {
private static final int TOTAL_NUMBERS = 10;
@Test
public void givenTotalIntegersNumber_whenSumCalculated_thenEquals() {
ConsecutiveNumbersSum consecutiveNumbersSum = new ConsecutiveNumbersSum(TOTAL_NUMBERS);
long expectedSum = calculateExpectedSum(TOTAL_NUMBERS);
assertEquals(expectedSum, consecutiveNumbersSum.getTotalSum());
}
private long calculateExpectedSum(int totalNumbers) {
return totalNumbers * (totalNumbers + 1) / 2;
}
}