Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is premain() and how does it get called?

Tags:

java

methods

I have never heard of a premain and I feel a little stupid to ask but the answer of this post suggests to run it in order to get the Instrumentation object.

But how does that function get called or how do I make it getting called?

package playground; import java.lang.instrument.Instrumentation;  public class ObjectSizeFetcher {     private static Instrumentation instrumentation;      public static void premain(String args, Instrumentation inst) {         instrumentation = inst;     }      public static long getObjectSize(Object o) {         return instrumentation.getObjectSize(o);     } } 
like image 310
Stefan Falk Avatar asked Jan 08 '15 23:01

Stefan Falk


People also ask

What is Premain class manifest attribute?

Manifest Attributes. The following manifest attributes are defined for an agent JAR file: Premain-Class. When an agent is specified at JVM launch time this attribute specifies the agent class.

How does a Java agent work?

In general, a java agent is just a specially crafted jar file. It utilizes the Instrumentation API that the JVM provides to alter existing byte-code that is loaded in a JVM. For an agent to work, we need to define two methods: premain – will statically load the agent using -javaagent parameter at JVM startup.

What is Java Instrumentation API?

This class provides services needed to instrument Java programming language code. Instrumentation is the addition of byte-codes to methods for the purpose of gathering data to be utilized by tools. Since the changes are purely additive, these tools do not modify application state or behavior.

How do I create a Javaagent?

To create a successful javaagent we'll need four things: an agent class, some meta-information to tell the JVM what capabilities to give to our agent class, a way to make the JVM load the . jar with the agent before it starts minding the application's business and a coffee.


2 Answers

The premain is a mechanism associated with the java.lang.instrument package, used for loading "Agents" which make byte-code changes in Java programs.

The mechanism is explained in the java.lang.instrument documentation.

The gist of it is that the "agent" is deployed in a jar, and that jar has a special entry in its manifest, that tells the instrumentation package where to look for the premain method. The source you quoted is supposed to be a simple agent.

like image 191
RealSkeptic Avatar answered Sep 23 '22 22:09

RealSkeptic


Minimal runnable example

GitHub upstream: https://github.com/cirosantilli/java-cheat/tree/d73d2786cad458973a6b46bc98b9faabae65f3e1/instrument

META-INF/MANIFEST.MF

Premain-Class: Sizeof 

Sizeof.java

import java.lang.instrument.Instrumentation;  final public class Sizeof {     private static Instrumentation instrumentation;      public static void premain(String args, Instrumentation inst) {         instrumentation = inst;     }      public static long sizeof(Object o) {         return instrumentation.getObjectSize(o);     } } 

Main.java

final public class Main {     public static void main(String [] args) {         System.out.println("Object");         System.out.println(Sizeof.sizeof(new Object()));          System.out.println("/\"\"");         System.out.println(Sizeof.sizeof(""));          System.out.println("/\"abc\"");         System.out.println(Sizeof.sizeof("abc"));          System.out.println("int[0]");         System.out.println(Sizeof.sizeof(new int[0]));          System.out.println("int[10]");         System.out.println(Sizeof.sizeof(new int[10]));          class OneInt {             public int i;         }         System.out.println("OneInt");         System.out.println(Sizeof.sizeof(new OneInt()));          class TwoInts {             public int i;             public int j;         }         System.out.println("TwoInts");         System.out.println(Sizeof.sizeof(new TwoInts()));          class IntArray0 {             int[] i = new int[0];         }         System.out.println("IntArray0");         System.out.println(Sizeof.sizeof(new IntArray0()));          class IntArray10 {             int[] i = new int[10];         }         System.out.println("IntArray10");         System.out.println(Sizeof.sizeof(new IntArray10()));     } } 

Makefile

all:     javac *.java     jar -cfm Sizeof.jar META-INF/MANIFEST.MF Sizeof.class     java -ea -javaagent:Sizeof.jar Main 

Sample output:

Object 16 /"" 24 /"abc" 24 int[0] 16 int[10] 56 OneInt 16 TwoInts 24 IntArray0 16 IntArray10 16 

Tested in Ubuntu 16.10, Java HotSpot 1.8.0_92.