Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  JStackAlloc - stack allocation of "value" objects in Java  (Read 34993 times)
0 Members and 1 Guest are viewing this topic.
Offline jezek2
« Posted 2008-06-21 07:08:07 »

Hi all,

I've created library that implements support for stack allocation of "value" objects, such as vectors and matrices. It's evolved version of stack allocation that I've used in JBullet, where it uses manual managing of stack state. This library generates this repetitive and cumbersome code with automatical bytecode instrumentation using ANT task and provides nice API.

Requires Java 5 and ASM 3.x library. Licensed under ZLIB license.

More details are available in JavaDoc:
http://jezek2.advel.cz/tmp/jstackalloc/javadoc/

And the latest version of library can be downloaded here:
http://jezek2.advel.cz/tmp/jstackalloc/jstackalloc-20080716.zip

(The original version posted in this thread can be found here)

Example ANT task (for NetBeans):

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
<target name="instrument-classes">
    <taskdef name="instrument-stack"
        classname="cz.advel.stack.instrument.InstrumentationTask"
        classpath="${run.classpath}">
    </taskdef>

    <instrument-stack dest="${build.classes.dir}" packageName="your.package.name">
        <fileset dir="${build.classes.dir}" includes="**/*.class"/>
    </instrument-stack>
</target>

<target name="-post-compile" depends="instrument-classes">
</target>


Possible future enhancements:
- allow selective storing of per-thread stack instance in protected final field and initialize it automatically in constructor (this is the system used in JBullet)
- allow passing parameters to set method when obtaining new instance from Stack.alloc(), this is problematic because it would need to use varargs method which would lose type safety (the heap allocations created by using varargs and autoboxing is not problem, because it would be entirelly replaced with direct call to set method)
- add optional single-thread mode, where stack instance is obtained from public static field instead of using ThreadLocal

EDIT 2008/06/23: updated download to latest version and edited possible enchancements
Offline DzzD
« Reply #1 - Posted 2008-06-21 09:02:28 »

I just discover JBullet and it looks great, but that's not the thread subject...

I must have a brain bug, but I have difficulties to understand the goal of this library, sry ?



Offline jezek2
« Reply #2 - Posted 2008-06-21 09:26:36 »

I must have a brain bug, but I have difficulties to understand the goal of this library, sry ?

The goal is to "stack allocate" (implementation uses object pool) temporary objects (such as vectors) so you don't need to create a lot of garbage or have temporary objects stored in static fields which are not thread-safe, and to have programmer friendly API that minimizes creation of lot of redudant code and thus reduce mistakes.

About the garbage creation, the problem is not in allocating new objects or garbage collection per se, in fact HotSpot is very good in this. But when your garbage creation exceeds some range (like in JBullet) the GC is called very often, eg. 10x or more per second and it badly affects performance, both in throughput and frame to frame jerkiness which is very visible in game. Also as JBullet is only a library and not final application, it must count with garbage produced by other libraries and final application.

The library tradeoffs some performance for nearly constant behaviour (very similar to realtime system definition). But because the code is generated it can generate more optimized code which would be pretty ugly in source code if written by hand.

The library also supports disabled mode, where no stack allocation occurs, but instead the method calls are replaced with normal heap allocation. This is good for debugging, comparing both allocation schemes and it's also prepared to day when hotspot will handle stack allocation (or some different optimization with similar effect) on it's own.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DzzD
« Reply #3 - Posted 2008-06-21 09:38:11 »

thank you, I now understand the whole now. but your second explanation is far away better for me Smiley

Offline bienator

Senior Member




OutOfCoffeeException


« Reply #4 - Posted 2008-06-21 10:26:48 »

very good work jezek2!

But how do you determine what to stack allocate and what not? Even escape analysis are not enough for doing that (but probably the first thing you do).

(copied from doc)
1  
2  
3  
4  
5  
6  
 public static Vector3f average(Vector3f v1, Vector3f v2) {
     Vector3f tmp = Stack.alloc(Vector3f.class);
     tmp.add(v1, v2);
     tmp.scale(0.5f);
     return Stack.copyOut(tmp);
 }


to stack allocate this it would require to figure out whether add(), scale() static{} and the constructor of Vector3f have "side effects" or some kind of state. In other words how do you distinct value objects from others?

have you already thought about annotations?
1  
2  
3  
4  
 @PostCompile(stackallocation=true)
 public static Vector3f average(Vector3f v1, Vector3f v2) {
..
 }


Offline jezek2
« Reply #5 - Posted 2008-06-21 10:39:27 »

very good work jezek2!

Thanks Smiley

But how do you determine what to stack allocate and what not? Even escape analysis are not enough for doing that (but probably the first thing you do).
...
to stack allocate this it would require to figure out whether add(), scale() static{} and the constructor of Vector3f have "side effects" or some kind of state. In other words how do you distinct value objects from others?

That's simple, stack allocated are only objects obtained by Stack.alloc(), simple as that Smiley So it's up to the programmer how he maintain things. This is entirelly local modification, so global optimization such as escape analysis is not needed.

have you already thought about annotations?
1  
2  
3  
4  
 @PostCompile(stackallocation=true)
 public static Vector3f average(Vector3f v1, Vector3f v2) {
..
 }


The goal is not to create escape analysis, it's too much work for the possible gain (in pure Java) and bad for libraries and runtime loading of classes (unlike VM which can dynamically deoptimize code if newly loaded class is in collision with some optimization). Also the build process would be much slower.
Offline bienator

Senior Member




OutOfCoffeeException


« Reply #6 - Posted 2008-06-21 10:48:44 »

Ah I see,

I just realized I understood it completely wrong  Undecided
I initially thought this "post processor" could be applied after compilation without any manual changes in source code and it would determine by itself which methods are good candidates for stack allocations.

sorry for the confusion

Offline Spasi
« Reply #7 - Posted 2008-06-21 12:47:01 »

If we ignore the bytecode instrumentation part, how does it compare to Javolution's StackContext?
Offline jezek2
« Reply #8 - Posted 2008-06-21 13:03:49 »

If we ignore the bytecode instrumentation part, how does it compare to Javolution's StackContext?

I would say less overhead, ie. stack is obtained from ThreadLocal only once per method, concrete methods are generated for each type, so minimum code is used for each case and no reflection involved (though it seems that javolution uses it only in 'generic' cases).
Offline jezek2
« Reply #9 - Posted 2008-06-23 07:40:08 »

New version available:
http://jezek2.advel.cz/tmp/jstackalloc/jstackalloc-20080623.zip

Also see the updated JavaDoc:
http://jezek2.advel.cz/tmp/jstackalloc/javadoc/

Changes in release 20080623:
- Removed obsolete code and fixed closing of files
- Added single thread mode
- Removed copyOut method
- Disabled stack allocation in suspendable methods when using Matthias Mann's Continuations library

The main change is that copyOut method was removed, it used two copies for most usages and had error prone behaviour by using per-thread static instance to pass values out. Using output parameter is preferred now, see the example in the JavaDoc.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gouessej
« Reply #10 - Posted 2008-06-23 08:30:46 »

But when your garbage creation exceeds some range (like in JBullet) the GC is called very often, eg. 10x or more per second and it badly affects performance, both in throughput and frame to frame jerkiness which is very visible in game.
I don't understand. It is already possible to select a better algorithm for the garbage collection since Java 1.4, a concurrent low pause collector by using the option -XX:+UseConcMarkSweepGC, isn't it?

http://java.sun.com/docs/hotspot/gc1.4.2/

It is already possible to set a limit to the duration of pause since Java 1.5 by using -XX:MaxGCPauseMillis, isn't it?

http://articles.techrepublic.com.com/5100-10878_11-6108296.html


Offline ewjordan

Junior Member





« Reply #11 - Posted 2008-06-23 09:30:02 »

Quote
I don't understand. It is already possible to select a better algorithm for the garbage collection since Java 1.4, a concurrent low pause collector by using the option -XX:+UseConcMarkSweepGC, isn't it?
When doing physics engine stuff you generate so much object garbage that it pretty much doesn't matter what garbage collection algorithm is in use, you're generating such huge piles of crap that no garbage collector could be expected to handle it all very well.  These are generally objects that were never created with the intention of lasting past the current block scope, so it makes perfect sense to have your own stack to handle them since Java offers no way to let you put stuff on the "real" stack.

Plus, with such tiny objects (a vector is mainly just a holder for a few values), and especially when you might be creating hundreds of thousands of them per frame, the extra microseconds that it takes to allocate and initialize the object meta-data can really add up, so I would argue that garbage is not the entire problem, even if it is the main one.
Offline jezek2
« Reply #12 - Posted 2008-06-24 05:26:34 »

I don't understand. It is already possible to select a better algorithm for the garbage collection since Java 1.4, a concurrent low pause collector by using the option -XX:+UseConcMarkSweepGC, isn't it?

http://java.sun.com/docs/hotspot/gc1.4.2/

It is already possible to set a limit to the duration of pause since Java 1.5 by using -XX:MaxGCPauseMillis, isn't it?

http://articles.techrepublic.com.com/5100-10878_11-6108296.html

I think this is pretty valid argument. I'm really concerned about allocations because of what ewjordan said, but I can be wrong. Maybe the VM is already capable of it. The tool is still very valuable for me, because I can now switch easily between different allocation schemes (or create new one, like automatically storing it in fields instead of using the emulated stack, which would help source readability a lot).

Also I would like to test it on final game when it's done, to see real results and be prepared for VM not handling it enough on it's own. And I would like to work it nicely even for older HW, eg. single core machines bought 4+ years ago with at least 512MB RAM (and I need that memory mainly for data, not for overhead of handling of allocations).

I've noticed that the ConcMarkSweepGC took much more memory than default GC, I also didn't tested how it perform when you use CPU a lot, there is a work to be done due to allocations, it's useless and the cost must be somewhere, that's the motivation behind this.
Offline jezek2
« Reply #13 - Posted 2008-07-03 21:01:10 »

New version available:
http://jezek2.advel.cz/tmp/jstackalloc/jstackalloc-20080703.zip

Changes in release 20080703:
- Fixed generation of stack class on first intrumentation run
- Added support for storing value objects in static fields instead of stack

It can now store objects in static fields, the idea is to profile your code and look for top hotspot methods by invocation count, and if it makes sense mark them with StaticAlloc annotation (see it's description carefully).

About performance, I'm using this library in JBullet and it looks like it's slightly faster than heap allocation when there is not excessive amount of allocation per method. The better part is that it doesn't seem to be slower than normal heap allocation, and the GC does nearly nothing Smiley The good thing is that I can always easily compare different approaches with just build option.
Offline jezek2
« Reply #14 - Posted 2008-07-16 16:51:31 »

New version available:
http://jezek2.advel.cz/tmp/jstackalloc/jstackalloc-20080716.zip

Changes in release 20080716:
- Fixed wrong generation of "get" method in stack when in single thread mode
- Added isolated mode and documented InstrumentationTask
Offline toucansam

Junior Newbie





« Reply #15 - Posted 2009-06-06 07:11:15 »

I think i've implemented everything correctly, but i'm getting an error:

Quote
BUILD FAILED
/path_to_file/build.xml:13: java.lang.Error: not instrumented

What could this mean? It's fairly nondescript.

Edit:
What doesn't make sense is that this is the actual build file, in the instrumentation task

Also, it would be great if there could be a way to "recycle" objects, so they are placed back on the stack.  Maybe require a set() method with no arguments?
This would eliminate a lot of object construction.
Offline jezek2
« Reply #16 - Posted 2009-06-06 10:41:05 »

I think i've implemented everything correctly, but i'm getting an error:

What could this mean? It's fairly nondescript.

Edit:
What doesn't make sense is that this is the actual build file, in the instrumentation task

The only thing that comes to my mind is that you're using stack allocation in static intializer of some class.

Also, it would be great if there could be a way to "recycle" objects, so they are placed back on the stack.  Maybe require a set() method with no arguments?
This would eliminate a lot of object construction.

Actually they're recycled automatically. That's what the bytecode instrumentation part does, see documentation for Stack class. There is rough example what the instrumentation does.
Offline toucansam

Junior Newbie





« Reply #17 - Posted 2009-06-06 18:22:05 »

Thanks that's probably the problem then.

Actually they're recycled automatically. That's what the bytecode instrumentation part does, see documentation for Stack class. There is rough example what the instrumentation does.

Does that mean that objects allocated with Stack.alloc(class) are not guaranteed to be an result of the () constructor, if they're recycled?  Like, if the instrumentation recycled a vector of <2,3,4>, and then you grabbed it with the Stack.alloc(class), would it still have <2,3,4>?
I guess i misunderstood this system.  So every object that you call Stack.alloc() for, it reuses?


Edit:
I added
1  
2  
3  
Error e = new Error("not instrumented");
e.printStackTrace();
throw e;

To the stack class so I could trace where it happened (ant doesn't print stack traces), which worked great.  I also had to clean it every time after these errors, for some reason.
Offline jezek2
« Reply #18 - Posted 2009-06-06 19:32:48 »

Does that mean that objects allocated with Stack.alloc(class) are not guaranteed to be an result of the () constructor, if they're recycled?  Like, if the instrumentation recycled a vector of <2,3,4>, and then you grabbed it with the Stack.alloc(class), would it still have <2,3,4>?
I guess i misunderstood this system.  So every object that you call Stack.alloc() for, it reuses?

Exactly, you must not rely on previous state of the value objects for this reason. Constructor is called only when there is no object present in recycle list of "stack".
Offline BegemoT

Junior Newbie





« Reply #19 - Posted 2009-07-07 19:42:03 »

Excellent work, jezek! JBullet at all, and JStackAlloc particular is very interesting. But I have a thought and idea -- why it's so explicit in code level? If you already use so powerfull method as bytecode instrumentation, why not use it like this:

1  
final Vector3f v = @StackAllocation new Vector3f(...);

and translate in into the same magic on instrumentation phase? From my current point of view, annotations gives you the same possibilities, as your explicit Stack.alloc, but they
  • have no influence on perfomance in case code not instrumented. They just slightly increase class-file size
  • do not require instrumentation. If code not instrumented, it just execute as written.
  • one can use instrumentation in realtime -- on classloader level, and even switch between optimized/not optimized version in realtime!
  • it's subject for more compile-time checking. For example, code like Vector3f = @StackAlloc new Vector3f(v1) simply won't compile, if Vector3f does not have copy constructor. (Unfortunately, it does not save us from missing or misimplementing .set(Vector3f) method...)
  • it's declarative, for me it looks much more elegant

That do you think?

Ruslan
Offline jezek2
« Reply #20 - Posted 2009-07-07 20:07:32 »

Excellent work, jezek! JBullet at all, and JStackAlloc particular is very interesting. But I have a thought and idea -- why it's so explicit in code level? If you already use so powerfull method as bytecode instrumentation, why not use it like this:

1  
final Vector3f v = @StackAllocation new Vector3f(...);


This syntax is not possible, the closest one is:
1  
@StackAllocation Vector3f v = new Vector3f(...);


and translate in into the same magic on instrumentation phase? From my current point of view, annotations gives you the same possibilities, as your explicit Stack.alloc, but they
  • have no influence on perfomance in case code not instrumented. They just slightly increase class-file size
  • do not require instrumentation. If code not instrumented, it just execute as written.
  • one can use instrumentation in realtime -- on classloader level, and even switch between optimized/not optimized version in realtime!
  • it's subject for more compile-time checking. For example, code like Vector3f = @StackAlloc new Vector3f(v1) simply won't compile, if Vector3f does not have copy constructor. (Unfortunately, it does not save us from missing or misimplementing .set(Vector3f) method...)
  • it's declarative, for me it looks much more elegant

That do you think?

Interesting idea, though I don't like the annotations syntax for this. I consider the stack allocation as a core feature that shoudn't be optional as it changes the memory behaviour a lot. This is reason why it throws Error instead of some sort of fallback, users would then accidentally run slower/worse path. Also I like it in this explicit way because it tells something special is occuring and not ordinary allocation, such as the case with constructor with argument (or without), the programmer can be misleaded to think that the constructor is actually run or assume that the values are zeroed whereas it's not true.
Offline BegemoT

Junior Newbie





« Reply #21 - Posted 2009-07-08 08:58:43 »

This syntax is not possible, the closest one is:
1  
@StackAllocation Vector3f v = new Vector3f(...);

Yes, sorry, I've forgot about exact syntax for statement annotations -- they are rarely used, as for me.

Interesting idea, though I don't like the annotations syntax for this. I consider the stack allocation as a core feature that shoudn't be optional as it changes the memory behaviour a lot. This is reason why it throws Error instead of some sort of fallback, users would then accidentally run slower/worse path. Also I like it in this explicit way because it tells something special is occuring and not ordinary allocation, such as the case with constructor with argument (or without), the programmer can be misleaded to think that the constructor is actually run or assume that the values are zeroed whereas it's not true.

Well, I agree, your point of view is completely legitime. I just think it's more about your specific use case. As far, as I understand, stack allocations was a critical feature, letting you to port C code to java without great rewritting it to refactor memory usage strategy. So it's really "something special" and "core feature" in your case. But if you want your library to be public used (as for me, it worth it -- it's small, easy, and do the work well -- that's more?), just try to look at it from point of view of developer, thinking about incorporate stack allocations in existing code. In current form, it can't be called non-obtrusive. One should make rather big changes in code, and live with fact, that code won't be ran without instrumentation.  It's makes a high barrier for such decision. From other side -- add annotations to some of statement is not a big deal. Anyone can just do it and be sure, what without special processing such annotations do change nothing in current behavior (and, most probably, even completely removed by obfuscator, if used). As for me, it makes decision "to use or not to use" much easier.

For example. Ive' just downloaded JBullet and exploring sources. I can't run it from my IDE without instrumentation -- although I just want to debug it to clearify code paths, and it's ok for me to have code run slow...

As for "changes the memory behaviour a lot" -- well, think of it from that point of view: memory behavior may be changed a lot by jvm GC options given at startup. It's gives you, in some cases, really big changes in memory behavior, and you really do not see nothing about it in code. It can be chaned by JIT -- and, again, you'll se nothing about it in code. It's java -- memory behavior is much less predictable at all, and I think, most java developers already learn to live with it. You even can't be sure, that new Vector3f() do not actually do the stack allocation by itself -- being optimized by JIT (well, may be for now you can -- such optimizations usually described in Sun's jdk's preview -- but for future... we all waiting for it). If jdk1.7 (8,9..) will include such optimization, one can just remove instrumentation step from it's build process, and letting jit do it's best. While currently one's left with some "strange" legacy code in allocations, which can confuse JIT in it's optimization, and confuse junior developers in understanding "wtf is happens here and why?"

To summarize -- I suppose, annotations-based instrumentation can be added as an option. If someone want stack allocation to be explicit -- it'll have such option. If for someone it'll be easier to add it in non-obtrusive way -- the option will also be here. Nobody can escape. Your library will conquer the world! At least, java part of it Smiley
Offline jezek2
« Reply #22 - Posted 2009-07-08 10:27:18 »

Well, I'm not sure if I really want this library to be widely used. I've made it for extreme case of allocation of many tiny objects and published here so someone other who will fall into the same situation can use it. Otherwise HotSpot is very good at allocations, so I don't recommend to use this library in normal situations. I've also used it in some other libraries, but I'm considering to remove it from there as the amount of allocation is not that much.

As for JBullet I don't see much problem here, most users just need precompiled JAR which doesn't have any runtime or API dependency on JStackAlloc. Ant is standard way for building applications, so I don't feel bad by requiring it.
Offline BegemoT

Junior Newbie





« Reply #23 - Posted 2009-07-08 12:31:48 »

Well, I'm not sure if I really want this library to be widely used. I've made it for extreme case of allocation of many tiny objects and published here so someone other who will fall into the same situation can use it. Otherwise HotSpot is very good at allocations, so I don't recommend to use this library in normal situations. I've also used it in some other libraries, but I'm considering to remove it from there as the amount of allocation is not that much.
Well, yes, JIT and GC becames more and more powerfull each day rise. Years Sun engineers adviced not to use object pools just to improve memory allocation, 'cos it does not give the bonus, but only confuses new GC algorithm (it was time generation GC was introduced). So, after years, I was surprised you was able to gain perfomance bonus from such a method, but it is -- and why do not expose it to community? May be it will speed up Sun's JIT enchancements at least Smiley

But if do this, it should be done in the way, which can be easily rolled back if JIT at last become smart enough to do the job by itself. I'm near to sure, what code like this
1  
final Vector3f v = Stack.alloc(Vector3f.class);

will greatly complicate escape analyze job for such "smart" future JIT. So in current version, gaining perfomance bonus for now you'll likely close the way for you code to gain perfomance boost from future compiler allocation optimization.

By the way, can you summarize the perfomance boost you gaining now? Just to be oriented in then and there to use you library
Offline ewjordan

Junior Member





« Reply #24 - Posted 2009-07-08 12:52:30 »

Years Sun engineers adviced not to use object pools just to improve memory allocation, 'cos it does not give the bonus, but only confuses new GC algorithm (it was time generation GC was introduced). So, after years, I was surprised you was able to gain perfomance bonus from such a method, but it is -- and why do not expose it to community? May be it will speed up Sun's JIT enchancements at least Smiley
In full fairness to the engineers that made these recommendations (I seem to recall a flurry of them in about 2005), they were only about 10 years early with them - I fully expect that by the time Java 8 rolls around, escape analysis/stack allocation/scalarization will be performing on par with manual object pooling.

Shocked

The lesson: never trust developers that are mucking with the innards of a system to give you a fair scoop on the best way to use it in its current form; they are far too optimistic as a rule about what is right around the corner, for certain values of "right around the corner."

jezek2, is there any way to use this library in a form where it can degrade gracefully (i.e. turning all pool pulls into plain old allocations) in the absence of instrumentation, or is that just not a realistic possibility given the way it's set up?
Offline BegemoT

Junior Newbie





« Reply #25 - Posted 2009-07-08 14:31:43 »

In full fairness to the engineers that made these recommendations (I seem to recall a flurry of them in about 2005), they were only about 10 years early with them - I fully expect that by the time Java 8 rolls around, escape analysis/stack allocation/scalarization will be performing on par with manual object pooling.
Well, it seems, (http://www.ibm.com/developerworks/java/library/j-jtp09275.html) that java 1.6 already has such feature like escape-analyze based stack or even registry allocation.

jezek2, is there any way to use this library in a form where it can degrade gracefully (i.e. turning all pool pulls into plain old allocations) in the absence of instrumentation, or is that just not a realistic possibility given the way it's set up?
I'm sure, it's the question every developer thinking about integrate the library ask first Smiley
Offline LeoMaheo

Senior Newbie





« Reply #26 - Posted 2009-08-29 14:32:44 »

Hi Jezek2!

EDIT: Forget this, this is not needed. Please refer to my next post instead.

This is a patch for JStackAlloc to work with Maven.

I'm building my project with Maven, hence I also build JBullet with Maven (version 2.0.9).
Hence I added an AntRun task to Maven's POM file to let JStackAlloc instrument JBullet.

For this to work, I had to modify JStackAllock,
because the method FileSet.getDirectoryScanner()
doesn't exist in the Ant-stuff provided by the Maven AntRun plugin.
Instead, getDirectoryScanner(Project) can be used.
Also a getDir() needs to be replaced by getDir(getProject()).

Here's the patch:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
--- /home/magnus/tmp/InstrumentationTask.java   2008-07-16 19:43:34.000000000 +0200
+++ /home/magnus/dev/dev/madmind/master.git/jstackalloc-20080716/src/cz/advel/stack/instrument/InstrumentationTask.java   2009-08-29 11:51:33.000000000 +0200
-105,13 +105,14 @@
    @Override
    public void execute() throws BuildException {
       try {
          List<File> files = new ArrayList<File>();
          for (FileSet fs : fileSets) {
-            String[] fileNames = fs.getDirectoryScanner().getIncludedFiles();
+            String[] fileNames = fs.getDirectoryScanner(
+                  getProject()).getIncludedFiles();
             for (String fname : fileNames) {
-               File file = new File(fs.getDir(), fname);
+               File file = new File(fs.getDir(getProject()), fname);
                if (file.getName().endsWith(".class")) {
                   files.add(file);
                }
             }
          }


Without above patch, the Maven AntRun task fails with a NoSuchMethodError:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] org.apache.tools.ant.types.FileSet.getDirectoryScanner()Lorg/apache/tools/ant/DirectoryScanner;
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.NoSuchMethodError: org.apache.tools.ant.types.FileSet.getDirectoryScanner()Lorg/apache/tools/ant/DirectoryScanner;
   at cz.advel.stack.instrument.InstrumentationTask.execute(InstrumentationTask.java:110)
   at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
   at org.apache.tools.ant.Task.perform(Task.java:364)
   at org.apache.tools.ant.Target.execute(Target.java:341)
   at org.apache.maven.plugin.antrun.AbstractAntMojo.executeTasks(AbstractAntMojo.java:108)
   at org.apache.maven.plugin.antrun.AntRunMojo.execute(AntRunMojo.java:83)
   at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
   at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
   at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:499)
   at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:478)
   at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
   at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:291)
   at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
   at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
   at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
   at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
   at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
   at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
   at org.codehaus.classworlds.Launcher.main(Launcher.java:375)


Kind regards, Magnus
Offline LeoMaheo

Senior Newbie





« Reply #27 - Posted 2009-08-29 20:51:36 »

This is a patch for JStackAlloc to work with Maven.
[...]
For this to work, I had to modify JStackAllock,
because the method FileSet.getDirectoryScanner()
doesn't exist in the Ant-stuff provided by the Maven AntRun plugin.
[...]

Instead I could simply specify that version 1.3 of the Maven AntRun plugin be used.
This AntRun version uses another version of Ant,
in which the above method is present, and so my patch is not needed.

In case anyone wants to build JStackAllock / JBullet with Maven,
below are some POM snippents.

(I hope it's fine by you, Jezek2, with Jezek2 as group ID?)

Regards, Magnus

Build JStackAlloc:  (Works with Maven 2.0.9)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>jezek2</groupId>
  <artifactId>jstackalloc</artifactId>
  <packaging>jar</packaging>
  <version>20080716</version>
  <name>jstackalloc</name>
  <url>http://www.java-gaming.org/topics/jstackalloc-stack-allocation-of-objects-in-java/18843/view.html</url>
 <dependencies>
    <dependency>
      <groupId>org.apache.ant</groupId>
      <artifactId>ant</artifactId>
      <version>1.7.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>asm</groupId>
      <artifactId>asm-all</artifactId>
      <version>3.1</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.0.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>


Instrument JBullet: (works for me with Maven 2.0.9)
(Notice the <version>1.3</version> element.)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
[...]
    <dependency>
      <groupId>jezek2</groupId>
      <artifactId>jstackalloc</artifactId>
      <version>20080716</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
[...]
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.3</version>
        <executions>
          <execution>
            <phase>process-classes</phase>
            <configuration>
              <tasks>
                <property name="compile_classpath" refid="maven.compile.classpath"/>
                <taskdef name="instrument-stack"
                    classname="cz.advel.stack.instrument.InstrumentationTask"
                    classpath="${compile_classpath}"/>
                <instrument-stack dest="${project.build.outputDirectory}" packageName="com.bulletphysics" isolated="true" singlethread="true">
                    <fileset dir="${project.build.outputDirectory}" includes="**/*.class"/>
                </instrument-stack>
              </tasks>
            </configuration>
            <goals>
              <goal>run</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
[...]

Offline quarante-sept

Innocent Bystander





« Reply #28 - Posted 2010-01-21 10:33:16 »

edit: forget it
Offline leesdolphin

Innocent Bystander





« Reply #29 - Posted 2010-03-06 08:38:33 »

I'm just wondering if there is ment to be any errors when i try and use your lirary wth Jbullet-JME.

i get the following error
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
java.lang.Error: not instrumented
        at cz.advel.stack.Stack.alloc(Stack.java:109)
        at com.bulletphysics.collision.shapes.BoxShape.calculateLocalInertia(BoxShape.java:165)
        at com.jmex.jbullet.collision.shapes.CollisionShape.calculateLocalInertia(CollisionShape.java:59)
        at com.jmex.jbullet.nodes.PhysicsNode.preRebuild(PhysicsNode.java:228)
        at com.jmex.jbullet.nodes.PhysicsNode.rebuildRigidBody(PhysicsNode.java:216)
        at com.jmex.jbullet.nodes.PhysicsNode.createCollisionShape(PhysicsNode.java:747)
        at com.jmex.jbullet.nodes.PhysicsNode.<init>(PhysicsNode.java:135)
        at com.jmex.jbullet.nodes.PhysicsNode.<init>(PhysicsNode.java:120)
        at com.jmex.jbullet.nodes.PhysicsVehicleNode.<init>(PhysicsVehicleNode.java:79)
        at jmetest.jbullet.TestSimplePhysicsCar.setupGame(TestSimplePhysicsCar.java:126)
        at jmetest.jbullet.TestSimplePhysicsCar$10.call(TestSimplePhysicsCar.java:277)
        at jmetest.jbullet.TestSimplePhysicsCar$10.call(TestSimplePhysicsCar.java:274)
        at com.jme.util.GameTask.invoke(GameTask.java:140)
        at com.jme.util.GameTaskQueue.execute(GameTaskQueue.java:111)
        at com.jmex.game.StandardGame.update(StandardGame.java:372)
        at com.jmex.game.StandardGame.run(StandardGame.java:244)
        at java.lang.Thread.run(Thread.java:619)


There appears to be an issue with the
1  
alloc(Class)
method, it will always throw the error above.
Slightly Huh, any help would be appreciated


Lee Symes
Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (16 views)
2014-08-28 18:26:30

CopyableCougar4 (25 views)
2014-08-22 19:31:30

atombrot (38 views)
2014-08-19 09:29:53

Tekkerue (34 views)
2014-08-16 06:45:27

Tekkerue (32 views)
2014-08-16 06:22:17

Tekkerue (20 views)
2014-08-16 06:20:21

Tekkerue (30 views)
2014-08-16 06:12:11

Rayexar (66 views)
2014-08-11 02:49:23

BurntPizza (43 views)
2014-08-09 21:09:32

BurntPizza (34 views)
2014-08-08 02:01:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!