i am struggling since days on a simple project that i just can't get to run.
My goal is to extend the functionality of a .jar-File in order to get more information about the inner workings of that jar. The .jar is not open source.
I came accross a lot of different concepts to "inject" my own code into the jvm like the "ASM"-Library, BECL, Javassist and finally AspectJ.
AspectJ caught my attention as it seems to be easier to use and more high level. To try how AspectJ is working before using it with the closed source .jar, i set up Test-Projects:
Project1:
To test it, i wanted to create a simply project containing one Class that should be compiled and packed to a .jar-File. This class should later be monitored using the Aspect. I took the Source Code of this Class from an example on the internet: https://github.com/Nosfert/AspectJ-Tutorial-jayway
The file content of the class looks like this:
YourClass.java:
package com.test.java.instrumentation;
public class YourClass {
public static void main(String[] args) {
YourClass yourClass = new YourClass();
yourClass.yourMethodBefore();
yourClass.yourMethodAfter();
yourClass.yourMethodAround(1);
yourClass.yourMethodAround(1,"Test");
}
public void yourMethodBefore() {
System.out.println("Executing TestTarget.yourMethodBefore()");
}
public void yourMethodAfter(){
System.out.println("Executing TestTarget.yourMethodAfter()");
}
public void yourMethodAround(Integer i){
System.out.println("Executing TestTarget.yourMethodAround()");
System.out.println("i : "+i);
}
public void yourMethodAround(Integer i,String x){
System.out.println("Executing TestTarget.yourMethodAround()");
System.out.println("i : "+i);
System.out.println("x : "+x);
}
}
I compile the code with the following command:
javac -d bin -cp ./src/ ./src/com/test/java/instrumentation/YourClass.java
The command runs without errors.
In the next step i created a Manifest file containing the necessary information to run the Class in a .jar-File:
MANIFEST.MF:
Manifest-Version: 1.0
Main-Class: com.test.java.instrumentation.YourClass
Built-By: Me
Build-Jdk: 1.8.0_131
In the next step i create a .jar:
cd bin\
jar cvfm program.jar ..\meta-inf\manifest.mf .
The .jar can be successfully executed via:
java -jar program.jar
The output looks like this:
Executing TestTarget.yourMethodBefore()
Executing TestTarget.yourMethodAfter()
Executing TestTarget.yourMethodAround()
i : 1
Executing TestTarget.yourMethodAround()
i : 1
x : Test
So far so good. Step 1 is completed. This is the example-application that should later be expanded with additional functionality using AspectJ's Load Time Weaving.
Project2:
In the next step i want to create the AspectJ .jar-File containing my code to expand the functionality of Project1:
The contents of Priject2 (YourAspect.java) is the following:
package com.test.java.instrumentation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.JoinPoint;
#Aspect
public class YourAspect {
//Patterns
//blank = modifier (public/private/protected or default(blank) should be looked for
//* = return type to look for. Void/Object/Primitive type
//com.jayway.YourClass.yourMethodBefore(..) = PackageName . ClassName . methodName (parameters)
#Before("execution (* com.test.java.instrumentation.YourClass.yourMethodBefore(..))")
//JointPoint = the reference of the call to the method
public void beforeAdvice(JoinPoint joinPoint) {
System.out.println("YourAspect's BeforeAdvice's body is now executed Before yourMethodBefore is called.");
}
//Patterns
//public = look for the specific modifier named public
//!Object = Basically we are looking for void or primitives. But if we specified Object we could get a good pattern
//com.jayway.YourClass.yourMethodBefore(..) = PackageName . ClassName . methodName (parameters)
#After("execution (public !Object com.test.java.instrumentation.YourClass.yourMethodAfter(..))")
public void afterAdvice(JoinPoint joinPoint) {
System.out.println("YourAspect's afterAdvice's body is now executed After yourMethodAfter is called.");
}
//Patterns
//!private = look for any modifier that's not private
//void = looking for method with void
//com.jayway.YourClass.yourMethodBefore(..) = PackageName . ClassName . methodName (parameters)
#Around("execution (!private void com.test.java.instrumentation.YourClass.yourMethodAround(Integer,..))")
//ProceedingJointPoint = the reference of the call to the method.
//The difference between ProceedingJointPoint and JointPoint is that a JointPoint can't be continued (proceeded)
//A ProceedingJointPoint can be continued (proceeded) and is needed for an Around advice
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
//Default Object that we can use to return to the consumer
Object returnObject = null;
try {
System.out.println("YourAspect's aroundAdvice's body is now executed Before yourMethodAround is called.");
//We choose to continue the call to the method in question
returnObject = joinPoint.proceed();
//If no exception is thrown we should land here and we can modify the returnObject, if we want to.
} catch (Throwable throwable) {
//Here we can catch and modify any exceptions that are called
//We could potentially not throw the exception to the caller and instead return "null" or a default object.
throw throwable;
}
finally {
//If we want to be sure that some of our code is executed even if we get an exception
System.out.println("YourAspect's aroundAdvice's body is now executed After yourMethodAround is called.");
}
return returnObject;
}
//Patterns
//blank = modifier (public/private/protected or default(blank) should be looked for
//* = return type to look for. Void/Object/Primitive type
//com.jayway.YourClass.yourMethod*(..) = PackageName . ClassName . * (parameters)
//Where the "*" will catch any method name
#After("execution ( * com.test.java.instrumentation.YourClass.*(..))")
//JointPoint = the reference of the call to the method
public void printNewLine(JoinPoint pointcut){
//Just prints new lines after each method that's executed in
System.out.print("\n\r");
}
}
I also created a MANIFEST.FM:
Manifest-Version: 1.0
Main-Class: com.test.java.instrumentation.YourAspect
Built-By: Me
Build-Jdk: 1.8.0_131
And a aop.xml:
<aspectj>
<aspects>
<aspect name="com.test.java.instrumentation.YourAspect"/>
</aspects>
<weaver options="-XlazyTjp">
<include within="com.test.java.instrumentation..*"/>
</weaver>
</aspectj>
I can compile the class successfully with the following command:
javac -cp ./lib/aspectjrt.jar;.lib/aspejctjweaver.jar;./src;. -d ./bin/ ./src/com/test/java/instrumentation/YourAspect.java
The resulting classfile is packaged together with the Manifest and the aop.xml into a .jar:
cd bin\
jar cvfm aspect.jar ..\meta-inf\manifest.mf ..\meta-inf\aop.xml .
When i try to run the example-program (Project1) and try to weave the aspect (Project2), i am using the following command:
java -Daj.weaving.verbose=true -Dorg.aspectj.weaver.showWeaveInfo=true -javaagent:./Aspect/lib/aspectjweaver.jar -cp ./Aspect/lib/aspectjrt.jar;./Aspect/lib/aspejctjtools.jar;. -jar ./JavaProgram/bin/program.jar
The load fails and the resulting error is the following:
[AppClassLoader#18b4aac2] info AspectJ Weaver Version 1.8.10 built on Monday Dec 12, 2016 at 19:07:48 GMT
[AppClassLoader#18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader#18b4aac2
[AppClassLoader#18b4aac2] info no configuration found. Disabling weaver for class loader sun.misc.Launcher$AppClassLoader#18b4aac2
Executing TestTarget.yourMethodBefore()
Executing TestTarget.yourMethodAfter()
Executing TestTarget.yourMethodAround()
i : 1
Executing TestTarget.yourMethodAround()
i : 1
x : Test
How can i injecte my aspect (Project2) into the running program.jar (Project1)?
Do you have any ideas?
I attached all the files including Sourcecode and Manifests that i created (Both projects) as a .zip-File in the following link, so you can also try out what i did so far. This might help you to spot my errors easier. The project is designed to run on windows commandline.
Link: Downloadlink of my Projects
Thank you very much for your Ideas!
Related
I'm on windows 10 + jdk1.8
Use used maven to create a project named UseNative, package name is mygroup, files are under:
src\main\java\mygroup\
I have UseNative.java:
package mygroup;
public class UseNative {
public native void greet(String name);
static {
System.loadLibrary("UseNative");
}
#SuppressWarnings("static-access")
public static void main(String[] args) {
System.out.println(System.getProperty("java.library.path"));
new UseNative().greet("me");
}
}
Then under powershell:
javac UseNative.java
OK, and then:
javah -classpath . UseNative
or
javah -classpath . mygroup.UseNative
Both says:
Error: cannot find class file for 'mygroup.UseNative'
I tried to remove the package mygroup line from java file, and then it works! But anyhow, I need this line to comply coding standard.
Where does it get wrong, add additional parameter or environment?
Thanks!
I am trying to run the following method in Loader.java from the command line:
public static void method(String path, String word)
As seen above, I must pass in the variables path and word, and I want the command line to display the System.out.println()'s in the method.
What command can I run to do this?
Note: when I run the following commands,
javac *.java
jar -cvf Loader.jar Loader.class
java -cp ./Loader.jar Loader
I get the following error:
Caused by: java.lang.NoClassDefFoundError: path/to/Loader (wrong name: Loader)
What must I do to successfully run method from the command line?
Here is minimum reproducible version of Loader.java:
public class Loader {
public static void main(String[] args) {
method("my/path", "my_word");
}
public static void method(String path, String word) {
System.out.println("Output after doing something");
}
}
Just do the following:
javac Loader.java
java Loader
In fact, if you are you Java-11 or above, you don't even need to use the first command i.e. you can directly use the following command:
java Loader.java
However, if you want to create a jar file and execute the class from it, execute the steps given below:
mkdir demo
cd demo
Now create/place Loader.java in this folder. Then,
javac *.java
jar -cvf loader.jar .
java -cp loader.jar Loader
Note that I've used a new directory, demo to make it clear but it is not necessary. Another thing you should notice is the . at the end of jar command which specifies the current directory.
How to process command-line arguments?
String[] args parameter in main stores all the parameters from the command-line e.g. if you run the following program as java Loader my/path my_word from the command-line,
public class Loader {
public static void main(String[] args) {
if (args.length >= 2) {
method(args[0], args[1]);
} else {
System.out.println("Command line parameters are missing");
}
}
public static void method(String path, String word) {
System.out.println("Path: " + path);
System.out.println("Word: " + word);
}
}
the output will be
Path: my/path
Word: my_word
I am new to Cucumber and trying to solve simple issue:
I have created a Java Project and referred all the cucumber related jars to the build-path of this project (called it "CukeTest4") and below is the structure showing the java file and feature file. When I run this feature file as Cucumber feature in Eclipse, it runs fine.
Now, I would like to run this from another main method. I created another Java Project, Added a Class with main method with code below which is in default package.
import cucumber.api.cli.Main;
public class UseCukeFromMain {
public static void main(String[] args) throws Throwable
{
Main.main(new String[]{"-g", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke/cukefeature.feature"});
}
}
I have provided implementation for the method in the java file as it works fine from Eclipse but shows the message below to implement the method
[33mU[0m
1 Scenarios ([33m1 undefined[0m)
1 Steps ([33m1 undefined[0m)
0m0.000s
You can implement missing steps with the snippets below:
#Given("^I want to write a step with precondition$")
public void i_want_to_write_a_step_with_precondition() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
I have tried a lot of combination for -g option, but the message is same.
EDIT2
From the comments below, adding the package to glue when the other project is in classpath, works fine.
Main.main(new String[]{"-g", "com.cuke", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke/cukefeature.feature"};
But, Another issue:
I have some old projects that I need to integrate with cucumber. All the .class and .java are present in the folder(NO src or bin directory):
C:\work\RFT_WS2\Cuketest3
, I have this directory in the Classpath. I have tried following option but unable to understand the issue:
-g "" path/to/feature //(NOT WORKING)
-g "classpath:" path/to/feature //(NOT WORKING)
-g "Cuketest3" // Added "C:\work\RFT_WS2" in classpath (NOT WORKING)
Now if I add the .java file to a package say "steps" and have "C:\work\RFT_WS2\Cuketest3" in classpath, option looks like
-g "steps" path/to/feature //(WORKING)
My question is that how to get it to find the methods implementation for a default package.
Also how do add multiple glue option, for example
Not Working cases I tried
Main.main(new String[]{"-g", "com.cuke,com.cuke1", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke/cukefeature.feature"};
Main.main(new String[]{"-g", "com.cuke", "com.cuke1", "C:/work/workspaces/neon2_wks_new1/Cuketest4/src/com/cuke/cukefeature.feature"};
Thanks.
The glue option takes a path value which reflects the package(s) of the glue classes to be included in the classpath.
Find a simplified working example below
Assume following structure
/tmp/cuke-test/features/cukefeature.feature
/tmp/cuke-test/lib
/tmp/cuke-test/project1/src/com/cuke/CukeSteps.java
/tmp/cuke-test/project2/src/UseCukeFromMain.java
cukefeature.feature
Feature: simple test
Scenario: test programatic call of Cucumber
Given we have feature file
When some glue code exists
Then those steps should not fail
lib
cucumber-core-2.1.0.jar
cucumber-html-0.2.6.jar
cucumber-java-2.1.0.jar
cucumber-jvm-deps-1.0.6.jar
cucumber-testng-2.1.0.jar
gherkin-5.0.0.jar
jcommander-1.64.jar
snakeyaml-1.17.jar
tag-expressions-1.0.1.jar
testng-6.11.jar
CukeSteps.java
package com.cuke;
import cucumber.api.PendingException;
import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.en.*;
public class CukeSteps {
#Given("^we have feature file$")
public void we_have_feature_file() throws Throwable {
System.out.println("execute Given step");
}
#When("^some glue code exists$")
public void some_glue_code_exists() throws Throwable {
System.out.println("execute Then step");
}
#Then("^those steps should not fail$")
public void those_steps_should_not_fail() throws Throwable {
throw new PendingException();
}
}
UseCukeFromMain.java
import cucumber.api.cli.Main;
public class UseCukeFromMain {
public static void main(String[] args) throws Throwable {
Main.main(new String[]{
"--glue",
"com/cuke", // the package which contains the glue classes
"/tmp/cuke-test/features/cukefeature.feature"}
);
}
}
compile the classes
javac -cp "lib/*" -d project1/bin/ project1/src/com/cuke/*.java
javac -cp "lib/*" -d project2/bin/ project2/src/*.java
run the UseCukeFromMain
The root direcotry which contains the glue classes (project1/bin) must be in the classpath.
java -cp "project2/bin:project1/bin:lib/*" UseCukeFromMain
output
execute Given step
execute Then step
1 Scenarios (1 pending)
3 Steps (1 pending, 2 passed)
0m0.104s
cucumber.api.PendingException: TODO: implement me
at com.cuke.CukeSteps.those_steps_should_not_fail(CukeSteps.java:21)
at ✽.those steps should not fail(/tmp/cuke-test/features/cukefeature.feature:6)
edit Using Step definitions in default package
Assume following structure
features/cukefeature.feature
lib/
project1/src/CukeSteps.java
project2/src/UseCukeFromMain.java
cukefeature.feature
lib/
the same as in the first example
CukeSteps.java
// note: there is no package statement
import cucumber.api.PendingException;
import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.en.*;
public class CukeSteps {
#Given("^we have feature file$")
public void we_have_feature_file() throws Throwable {
System.out.println("execute Given step");
}
#When("^some glue code exists$")
public void some_glue_code_exists() throws Throwable {
System.out.println("execute Then step");
}
#Then("^those steps should not fail$")
public void those_steps_should_not_fail() throws Throwable {
throw new PendingException();
}
}
UseCukeFromMain.java
import cucumber.api.cli.Main;
public class UseCukeFromMain {
public static void main(String[] args) throws Throwable {
Main.main(new String[]{
"--glue",
"", // to used Step definitions in default package
"features/cukefeature.feature"}
);
}
}
compile classes
The option -d . creates the class files in the current directory.
javac -cp "lib/*" -d . project1/src/*.java
javac -cp "lib/*" -d project2/bin/ project2/src/*.java
created class files
CukeSteps.class
project2/bin/UseCukeFromMain.class
run the UseCukeFromMain
The current directory is added to the classpath using the ..
java -cp "project2/bin:.:lib/*" UseCukeFromMain
output
execute Given step - default package
execute Then step - default package
1 Scenarios (1 pending)
3 Steps (1 pending, 2 passed)
0m0.096s
cucumber.api.PendingException: TODO: implement me
at CukeSteps.those_steps_should_not_fail(CukeSteps.java:19)
at ✽.those steps should not fail(features/cukefeature.feature:5)
edit Using Step definitions from different packages.
Assume following structure
features/cukefeature.feature
lib
project1/src/com/cuke1/CukeStepsB.java
project1/src/com/cuke/CukeStepsA.java
project2/src/UseCukeFromMain.java
cukefeature.feature
lib/
the same as in the first example
The Step definitions are split in two classes, in different packages
CukeStepsA.java
package com.cuke;
import cucumber.api.PendingException;
import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.en.*;
public class CukeStepsA {
#Given("^we have feature file$")
public void we_have_feature_file() throws Throwable {
System.out.println("execute Given step - package com.cuke");
}
}
CukeStepsB.java
package com.cuke1;
import cucumber.api.PendingException;
import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.en.*;
public class CukeStepsB {
#When("^some glue code exists$")
public void some_glue_code_exists() throws Throwable {
System.out.println("execute Then step - package com.cuke1");
}
#Then("^those steps should not fail$")
public void those_steps_should_not_fail() throws Throwable {
throw new PendingException();
}
}
UseCukeFromMain.java
import cucumber.api.cli.Main;
public class UseCukeFromMain {
public static void main(String[] args) throws Throwable {
Main.main(new String[]{
"--glue",
"com/cuke",
"--glue",
"com/cuke1",
"features/cukefeature.feature"}
);
}
}
compile classes
javac -cp "lib/*" -d project1/bin/ project1/src/com/cuke/*.java project1/src/com/cuke1/*.java
javac -cp "lib/*" -d project2/bin/ project2/src/*.java
created class files
project1/bin/com/cuke1/CukeStepsB.class
project1/bin/com/cuke/CukeStepsA.class
project2/bin/UseCukeFromMain.class
run the UseCukeFromMain
java -cp "project2/bin:project1/bin:lib/*" UseCukeFromMain
output
execute Given step - package com.cuke
execute Then step - package com.cuke1
1 Scenarios (1 pending)
3 Steps (1 pending, 2 passed)
0m0.114s
cucumber.api.PendingException: TODO: implement me
at com.cuke1.CukeStepsB.those_steps_should_not_fail(CukeStepsB.java:16)
at ✽.those steps should not fail(features/cukefeature.feature:5)
The absolute path is required for feature file. The step def directory requires classpath format.
public static void main(String[] args) throws Throwable {
//Your code to get feature file full path
Main.main(new String[]{"-g", "classpath to step definition file", "Full path to feature file"});
}
I have just started learning java, and know only a small amount of code, however this is still a simple program. It is more of a prank program, but mostly just to test if I can make a jar file.
Here is the code:
import java.awt.*;
import java.awt.event.*;
import java.lang.*;
import java.util.Random;
public class randommouse {
public static void main(String[] args) {
for (int i=1; i<1000; i++) {
Random rand = new Random();
int w = rand.nextInt(1024) + 1;
int h = rand.nextInt(768) + 1;
int t = rand.nextInt(2000) + 1;
try {
Robot r = new Robot();
r.mouseMove(w,h);
Thread.sleep(t);
} catch (AWTException e) {}
catch (InterruptedException e) {}
catch (NullPointerException e) {}
}
}
}
I save this to file called randommouse.java,
then compile it using
javac randommouse.java
This works and when I run it using
java randommouse
it works fine also.
So then I try to create a jar file. I use the command
jar cvf randommouse.jar randommouse.class
and it works. Afterwards I double click the jar file and it comes up with an error Java Exception.
So then I run it in the cmd with
java -jar randommouse.jar
and get this error
F:\Java>java -jar randommouse.jar
Exception in thread "main" java.lang.NullPointerException
at sun.launcher.LauncherHelper.getMainClassFromJar(LauncherHelper.java:3
99)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:463)
F:\Java>
Do I need to put in an argument, and if so where do I put that in and how?
Thank you in advance
Sam
From the JDK doc:
In order for this option to work, the manifest of the JAR file must
contain a line of the form
Main-Class: classname
Here, classname
identifies the class having the public static void main(String[] args)
method that serves as your application's starting point. See the Jar
tool reference page and the Jar trail of the Java Tutorial for
information about working with Jar files and Jar-file manifests.
When you use this option, the JAR file is the source of all user
classes, and other user class path settings are ignored.
You have to set the entry point
$> echo "Main-Class: randommouse" > Manifest
$> jar cfm randommouse.jar Manifest randommouse.class
Did you specify the entry point in the manifest?
http://download.oracle.com/javase/tutorial/deployment/jar/appman.html
A couple of issues with your code that are not related to your actual problem, but are important nevertheless.
1) This statement is unnecessary:
import java.lang.*;
By default, every class in java.lang is implicitly imported. You don't need to do it explicitly.
2) This is dangerously bad code:
try {
// ...
} catch (AWTException e) {
} catch (InterruptedException e) {
} catch (NullPointerException e) {
}
You are catching exceptions that are most likely due to programming errors, and throwing away all evidence that they ever happened. At the very least, you should print out some kind of error message ... and the exception stacktrace to that you can diagnose it.
In this particular context (in a main method), the following is a better approach:
try {
// ...
} catch (Throwable e) {
System.err.println("An unexpected error has occurred:");
e.printStacktrace(System.err);
System.exit(1);
}
I took a look at the source code of the class and it seems to try to get the main class attribute from a list of attributes, which are Strings, and is then invoking the trim() method on the found main class attribute. When the main class is not being specified, there is no main class attribute, which causes the searching method to return null to indicate so, and when trim() is being invoked on it, it is causing the NullPointerException since the searching method has returned null. To avoid this, be sure that the main class is specified in the jar manifest:
[directory of class files]>jar -cvmf [name of manifest] MyApp.jar
And be sure that you have written the manifest right (with the line break at the end):
Main-Class: [name of main class]
I am trying to use the java.lang.instrument.Instrumentation class which requires usage of the 'premain' class - a good descrip can be found on stack here.
The problem is that I have done this and am having trouble using it in another program. My class looks like this:
public class InstrumentationWrapper {
private static final String INSTR_KEY = "test.instrumentation";
private static Instrumentation instrumentation;
public static void premain(String options, Instrumentation inst) {
Properties props = System.getProperties();
if(props.get(INSTR_KEY) == null)
props.put(INSTR_KEY, inst);
}
public static Instrumentation getInstrumentation() {
if (instrumentation == null) {
instrumentation = (Instrumentation) System.getProperties().get(INSTR_KEY);
}
return instrumentation;
}
public static long getObjectSize(Object o) {
return instrumentation.getObjectSize(o);
}
public static long getSizeOfObjects (Collection<?> col) {
long cumSize = 0;
for (Object o : col) {
cumSize = getObjectSize (o);
}
return cumSize;
}
}
The manifest is in the Jar file as such:
$ jar -tf target/instrumentator-1.0.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/testTools/
com/testTools/instrumentation/
com/testTools/instrumentation/InstrumentationWrapper.class
META-INF/maven/
META-INF/maven/com.netrecon.testTools/
META-INF/maven/com.netrecon.testTools/instrumentator/
META-INF/maven/com.netrecon.testTools/instrumentator/pom.xml
META-INF/maven/com.netrecon.testTools/instrumentator/pom.properties
and the MANIFEST.MF is just:
$ more src/resources/META-INF/MANIFEST.MF
Manifest-Version: 1.0
Premain-Class: com.testTools.instrumentation.InstrumentationWrapper
In the launch configuration in eclipse I get the following problem
Failed to find Premain-Class manifest attribute in Z:\workspace\<project>\testTools\instrumentor\target\instrumentator-1.0.jar
and the option is -javaagent:${workspace_loc:instrumentator}\target\instrumentator-1.0.jar
I am really unsure how I can get this to work - All I really need to do is have a test harness that will let me look at the memory foot print of an array. Any ideas?
Nothing jumps out at me, but if you want to inspect further you can write a quick class to open up your Jar file with java.util.jar.JarFile and programatically inspect the manifest. This will indicate whether the issue is somehow in the way you wrote your manifest (maybe a space in the wrong place or something) or the way it's getting loaded (Maybe there is a typo in the specification of the premain class?).