My original code looked like this:
SpecificEntity result = broker.changeSpecificEntity ( myTestKey , myTestData ) ;
"broker" is an (interface/implementation facade) with several methods (create, change, remove, etc) for each of many entity types.
I want to implement a generic version of the code so I don't have to repeat myself. There is more code than shown here, but the rest is already generic.
This is what we have so far.
public < K extends Key , D extends Data > D changeAnyEntity ( final K testKey, final D testData, BiFunction<K, D, D> brokerMethod )
{
return brokerMethod.apply ( testKey , testData ) ;
}
Now I need to invoke a generic method, (e.g., changeAnyEntity) for each of the methods under test.
SpecificEntity result = changeAnyEntity ( myTestKey , myTestData , myBrokerFuncion )
I have not yet figured out how to define / create "myBrokerFunction"
Create an interface with a single method accepting your wanted arguments and returning the type you need.
Then you can use that interface as a parameter type, and you can avoid all unnecessary casting inside your generic method. The reason for making it generic is to avoid "knowing" about all individual child types after all
#FunctionalInterface
interface BrokerFun<KK, DD> {
DD changeEntity(KK key, DD data);
}
public < K extends Key , D extends Data > boolean changeAnything (
final K testKey,
final D testData,
BrokerFun<K, D> brokerFun
) {
try {
D result = brokerFun.changeEntity(testKey,testData);
return isEqualCriticalFields(result, testData);
} catch ( final Exception e ) {
return false ;
}
}
EDIT(Adding a BiFunction solution)
Alternatively you can use the BiFunction interface like this
public < K extends Key , D extends Data > boolean changeAnything (
final K testKey,
final D testData,
BiFunction<K, D, D> brokerFun
) {
try {
D result = brokerFun.apply(testKey,testData);
return isEqualCriticalFields(result, testData);
} catch ( final Exception e ) {
return false ;
}
}
Finally . . . ignoring try/catch logic
final BiFunction < SpecificEntityKey , SpecificEntityData , SpecificEntityData >
brokerMethod = ( k , d ) -> { myBroker.changeSpecificEntity ( k , d , null ) ; return d ; } ;
Related
I'm writing a program to sort datetimes by date.
There is a DateTime beginning and a DateTime end.
These are put into their own object from user input.
The DateTime beginning and the DateTime end make up their own term.
So each term has an object of its own with a DateTime beginning and a DateTime end.
What I want to do is to sort all DateTime beginning and all DateTime end by date.
How can I do this? I'm thinking about a comperator but I can't seem to do this on custom objects.
So lets say user imputs one beginning date of 01/01/2000 and one end date of 01/01/2002. This makes up one term.
The user then imputs a second term consisting of a beginning date of 01/01/2001 and an end date of 01/01/2003.
What I now want to do is to sort the dates and make the three new terms which would be:
beginning 01/01/2000 end 01/01/2001
beginning 01/01/2001 end 01/01/2002
beginning 01/01/2002 end 01/01/2003
I'm stuck on how to proceed with this, any ideas?
Put every date in a new collection, sort it by the date, and then create new objects that consist neighbour dates from the collection.
Try:
public static void main(String[] args) {
List<YourClass> list = new ArrayList<>();
list.add(new YourClass(new Date(100000000), new Date(200000000)));
list.add(new YourClass(new Date(150000000), new Date(250000000)));
list.add(new YourClass(new Date(50000000), new Date(300000000)));
System.out.println(list);
List<Date> dates = new ArrayList<>();
for (YourClass yc : list){
if (!dates.contains(yc.beginning)) dates.add(yc.beginning);
if (!dates.contains(yc.end)) dates.add(yc.end);
}
Collections.sort(dates);
List<YourClass> list2 = new ArrayList<>();
for (int i=0; i < dates.size() -1; i++){
list2.add(new YourClass(dates.get(i), dates.get(i+1)));
}
System.out.println(list2);
}
public static class YourClass {
Date beginning;
Date end;
public YourClass(Date beginning, Date end) {
this.beginning = beginning;
this.end = end;
}
#Override
public String toString() {
return "\n" + beginning + " -> " + end ;
}
}
tl;dr
What I want to do is to sort all DateTime beginning and all DateTime end by date.
You can do one or the other but not both.
To sort by start date (seems sensible in practice), implement compareTo method.
return this.getDateRange().getStart().compareTo( thatStart );
To sort by stop date (I do not see any sense in this), implement the Comparator interface.
return
t1.getDateRange().getEnd().compareTo(
t2.getDateRange().getEnd()
)
;
LocalDate
As others noted, you should be using the modern java.time classes, never the terrible old Date/Calendar/SimpleDateFormat classes. For a date-only value, without time-of-day and without time zone, use LocalDate.
LocalDateRange
As the Answer by jbx discusses, you should represent your term’s start and stop dates as a pair. But do not write a class when one already exists. Use LocalDateRange class from the ThreeTen-Extra project. This project adds functionality to the java.time classes.
Comparable
On your Term class, implement Comparable interface to enable simple easy sorting. Add the method compareTo. The obvious approach there would be to compare the starting LocalDate of each Term object’s LocalDateRange object.
The LocalDate class implements compareTo, no we don’ have to.
#Override
public int compareTo ( Object o ) {
if ( this == o ) return 0;
if ( o == null || getClass() != o.getClass() ) return 0;
LocalDate thatStart = ( ( Term ) o ).getDateRange().getStart();
return this.getDateRange().getStart().compareTo( thatStart );
}
See the Java Tutorial on object-ordering.
Sort by stop date
Your Question is not clear, but you seem to be asking to alternatively sort by the ending date. I cannot imagine how this is useful in practical terms. But anyways, the solution is to sort by providing an implementation of the Comparator interface.
#Override
public int compare ( Term t1 , Term t2 ) {
return t1.getDateRange().getEnd().compareTo( t2.getDateRange().getEnd() );
}
Example class
Here is an example Term class. May not be production-quality code, but should get you going in the right direction.
package com.basilbourque.example;
import org.threeten.extra.LocalDateRange;
import java.time.LocalDate;
import java.time.Month;
import java.util.*;
public class Term implements Comparable {
private UUID id;
private LocalDateRange dateRange;
// Constructor
public Term ( LocalDate start , LocalDate stop , UUID id ) {
Objects.requireNonNull( start ); // TODO: Add more such checks for all arguments.
if ( start.getYear() < 2015 ) { // TODO: Add more such checks for too far into the past or future, for both start and for stop.
throw new IllegalArgumentException( "Year of start date is too far in the past. Message # afcd30a0-b639-4ccf-b064-18cc2ea8587b." );
}
this.id = id;
this.dateRange = LocalDateRange.of( start , stop );
}
// Alternative constructor.
public Term ( LocalDateRange dateRange , UUID id ) {
this( dateRange.getStart() , dateRange.getEnd() , id );
}
// --------| Object |-------------------------
#Override
public String toString ( ) {
return "Term{ " +
"id=" + id +
" | dateRange=" + dateRange +
" }";
}
public UUID getId ( ) {
return id;
}
public LocalDateRange getDateRange ( ) {
return dateRange;
}
#Override
public boolean equals ( Object o ) {
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
Term term = ( Term ) o;
return this.getId().equals( term.getId() );
}
#Override
public int hashCode ( ) {
return Objects.hash( this.getId() );
}
#Override
public int compareTo ( Object o ) {
if ( this == o ) return 0; // If same object.
if ( o == null || getClass() != o.getClass() ) return 0;
LocalDate thatStart = ( ( Term ) o ).getDateRange().getStart();
return this.getDateRange().getStart().compareTo( thatStart );
}
static public class StopDateComparator implements Comparator < Term > {
#Override
public int compare ( Term t1 , Term t2 ) {
return t1.getDateRange().getEnd().compareTo( t2.getDateRange().getEnd() );
}
}
}
Try it.
public static void main ( String[] args ) {
Term t1 = new Term( LocalDate.of( 2018 , Month.JUNE , 23 ) , LocalDate.of( 2018 , Month.JULY , 23 ) , UUID.randomUUID() );
Term t2 = new Term( LocalDate.of( 2018 , Month.JANUARY , 23 ) , LocalDate.of( 2018 , Month.DECEMBER , 23 ) , UUID.randomUUID() );
Term t3 = new Term( LocalDate.of( 2018 , Month.MARCH , 23 ) , LocalDate.of( 2018 , Month.APRIL , 23 ) , UUID.randomUUID() );
List < Term > terms = new ArrayList <>( List.of( t1 , t2 , t3 ) );
System.out.println( "Before natural sort: " + terms );
Collections.sort( terms );
System.out.println( "After natural sort: " + terms );
Collections.sort( terms , new Term.StopDateComparator() );
System.out.println( "After Comparator sort: " + terms );
}
Before natural sort: [Term{ id=27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | dateRange=2018-06-23/2018-07-23 }, Term{ id=792bf365-eca4-460b-afad-c5cf62cf9a29 | dateRange=2018-01-23/2018-12-23 }, Term{ id=c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | dateRange=2018-03-23/2018-04-23 }]
After natural sort: [Term{ id=792bf365-eca4-460b-afad-c5cf62cf9a29 | dateRange=2018-01-23/2018-12-23 }, Term{ id=c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | dateRange=2018-03-23/2018-04-23 }, Term{ id=27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | dateRange=2018-06-23/2018-07-23 }]
After Comparator sort: [Term{ id=c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | dateRange=2018-03-23/2018-04-23 }, Term{ id=27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | dateRange=2018-06-23/2018-07-23 }, Term{ id=792bf365-eca4-460b-afad-c5cf62cf9a29 | dateRange=2018-01-23/2018-12-23 }]
abuts
If your Term objects should run up against one another in succession, you can test for that using the LocalDateRange::abuts method.
The approach in comparing is Half-Open, where the beginning is inclusive while the ending is exclusive. So a year starts on the first of the year and runs up to, but does not include, the first of the following year. You show this in your examples in the Question.
I assume the question is not just about sorting, but also about splitting overlapping intervals into smaller segments. You have to play a lot with Interval Arithmetic.
With Java 8 you can start by encoding your 'terms' as a time Interval, which in itself is Comparable. The second part would be to split your intervals into multiple ones if the user specifies overlapping ones.
class Interval implements Comparable<Interval> {
private final LocalDateTime start;
private final LocalDateTime end;
public Interval(LocalDateTime start, LocalDateTime end) {
this.start = start;
this.end = end;
}
public int compareTo(Interval that) {
return this.start.compareTo(that.start);
}
public boolean overlaps(Interval that) {
return !this.isBefore(that) && !this.isAfter(that);
}
public boolean contains(Interval that) {
return this.start.isBefore(that.start) && this.end.isAfter(that.end);
}
public boolean isBefore(Interval that) {
return this.end.isBefore(that.start);
}
public boolean isAfter(Interval that) {
return this.start.isAfter(that.end);
}
public Set<Interval> fragment(Interval that) {
if (that.start.isBefore(this.start)) {
return that.fragment(this);
}
Set<Interval> result = new HashSet<>();
if (this.end.isBefore(that.start)) {
result.add(this);
result.add(that);
result.add(new Interval(this.end, that.start));
} else if ((this.end.isAfter(that.start) && this.end.isBefore(that.end)) {
result.add(new Interval(this.start, that.start);
result.add(new Interval(that.start, this.end);
result.add(new Interval(this.end, that.end));
} else if (this.end.isAfter(that.end)) {
result.add(new Interval(this.start, that.start);
result.add(new Interval(that);
result.add(new Interval(that.end, this.end));
}
}
}
You can now keep them sorted, since Intervals are comparable by start date.
Whenever the user enters a new Interval (term) you have to go through the list and checks whether it contains() the existent interval, or whether it comes before it, with isBefore() or isAfter(). If it overlaps() you have to be careful if to also check whether it overlaps with the next interval in the list.
You can then call fragment() which will combine the 2 intervals together into smaller ones. You need to be careful to remove the previous ones. So maybe makes sense to just go through the list and check if they overlap or not. If you reach the end you can still use fragment() to combine two disjoint intervals.
I am struggling as newby with collecting solutions in java. The problem entails a mixed-integer linear problem in which i have to collect multiple solutions. I use gurobi for the optimalisation and we should get multiple solutions for the decision variables. I am using the Solutioncollection that is given below for this. In the solution class the solution is retrieved and makes it possible to set an objective value. My question is how do i get different values for the decision variables. Till now I have the following code in the optimizer and the solution collection below:
CLSPSolutionCollection collection = new CLSPSolutionCollection ();
CLSPSolution sol = new CLSPSolution (K,T);
model.optimize();
// 6. determine production quantities, setups and overtime ----------------------------------------------------------
if (model.get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) {
int s = model.get(GRB.IntAttr.SolCount);
model.set(GRB.IntParam.SolutionNumber, s);
sol.setObjectiveValue((int) model.get(GRB.DoubleAttr.ObjNVal)); // produce result
for (int k = 0; k < K; k++) {
for (int t = 0; t < T; t++) {
sol.setProductionQuantity(k, t, q[k][t].get(GRB.DoubleAttr.Xn)); // set decision variable q
sol.setSetupDecision(k, t, gamma[k][t].get(GRB.DoubleAttr.Xn)); // set decision variable Q
sol.setOvertimeDecision(t, beta[t].get(GRB.DoubleAttr.Xn)); // set decision variable Q
//collection.add();
}}
}
// if
// clean up ---------------------------------------------------------------------------------------------------------
model.dispose();
env.dispose();
} catch ( GRBException e){
e.printStackTrace();
} // catcher in the rye
return collection;
// COLLECTION CLASS
public class CLSPSolutionCollection {
private ArrayList<CLSPSolution> solutions;
public CLSPSolutionCollection ( ) {
// TODO
} // constructor
//TODO ..
public void add ( CLSPSolution solution ) {
solutions.add(solution);
} // add
public int size ( ) {
return solutions.size();
} // size
public CLSPSolution get ( int index ) {
return solutions.get(index);
} // get
} // CLSPSolutionCollection
I have a set of ints whose input I'd like to restrict. I would like it to behave something like the following:
# RestrictedIntSet.add 15 (RestrictedIntSet.make 0 10)
Exception: 15 out of acceptable range [0 .. 10]
How can I implement this? In Java, it could look something like:
Set<Integer> restrictedSet = new HashSet<Integer>() {
public boolean add(Integer i) {
if (i < lowerBound || i > upperBound) {
throw new IllegalArgumentException("out of bounds");
}
return super.add(i);
}
Or, to be less abusing of inheritance:
public class RestrictedSet {
private int lowerBound;
private int upperBound;
private Set elems = Sets.newHashSet();
public RestrictedSet(int lowerBound, int upperBound) {
this.lowerBound = lowerBound;
this.upperBound = upperBound;
}
public boolean add(Integer i) {
if (i < lowerBound || i > upperBound) {
throw new IllegalArgumentException("out of bounds");
}
return elems.add(i);
}
/* fill in other forwarded Set calls as needed */
}
What is the equivalent, idiomatic way to do this in OCaml?
Well, it depends, which set library are you using?
Using the Set module of the standard library, you could do the following:
module type RestrictedOrderedType = sig
type t
val compare : t -> t -> int
val lower_bound : t
val upper_bound : t
end
module RestrictedSet (Elem : RestrictedOrderedType) = struct
include Set.Make(Elem)
exception Not_in_range of Elem.t
let check e =
if Elem.compare e Elem.lower_bound < 0
|| Elem.compare e Elem.upper_bound > 0
then raise (Not_in_range e)
else e
(* redefine a new 'add' in term of the one in Set.Make(Elem) *)
let add e s = add (check e) s
let singleton e = singleton (check e)
end
(* test *)
module MySet = RestrictedSet(struct
type t = int
let compare = compare
let lower_bound = 0
let upper_bound = 10
end)
let test1 = MySet.singleton 3
let test2 = MySet.add (-3) test1
(* Exception: Not_in_range (-3) *)
I like #gasches's answer.
As a short complement: OCaml's Set module is designed to be instantiated by an OrderedType module, which means you cannot directly use OCaml's native ints directly.
One thus needs to use a module that complies with the requested signature. gasche's definition of a RestrictedOrderedType signature does this and elegantly includes the lower and upper bound fields. A rougher approach would be to use OCaml's Int32 or Int64 modules, which conform to the requested OrderedType signature, and hard-code the bounds in the MySet module.
Below is a slight reformulation of gasche's example to illustrate this point.
module MySet = struct
include Set.Make(Int32)
exception Not_in_range of Int32.t
let lower_bound = Int32.of_int 5
let upper_bound = Int32.of_int 10
let add elt set =
if (elt < lower_bound)||(elt > upper_bound)
then raise (Not_in_range elt)
else add elt set
end;;
I have a 32-bit Java service with scalability problems: with high user count we run out of memory because of excessive thread count. In the long term, I plan to switch to 64-bit and to reduce the threads-per-user ratio. In the short term, I'd like to reduce the stack size (-Xss, -XX:ThreadStackSize) to get some more headroom. But this is risky because if I make it too small, I'm going to get StackOverflowErrors.
How can I measure the average and maximum stack size for my application to guide my decision for an optimal -Xss value? I'm interested in two possible approaches:
Measuring a running JVM during integration testing. What profiling tools will report max stack depth?
Static analysis of the application looking for deep call hierarchies. Reflection in dependency injection makes it unlikely that this would work.
Update: I know the long-term right way to fix this problem. Please focus on the question I've asked: how do I measure stack depth?
Update 2: I got a nice answer on a related question specifically about JProfiler: Can JProfiler measure stack depth? (I posted the separate question as per JProfiler's community support recommendations)
You can get an idea of the stack depth with something like an aspect that can be woven to your code (load time weaver to allow advising all loaded code except system class loader). The aspect would work around all executed code and would be able to note when you are calling a method and when you return. You can use this to capture most of your stack usage (you'll miss anything loaded from the system class loader, e.g. java.*). While not perfect, it avoids having to change your code to gather StackTraceElement[] at sample points and also gets you into non-jdk code that you might not have written.
For example (aspectj):
public aspect CallStackAdvice {
pointcut allMethods() : execution(* *(..)) && !within(CallStackLog);
Object around(): allMethods(){
String called = thisJoinPoint.getSignature ().toLongString ();
CallStackLog.calling ( called );
try {
return proceed();
} finally {
CallStackLog.exiting ( called );
}
}
}
public class CallStackLog {
private CallStackLog () {}
private static ThreadLocal<ArrayDeque<String>> curStack =
new ThreadLocal<ArrayDeque<String>> () {
#Override
protected ArrayDeque<String> initialValue () {
return new ArrayDeque<String> ();
}
};
private static ThreadLocal<Boolean> ascending =
new ThreadLocal<Boolean> () {
#Override
protected Boolean initialValue () {
return true;
}
};
private static ConcurrentHashMap<Integer, ArrayDeque<String>> stacks =
new ConcurrentHashMap<Integer, ArrayDeque<String>> ();
public static void calling ( String signature ) {
ascending.set ( true );
curStack.get ().push ( signature.intern () );
}
public static void exiting ( String signature ) {
ArrayDeque<String> cur = curStack.get ();
if ( ascending.get () ) {
ArrayDeque<String> clon = cur.clone ();
stacks.put ( hash ( clon ), clon );
}
cur.pop ();
ascending.set ( false );
}
public static Integer hash ( ArrayDeque<String> a ) {
//simplistic and wrong but ok for example
int h = 0;
for ( String s : a ) {
h += ( 31 * s.hashCode () );
}
return h;
}
public static void dumpStacks(){
//implement something to print or retrieve or use stacks
}
}
And a sample stack might be like:
net.sourceforge.jtds.jdbc.TdsCore net.sourceforge.jtds.jdbc.JtdsStatement.getTds()
public boolean net.sourceforge.jtds.jdbc.JtdsResultSet.next()
public void net.sourceforge.jtds.jdbc.JtdsResultSet.close()
public java.sql.Connection net.sourceforge.jtds.jdbc.Driver.connect(java.lang.String, java.util.Properties)
public void phil.RandomStackGen.MyRunnable.run()
Very slow and has its own memory issues but can be workable to get you the stack information you need.
You can then use the max_stack and max_locals for each method in your stack traces to compute a frame size (see class file format) for the method. Based on the vm spec I believe this should be (max_stack+max_locals)*4bytes for the max frame size for a method (long/double occupy two entries on the operand stack/local vars and is accounted for in max_stack and max_locals).
You can easily javap the classes of interest and see the frame values if you don't have that much in your call stacks. And something like asm provides you with some easy tools to use to do this on a larger scale.
Once you have this computed, you need to estimate additional stack frames for JDK classes that might be called by you at your max stack points and add that to your stack sizes. It wont be perfect but it ought to get you a decent starting point for -Xss tuning without hacking around the JVM/JDK.
One other note: I don't know what JIT/OSR does to frame sizes or stack requirements so do be aware that you may have different impacts from -Xss tuning on a cold vs. warm JVM.
EDIT had a few hours of down time and threw together another approach. This is a java agent that will instrument methods to keep track of a max stack frame size and stack depth. This will be able to instrument most of the jdk classes along with your other code and libraries, giving you better results than the aspect weaver. You need asm v4 for this to work. It was more for the fun of it so file this under plinking java for fun, not profit.
First, make something to track the stack frame size and depth:
package phil.agent;
public class MaxStackLog {
private static ThreadLocal<Integer> curStackSize =
new ThreadLocal<Integer> () {
#Override
protected Integer initialValue () {
return 0;
}
};
private static ThreadLocal<Integer> curStackDepth =
new ThreadLocal<Integer> () {
#Override
protected Integer initialValue () {
return 0;
}
};
private static ThreadLocal<Boolean> ascending =
new ThreadLocal<Boolean> () {
#Override
protected Boolean initialValue () {
return true;
}
};
private static ConcurrentHashMap<Long, Integer> maxSizes =
new ConcurrentHashMap<Long, Integer> ();
private static ConcurrentHashMap<Long, Integer> maxDepth =
new ConcurrentHashMap<Long, Integer> ();
private MaxStackLog () { }
public static void enter ( int frameSize ) {
ascending.set ( true );
curStackSize.set ( curStackSize.get () + frameSize );
curStackDepth.set ( curStackDepth.get () + 1 );
}
public static void exit ( int frameSize ) {
int cur = curStackSize.get ();
int curDepth = curStackDepth.get ();
if ( ascending.get () ) {
long id = Thread.currentThread ().getId ();
Integer max = maxSizes.get ( id );
if ( max == null || cur > max ) {
maxSizes.put ( id, cur );
}
max = maxDepth.get ( id );
if ( max == null || curDepth > max ) {
maxDepth.put ( id, curDepth );
}
}
ascending.set ( false );
curStackSize.set ( cur - frameSize );
curStackDepth.set ( curDepth - 1 );
}
public static void dumpMax () {
int max = 0;
for ( int i : maxSizes.values () ) {
max = Math.max ( i, max );
}
System.out.println ( "Max stack frame size accummulated: " + max );
max = 0;
for ( int i : maxDepth.values () ) {
max = Math.max ( i, max );
}
System.out.println ( "Max stack depth: " + max );
}
}
Next, make the java agent:
package phil.agent;
public class Agent {
public static void premain ( String agentArguments, Instrumentation ins ) {
try {
ins.appendToBootstrapClassLoaderSearch (
new JarFile (
new File ( "path/to/Agent.jar" ) ) );
} catch ( IOException e ) {
e.printStackTrace ();
}
ins.addTransformer ( new Transformer (), true );
Class<?>[] classes = ins.getAllLoadedClasses ();
int len = classes.length;
for ( int i = 0; i < len; i++ ) {
Class<?> clazz = classes[i];
String name = clazz != null ? clazz.getCanonicalName () : null;
try {
if ( name != null && !clazz.isArray () && !clazz.isPrimitive ()
&& !clazz.isInterface ()
&& !name.equals ( "java.lang.Long" )
&& !name.equals ( "java.lang.Boolean" )
&& !name.equals ( "java.lang.Integer" )
&& !name.equals ( "java.lang.Double" )
&& !name.equals ( "java.lang.Float" )
&& !name.equals ( "java.lang.Number" )
&& !name.equals ( "java.lang.Class" )
&& !name.equals ( "java.lang.Byte" )
&& !name.equals ( "java.lang.Void" )
&& !name.equals ( "java.lang.Short" )
&& !name.equals ( "java.lang.System" )
&& !name.equals ( "java.lang.Runtime" )
&& !name.equals ( "java.lang.Compiler" )
&& !name.equals ( "java.lang.StackTraceElement" )
&& !name.startsWith ( "java.lang.ThreadLocal" )
&& !name.startsWith ( "sun." )
&& !name.startsWith ( "java.security." )
&& !name.startsWith ( "java.lang.ref." )
&& !name.startsWith ( "java.lang.ClassLoader" )
&& !name.startsWith ( "java.util.concurrent.atomic" )
&& !name.startsWith ( "java.util.concurrent.ConcurrentHashMap" )
&& !name.startsWith ( "java.util.concurrent.locks." )
&& !name.startsWith ( "phil.agent." ) ) {
ins.retransformClasses ( clazz );
}
} catch ( Throwable e ) {
System.err.println ( "Cant modify: " + name );
}
}
Runtime.getRuntime ().addShutdownHook ( new Thread () {
#Override
public void run () {
MaxStackLog.dumpMax ();
}
} );
}
}
The agent class has the premain hook for instrumentation. In that hook, it adds a class transformer that instruments in the stack frame size tracking. It also adds the agent to the boot class loader so that it can process jdk classes, too. To do that, we need to retransform anything that might be loaded already, like String.class. But, we have to exclude a variety of things that are used by the agent or the stack logging which lead to infinite loops or other problems (some of that was found by trial and error). Finally, the agent adds a shutdown hook to dump the results to stdout.
public class Transformer implements ClassFileTransformer {
#Override
public byte[] transform ( ClassLoader loader,
String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer )
throws IllegalClassFormatException {
if ( className.startsWith ( "phil/agent" ) ) {
return classfileBuffer;
}
byte[] result = classfileBuffer;
ClassReader reader = new ClassReader ( classfileBuffer );
MaxStackClassVisitor maxCv = new MaxStackClassVisitor ( null );
reader.accept ( maxCv, ClassReader.SKIP_DEBUG );
ClassWriter writer = new ClassWriter ( ClassWriter.COMPUTE_FRAMES );
ClassVisitor visitor =
new CallStackClassVisitor ( writer, maxCv.frameMap, className );
reader.accept ( visitor, ClassReader.SKIP_DEBUG );
result = writer.toByteArray ();
return result;
}
}
The transformer drives two separate transformations - one to figure out the max stack frame size for each method and one to instrument the method for recording. It might be doable in a single pass but I didn't want to use the ASM tree API or spend more time figuring it out.
public class MaxStackClassVisitor extends ClassVisitor {
Map<String, Integer> frameMap = new HashMap<String, Integer> ();
public MaxStackClassVisitor ( ClassVisitor v ) {
super ( Opcodes.ASM4, v );
}
#Override
public MethodVisitor visitMethod ( int access, String name,
String desc, String signature,
String[] exceptions ) {
return new MaxStackMethodVisitor (
super.visitMethod ( access, name, desc, signature, exceptions ),
this, ( access + name + desc + signature ) );
}
}
public class MaxStackMethodVisitor extends MethodVisitor {
final MaxStackClassVisitor cv;
final String name;
public MaxStackMethodVisitor ( MethodVisitor mv,
MaxStackClassVisitor cv, String name ) {
super ( Opcodes.ASM4, mv );
this.cv = cv;
this.name = name;
}
#Override
public void visitMaxs ( int maxStack, int maxLocals ) {
cv.frameMap.put ( name, ( maxStack + maxLocals ) * 4 );
super.visitMaxs ( maxStack, maxLocals );
}
}
The MaxStack*Visitor classes handle figuring out the max stack frame size.
public class CallStackClassVisitor extends ClassVisitor {
final Map<String, Integer> frameSizes;
final String className;
public CallStackClassVisitor ( ClassVisitor v,
Map<String, Integer> frameSizes, String className ) {
super ( Opcodes.ASM4, v );
this.frameSizes = frameSizes;
this.className = className;
}
#Override
public MethodVisitor visitMethod ( int access, String name,
String desc, String signature, String[] exceptions ) {
MethodVisitor m = super.visitMethod ( access, name, desc,
signature, exceptions );
return new CallStackMethodVisitor ( m,
frameSizes.get ( access + name + desc + signature ) );
}
}
public class CallStackMethodVisitor extends MethodVisitor {
final int size;
public CallStackMethodVisitor ( MethodVisitor mv, int size ) {
super ( Opcodes.ASM4, mv );
this.size = size;
}
#Override
public void visitCode () {
visitIntInsn ( Opcodes.SIPUSH, size );
visitMethodInsn ( Opcodes.INVOKESTATIC, "phil/agent/MaxStackLog",
"enter", "(I)V" );
super.visitCode ();
}
#Override
public void visitInsn ( int inst ) {
switch ( inst ) {
case Opcodes.ARETURN:
case Opcodes.DRETURN:
case Opcodes.FRETURN:
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.RETURN:
case Opcodes.ATHROW:
visitIntInsn ( Opcodes.SIPUSH, size );
visitMethodInsn ( Opcodes.INVOKESTATIC,
"phil/agent/MaxStackLog", "exit", "(I)V" );
break;
default:
break;
}
super.visitInsn ( inst );
}
}
The CallStack*Visitor classes handle instrumenting methods with code to call the stack frame logging.
And then you need a MANIFEST.MF for the Agent.jar:
Manifest-Version: 1.0
Premain-Class: phil.agent.Agent
Boot-Class-Path: asm-all-4.0.jar
Can-Retransform-Classes: true
Finally, add the following to your java command line for the program you want to instrument:
-javaagent:path/to/Agent.jar
You will also need to have the asm-all-4.0.jar in the same directory as the Agent.jar (or change Boot-Class-Path in the manifest to reference the location).
A sample output might be:
Max stack frame size accummulated: 44140
Max stack depth: 1004
This is all a bit crude but works for me to get going.
Note: the stack frame size isn't a total stack size (still don't really know how to get that one). In practice, there are a variety of overheads for the thread stack. I found that I usually needed between 2 and 3 times the reported stack max frame size as a -Xss value. Oh, and be sure to do the -Xss tuning without the agent loaded as it adds to your stack size requirements.
I would reduce the -Xss setting in a test environment until you see a problem. Then add some head room.
Reducing your heap size would give your application more space for thread stacks.
Just switching to a 64-bit OS could give your application more memory as most 32-bit OSes only allow about 1.5 GB for each application, however a 32-bit application on a 64-bit OS can use up to 3-3.5 GB depending on the OS.
There is no readily usable tooling in the Java VM to query the stack depth in bytes. But you can get there. Here are some pointers:
Exceptions contain arrays of stack frames which gives you the methods which were called.
For each method, you can find the Code attribute in the .class file. This attribute contains the frame size per method in the field max_stack.
So what you need is a tool that compiles a HashMap which contains method name + file name + line number as keys and the value max_stack as values. Create an Throwable, fetch the stack frames from it with getStackTrace() and then iterate over the StackTraceElements.
Note:
Each entry on the operand stack can hold a value of any Java virtual machine type, including a value of type long or type double.
So each stack entry is probably 64bits, so you need to multiply max_stack with 8 to get bytes.
This is kind of a design-patterns question in Java.
I am designing a java .jar file to act as a frameworks for managing and processing a certain form of data. I want the end user to be able to dictate the "plumbing" configuration, within certain constraints, in a certain way. The pieces are producers and/or consumers, and I know how to implement them, but the connections are confusing to me... here's a nonsense example that sort of parallels my application.
Suppose I have implemented these elements:
AppleTree => produces apples
ApplePieMaker => consumes apples,
produces apple pies
ApplePress =>
consumes apples, produces apple cider
AppleSave => stores apples,
apple pies, or apple cider into a
file
AppleLoad => "reconstitutes" apples, apple pies, or apple cider from a file that was produced by AppleSave
ApplePieMonitor => displays apple pies on the screen in a GUI format, as they are produced
Now I want the user to be able to specify things like:
AppleTree | ApplePress | AppleSave cider1.sav (produce apples, make them into cider, save them to a file)
AppleTree | AppleSave apple1.sav (produce apples, save them to a file)
AppleLoad apple1.sav | ApplePieMaker | ApplePieMonitor (take saved apples, make them into pies, display the results on the screen in a GUI)
(not sure how to illustrate this, but might be specified as follows)
AppleTree tree1, ApplePieMaker piemaker1 < tree1, AppleSave apples.sav < tree1, AppleSave #select(*.sav) < piemaker1, ApplePress press1 < tree1, AppleSave cider.sav < press1, ApplePieMonitor piemon1 < piemaker1
(produce apples, make them into pies and cider, save the apples, pies and cider to separate files, with the pies going to a file selected by the user at runtime and the others going to predetermine files, and also display the pies on the screen in a GUI)
So I have a rough idea of how to architect a configuration file: namely to structure the thing into elements that have at most 1 input and at most 1 output, and then for each instantiated element, name it, and if it has an input, specify the name of the element providing the input.
What I'm unclear is how to go about coupling the elements of the program when they run. Maybe the way to go is to have a number of interfaces, like AppleConsumer, ApplePieConsumer, etc. so an ApplePieMaker would implement the AppleConsumer interface (incl. method consumeApple()), and an AppleTree would implement an AppleProducer interface which can register consumers at startup, so that every time the AppleTree produces an apple, it has a list of its consumers and calls consumeApple() on each of them, which then does the right thing without the AppleTree having to know what they are doing with the apples....
Any suggestions? Does this sort of thing have a name? I'm not really that experienced in design patterns.
edit: my end users don't know and don't care about Java. They just need to be able to set up a config file (which I'm trying to make as simple as possible so I can give them some good examples) and run my program which will read the config file, construct the elements, hook them together, and go. All the elements are under my control, I don't need to support plugins, so I don't have to be super-general.
I had that problem a while ago, and it was a bit hard to specify cleanly in Java, since my input and output could be plural. However, when you are sure to have a single input and output (since a file is a specific kind of output, right?), you could try to use checked generics.
A processing step implementation (I will call that a filter) has two checked type arguments: input and output (lets for instance suppose they all extend a common interface, and for every new type you inject in the system, you will subclass that interface).
public interface Filter<Input extends Type, Output extends Type> {
public Class<Input> getInputType();
public Class<Output> getOutputType();
public void process(Input in, Output out);
}
A filter chain is then just an array of (compatible) Filters. By compatible, I intend that for each filter, its Output is the same type as its follower Input, the first filter has an Input that match your overall input type, and the last filter has an Output that matches the expected result type. This is easy to validate, in practice, since we are using checked generics.
A filter chain is thus an other (compound) filter. The compatibility of compounded filters should be checked in the constructor, and the array of compounds final. There is no accurate way to express the "chaining" property (compatibility) of the arguments of that constructors with generics, so you are going to have to do that with bare types, which is a bit unclean.
An other way to do it that gets around this limitation, at the cost of more cumbersome writing, is to change the definition of a filter like this:
public interface Filter<Input extends Type, Output extends Type> {
public Class<Input> getInputType();
public Class<Output> getOutputType();
public Output out process(Input in);
}
We will then have to define a compound filter as an imbrication of filter pairs, thus defined:
public class CompoundFilter<Input extends Type, Output extends Type>
implements Filter<Input extends Type, Output extends Type> {
private final Filter<Input extends Type, ? extends Type> l;
private final Filter<Input extends Type, ? extends Type> r;
public <Median extends Type> CompoundFilter(
Filter<Input, Median> r,
Filter<Median, Output> l
) {
this.l = l;
this.r = r;
}
#SuppressWarnings("unchecked")
public Output out process(Input in) {
// Compute l(r(in)) = (l o r) (in)
return ((Output<Input,Type>) l).process(r.process(in));
}
}
Thus, composing filters is just a matter of writing:
Filter<A,B> f1 = new FilterImpl<A,B>;;
Filter<B,C> f2 = new FilterImpl<B,C>;
// this is mathematically f2 o f1
Filter<A,C> comp = new CompoundFilter<A,C>(f1,f2);
I could not help it, I have to workout something for this.
So here it is.
You already have the idea about the apple producer/consumer so this is how I would do it.
Create three interfaces and implement as follows:
Product - Either Apple, AppleCider, ApplePie,
Producer - AppleTree, ApplePress, ApplePieMaker, AppleLoad,
Consumer - ApplePress ( consumes Apples ), ApplePieMaker ( consumes Apples ) , AppleMonitor, AppleSave.
The idea is to have a generic Product, produced by generic Producers and consumed by generic Consumers.
Once you have that, you can create the configuration file pretty much the way you describe it, and parse it to create a new instance for each element.
element1 | element2 | element3 <parameters> | element 4
In a map you create the element name and map it to the class that will create the new instance.
Let's say
map.put( "AppleTree", YouAppleTreeClass.class );
So each time you read an element in the configuration you create the instance:
for( String item: line ) {
Object o = map.get( item ).newInstance();
}
Finally you have to validate the structure of your configuration, but basically it could be like this:
The first element should be a producer
The last should be a consumer
Any intermediate should be producer-consumers
You can parse arguments needed ( file to save data for instance )
Once you have all your objects created and chained, you start producing.
There are some thing you have to workout but they're pretty easy:
Argument passing ( the file where they will be saved/loaded from)
Object re-use in different configurations ( use the same AppleTree always )
Final notes: The following code, is just an scratch, you may really consider a dependency injector to do the job, but of course it will take you a little while to learn it.
The configuration parsing should be made by hand, for the format you're using will be unique for the end-user and should be pretty simple. Still you can deliver as much complexity you want inside your jar ( using any number of frameworks you need ).
You can also take a look to the following design patterns:
Composite
Observer
Interpreter
The implementation below, is a kind of monster the these three ( I didn't compile it, just throw some code to show how the idea would look like )
I hope this helps.
/**
* Anything. An apple, cider, pie, whatever.
*/
interface Product{}
// The kinds of products.
class Apple implements Product{}
class ApplePies implements Product{}
class AppleCider implements Product{}
/**
* This indicates the class will do something.
**/
interface Producer {
// adds a consumer to the list.
public void addConsumer( Consumer c );
// removes the consumer from the list.
public void removeConsumer( Consumer c );
// let know eveytone a product has been created.
public void notifyProductCreation( Product someProduct );
// You're producer? Produce then...
public void startProduction();
}
// To avoid copy/paste all around
class AbstractProducer implements Producer {
private List<Consumer> consumers = new ArrayList<Consumer>();
// adds a consumer to the list.
public void addConsumer( Consumer c ) {
consumers.add( c );
}
// removes the consumer from the list.
public void removeConsumer( Consumer c ) {
consumers.remove( c );
}
public void notifyProductCreation( Product someProduct ) {
for( Consumer c : list ) {
c.productCreated( someProduct );
}
}
}
interface Consumer {
// Callback to know a product was created
public void productCreated( Product p );
}
class AppleTree extends AbstractProducer {
public void startProduction() {
// do something with earh, sun, water..
// and from time to time:
Product ofThisNewApple = new Apple();
notifyProductCreation( ofThisNewApple );
}
}
class ApplePieMaker extends AbstractProducer implements Consumer {
// Ok, a product was created, but
// is it the product I care?
// check first and consume after.
public void productCreated( Product p ){
// Is this the kind of product I can handle..
// well do handle
if( p instanceof Apple ) {
/// start producing pies..
}
}
public void startProduction() {
// collect the needed number of apples and then...
Product ofPie = new ApplePie();
notifyProductCreation( ofPie );
}
}
class ApplePress extends AbstractProducer implements Consumer {
// Yeap, something gots produced.
// Just handle if it is an apple
public void productCreated( Product p ) {
if( p instanceof Apple ) {
// start producing cider
}
}
public void startProduction() {
// collect the needed number of apples and then...
Product ofCiderBottle = new AppleCider();
notifyProductCreation( ofCiderBottle );
}
}
class AppleSave implements Consumer {
public void productCreated( Product p ) {
file.append( p );// any one will do.
}
}
class AppleLoad extends AbstractProducer {
public void startProduction() {
readFromFile();
}
private readFromFile() {
for( Product p : file ) {
notifyProductCreation( p );
}
}
}
class Main {
public static void main( String [] args ) {
Configuration conf = new Configuration();
List<Producer> producers conf.read();
for( Producer p : producers ) {
// fasten your seat belts....
p.startProduction();
}
}
}
/// Ahhh, pretty ugly code below this line.
// the idea is:
// Read the configuration file
// for each line split in the "|"
// for each element create a new instance
// and chain it with the next.
// producer | consumer | etc...
// Becomes....
// new Producer().addConsumer( new Consumer() );
// Return the list of create producers.
class Configuration {
List<Producer> producers
// read the file
// create the instances
// let them run.
public List<Producer> read() {
File file = new File(....
// The format is:
// producer | consumer-producer <params> | consumer
String line = uniqueLineFrom( file );
String [] parts = line.split("|");
if( parts.length == 1 ) {
System.err.println("Invalid configuration. use element | element | etc. Only one element was....");
System.exit( 1 );
}
int length = parts.length;
for( int i = 0 ; i < parts.length ; i++ ) {
Object theInstance = implementationMap.get( parts[i] ).newInstance();
validatePosition( i, length, theInstance , parts[i] );
}
List<Producer> producers = new ArrayList<Producer>();
for( int i = 0 ; i < parts.length ; i++ ) {
Object theInstance = getInstance( parts[i] );
if( not( isLast( i, length ) && isProducer( theInstance ) ) {
// the next is its consumer
Producer producer = ( Producer ) theInstance;
producer.addConsumer( ( Consumer ) getInstance( parts[i+1] ));
producers.add( producer );
}
}
return producers;
}
// creates a new instance from the implementation map.
private Object getInstance( String key ) {
return implementationMap.get( part[i] ).newInstance();
}
// validates if an element at the given position is valid or not.
// if not, prints the message and exit.
// the first element most be a producer
// the last one a consumer
// all the middle elements producer-consumer
//
private void validatePosition( int i, int length, Object theInstance, String element ) {
if( isFirst( i ) && not(isProducer(( theInstance ) ))) {
System.err.println( "Invalid configuration: " + element + " most be a producer ( either Ap...");
System.exit( 2 );
} else if ( isLast( i, length ) && not( isConsumer( theInstance ))) {
System.err.println( "Invalid configuration: " + element + " most be a consumer ( either Ap...");
System.exit( 3 );
} else if ( isMiddleAndInvalid( i, length , instance ) ) {
System.err.println( "Invalid configuration: " + element + " most be a producer-consumer ( either Ap...");
System.exit( 4 );
}
}
private static Map<String,Class> implementationMap = new HashMap<String,Class>() static {
implementationMap.put( "AppleTree", AppleTree.class );
implementationMap.put( "ApplePieMaker ", ApplePieMaker .class );
implementationMap.put( "ApplePress", ApplePress.class );
implementationMap.put( "AppleSave", AppleSave.class );
implementationMap.put( "AppleLoad", AppleLoad.class );
implementationMap.put( "ApplePieMonitor", ApplePieMonitor.class );
};
// Utility methods to read better ( hopefully ) the statements
// If you could read the validations above you may ignore these functions.
private boolean not( boolean value ) {
return !value;
}
private boolean isFirst( int i ) {
return i == 0;
}
private boolean isLast( int i, int l ) {
return i == l -1 ;
}
private boolean isProducer( Object o ) {
return o instanceof Producer;
}
private boolean isConsumer( Object o ) {
return o instanceof Consumer;
}
private boolean isMiddleAndInvalid( int index, int length, Object instance ) {
return not( isFirst( index ) ) && not( isLast( index, length ) ) && not( isProducer( instance ) && isConsumer( instance ));
}
}
I believe what you are trying to do can be done within the Spring framework. It uses dependency injection to say "In order to create X I need Y, so find something that produces Y and see what you need in order to create it".
I may be wrong, but I suggest you have a look.
You would need some sort of Registry where producers could register (Hi, I'm an apple tree and I produce apples) and then the consumers could look up whom ever produces apples. This could also be done in reverse where the consumers register interest and the producers look up. I did something similar using JMX where an Object could query the JMX Server for an Object that produced a certain type of Message and then register with that Object (Publish/Subscribe). I am now porting that app to use OSGi which has a similar capability
Try the Java Beanshell.
BeanShell is a small, free, embeddable Java source interpreter with object scripting language features, written in Java. BeanShell dynamically executes standard Java syntax and extends it with common scripting conveniences such as loose types, commands, and method closures like those in Perl and JavaScript.