import java.lang.reflect.Method;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Загрузчик классов из массива байт
*/
class DynamicClassLoader extends ClassLoader {
public Class<?> defineClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}
public class AsmDemo {
private static final String BASE_NAME = "DynamicHello";
private static final DynamicClassLoader loader = new DynamicClassLoader();
/**
* Метод генерирующий байткод
*/
private static byte[] generateBytecode(String className) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
// Объявление генерируемого класса
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object",
new String[] {});
// Конструктор генерируемого класса
MethodVisitor con = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
con.visitCode();
con.visitVarInsn(Opcodes.ALOAD, 0);
con.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
con.visitInsn(Opcodes.RETURN);
con.visitMaxs(1, 1);
// Метод генерируемого класса
// выводящий его имя
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "introduceYourself", "()V",
null, null);
mv.visitCode();
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
mv.visitInsn(Opcodes.DUP);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V",
false);
mv.visitLdcInsn("I am ");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass",
"()Ljava/lang/Class;", false);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getName",
"()Ljava/lang/String;", false);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
"()Ljava/lang/String;", false);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
"(Ljava/lang/String;)V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 1);
cw.visitEnd();
return cw.toByteArray();
}
/**
* Метод запускающий сгенерированные классы с помощью рефлексии
*/
public static void loadAndRun(String className, byte[] bytes) throws ReflectiveOperationException {
Class<?> cls = loader.defineClass(className, bytes);
Method method = cls.getDeclaredMethod("introduceYourself");
method.invoke(cls.newInstance());
}
public static void main(String[] args) throws Exception {
// Генерируем байткод десятка классов
// и запускаем
for (int x = 0; x < 10; x++) {
String className = BASE_NAME + x;
byte[] bc = generateBytecode(className);
loadAndRun(className, bc);
}
}
}
<persistence>
<persistence-unit name="MyPU">
<properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/somedb" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="password" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL96Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
public class ReOrdering implements Runnable { int one, two, three, four, five, six; volatile int volaTile; @Override public void run() { one = 1; two = 2; three = 3; volaTile = 92; int x = four; int y = five; int z = six; } }
The assignments of one, two and three may be reordered, as long as they all happen before the volatile write. Similarly, the x, y, and z statements may be reordered as the volatile write happens before all of them. The volatile operation is often called a memory barrier. The happens before guarantee ensures that read and write instructions of volatile variables cannot be reordered across a memory barrier.
The happens before guarantee has another effect: When a thread writes to a volatile variable, then all other variables - including non-volatiles - changed by the thread before writing to the volatile variable are also flushed to main memory. When a thread reads a volatile variable it also reads all other variables - including non-volatile - that were flushed to main memory together with the volatile variable.
pip <имя файла>