My program has the following structure:
void main (String[] args) {
Object largeObject = longInitialization();
interestingLogic(largeObject);
}
The longInitialization code never changes during development. BUt whenever I change the interestingLogic, I have to run the program again and wait for the longInitialization to complete.
Unfortunately I cannot serialize largeObject because it is not Serializable and I don't have the code to it.
Is there a trick by which I can save the initialization time? Maybe, in some way save the state of the JVM just after initialization, and then always start from that state?
You can make little modification of code:
main(){
Object largeObject = longInitialization();
boolean debug = true;
while(debug){
interestingLogic(largeObject);
}
}
now run program in debug mode. Set breakpoint at interestingLogic call and use code hotswap debug mode in IDE. read more about hotswap in Eclipe: Java Hotswap with Eclipses and Remote Debugging on Local Machine
//Edit:
One more option. Just write mock of largeObject.
You will need a new object to call interestingLogic(largeObject). You can make changes to the new object while the driver program is waiting for user input.
void main (String[] args) {
Object largeObject = longInitialization();
boolean anotherTry = true;
String answer = "";
Scanner input = new Scanner(System.in);
while (anotherTry) {
Object newobject = NewObject();
newobject.interestingLogic(largeObject).
System.out.print("Run Again Y/N");
answer = input.nextLine();
if (answer.equalsIgnoreCase("N")) {
anotherTry = false;
}
}
}
If the large object is not needed immediately, you could decorate it with a "lazy initializing" wrapper, and invoke the "longInitialization" just before you want to access it.
A second solution could be "cloning" it by marshalling/unmarshalling it to an xml file
Because you said "...cannot serialize largeObject..." there is no way to persist an object across JVM lifetimes (since you don't have the source). But, you have code that initializes/uses the largeOject. Create a serializable debugLargeObject that acts like the real largeObject and use debugLargeObject during development.
Not without a lot of work. You need a minor refactor, as shown by Guido, then you need to reload the NewObject class each time through the loop (or whatever). In other words, your VM needs to be able to remove the NewObject class, then reload it, each time you change the code.
There are commercial products which do this (see JRebel, for example). You can roll your own (see this StackOverflow topic: Unloading classes in java?). You can hotswap, if you're very careful about your interestingLogic. But ultimately, you need to swap out that class somehow.
Related
I've been playing around with the jdk.incubator.foreign stuff in JDK-18. It's pretty nice. WAY faster than JNI. An order of magnitude faster. The foreign memory stuff is better (and maybe slightly faster) than the UNSAFE stuff. Can't wait for this to ship.
One thing I can't figure out: How to upCall to a non-static JVM function?
If I can't, how do I pass some context down and back so I can cast the context into the correct instance/type in the java static function? In java how do you create a ValueLayout.ADDRESS from this? And vice-versa?
The only way I can figure out how to do it is to keep a list of instantiated classes, and round-trip the index in the list. Which seems like a hack.
Maybe the JVM reserves the right to move JVM memory around without restriction whenever it feels like it, so maybe it's not possible? If so, what is the recommended pattern for this?
--- edit - Add code example ---
public class RoundTripExample {
private String name;
RoundTripExample(String _name) {
this.name = _name;
}
public void callback() {
System.out.println("Called from native"+name);
}
public static void main(String[] args) throws Throwable {
var fName = new File("../zig/zig-out/lib/libnativeFuncs.so").getCanonicalFile();
System.load(fName.toString());
var instance =new RoundTripExample("round trip name");
CLinker link = CLinker.systemCLinker();
SymbolLookup symLook = SymbolLookup.loaderLookup();
ResourceScope scope = ResourceScope.newSharedScope();
var nativeFunc = link.downcallHandle(
symLook.lookup("zigCallTest").get(),
FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS)
);
var handle =
MethodHandles.lookup().findVirtual(
RoundTripExample.class,
"callback",
MethodType.methodType(void.class)
);
handle.bindTo(instance);
var upcall = link.upcallStub(
handle,
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS),
ZigStubs.scope
);
nativeFunc.invoke(upcall);
}
}
Assuming this is the way to do it, the problem is creating the upCall handle. You can only pass it a handle to functions that take LONG, INT, ADDRESS, etc. An instance of a class isn't any of those.
If the context you need to pass is constant for the target function, you could bind it to the target method handle using MethodHandles.insertArguments and then use the resulting method handle to create an upcall stub.
If the context is not constant for the target function, then your idea of using a list and passing around the index to the object you want is a pretty good way to go. This is essentially a way to turn an object into an integer, by inserting it into the list, and then back into an object by looking it up in the list again.
There's no safe way of turning an object into a plain native address, since, as you say, the object might be move by the JVM.
In the example, using bindTo looks feasible. In this case you've forgotten to assign the result of bindTo:
handle = handle.bindTo(instance);
Additionally, you'd have to drop the address argument passed from native code, as it looks like it's not being used by your Java code:
handle = MethodHandles.dropArguments(handle, 0, MemoryAddress.class);
var upcall = link.upcallStub(
handle,
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS),
ZigStubs.scope
);
I want to see how many objects are created by Java when I run my program.
My intention is if I use the code String s = new String("Hi"); I want to see how many objects Java will create. Later I want to try with String news = "Hi";
This is my sample program:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
String str = new String("Hi");
Scanner s = new Scanner(System.in);
s.nextLine();
}
}
I am using Scanner just to avoid the program to terminate.
I have gone through this SO post How to find the number of objects in the heap and tried to use jvisualvm, but the tool is not giving the count of my objects created in my class. I also do not understand how to get the actual count of objects based on below image.
When I tried to use the command jmap -heap <pid> then I get below error:
Attaching to process ID 15101, please wait... Error attaching to
process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to
the process
If I use eclipse Debug as option, then I see that it is not the correct way to find out the number of objects that are being created.
If you look in your debugger you can see that
The String#437 object is the same in s1 s2 s3 but this refers to a char[2]#438 which is another object. Thus you have two objects.
In 2017 edition of Intellij idea there is a window named "Memory view" in debugger page.
The functionality is provided by a JVMTI (Tool Interface) agent at https://github.com/JetBrains/debugger-memory-agent.
I am having some strange trouble with the method await(Future future) of the Controller.
Whenever I add an await line anywhere in my code, some GenericModels which have nothing to do with where I placed await, start loading incorrectly and I can not access to any of their attributes.
The wierdest thing is that if I change something in another completely different java file anywhere in the project, play will try to recompile I guess and in that moment it starts working perfectly, until I clean tmp again.
When you use await in a controller it does bytecode enhancement to break a single method into two threads. This is pretty cool, but definitely one of the 'black magic' tricks of Play1. But, this is one place where Play often acts weird and requires a restart (or as you found, some code changing) - the other place it can act strange is when you change a Model class.
http://www.playframework.com/documentation/1.2.5/asynchronous#SuspendingHTTPrequests
To make it easier to deal with asynchronous code we have introduced
continuations. Continuations allow your code to be suspended and
resumed transparently. So you write your code in a very imperative
way, as:
public static void computeSomething() {
Promise delayedResult = veryLongComputation(…);
String result = await(delayedResult);
render(result); }
In fact here, your code will be executed in 2 steps, in 2 different hreads. But as you see it, it’s very
transparent for your application code.
Using await(…) and continuations, you could write a loop:
public static void loopWithoutBlocking() {
for(int i=0; i<=10; i++) {
Logger.info(i);
await("1s");
}
renderText("Loop finished"); }
And using only 1 thread (which is the default in development mode) to process requests, Play is able to
run concurrently these loops for several requests at the same time.
To respond to your comment:
public static void generatePDF(Long reportId) {
Promise<InputStream> pdf = new ReportAsPDFJob(report).now();
InputStream pdfStream = await(pdf);
renderBinary(pdfStream);
and ReportAsPDFJob is simply a play Job class with doJobWithResult overridden - so it returns the object. See http://www.playframework.com/documentation/1.2.5/jobs for more on jobs.
Calling job.now() returns a future/promise, which you can use like this: await(job.now())
I'm using JRules Studio to develop some extremely simple rules. The rules populate an IN_OUT parameter. When the test finishes, is there a way of interrogating the values in the IN_OUT object?
Initially I'd like to interrogate it in the debugger, but any other ideas would be welcomed.
I am not sure to understand the question:
Your JAVA code is like this:
IlrSessionFactory factory = new IlrJ2SESessionFactory();
IlrStatelessSession session = factory.createStatelessSession();
IlrSessionRequest sessionRequest = factory.createRequest();
sessionRequest.setRulesetPath(“/RuleAppName/rulesetName”);
sessionRequest.setTraceEnabled(true);
sessionRequest.getTraceFilter().setInfoAllFilters(true);
Map inputParameters = new HashMap ();
Report in_report = new Report(); // no-arg constructor
// ... populate the Object ...
inputParameters.put("report", in_report);
sessionRequest.setInputParameters(inputParameters);
IlrSessionResponse sessionResponse = session.execute(sessionRequest);
Report out_report = (Report)sessionResponse.getOutputParameters().get("report“);
And then you play with your "out" parameters... As you would do with any JAVA object
If you want to see them at debug time, I would say:
1/ (not tested) Have a look on the "working memory tab" in the debugger perspective
I am not sure but this is the easiest way to find them if it is visible here
2/ (tested) in the initial action of the starting point of your ruleflow, add:
context.insert(the technical name of your parameter);
Not the "business name". Anyway avoid using BAL in technical artifact such as ruleflow, IRL rules!
By doing this you force the engine to insert your parameter in the working memory.
No duplication (don't worry, it will work like a charm) but as far as I can remember this is the shortest way to make them visible in the Eclipse debugger in JRules
Hope it helps
I maintain an application which acts as a container for multiple individual programs. These programs have their own dedicated logging facility, i.e. everything they log does to a special log file.
Nevertheless, application developers seem to love to throw System.out.println and e.printStackTrace calls all over, making it impossible to maintain a clean console when running the container.
How can I prevent these applications from polluting System.out and System.err?
Implementation notes:
the applications use Log4j for logging;
the container also uses the console for logging, but it is strictly reserved for lifecycle events and problems, so I still need the console;
the applications are loaded using a custom classloader, but no security checks are applied.
Update:
Simply redirecting System.out would not work since it redirects all output, so something like this fails:
System.setOut(new PrintStream(new OutputStream() {
#Override
public void write(int b) {
throw new Error("Not on my watch you don't");
}
}));
Logger logger = Logger.getLogger(Runner.class);
logger.info("My log message");
This should succeed.
Update 2:
The applications are loaded and configured using code similar to
App app = new UrlClassLoader(...).loadClass(className)).newInstance();
app.setLogger(loggerForClass(app));
Log4j is loaded from the system class loader.
Assuming that you can control your containers output you can do the following:
import java.io.*;
public class SysOut {
public static void main(String[] args) throws Exception {
PrintStream pw = new PrintStream(new FileOutputStream("a.txt"));
PrintStream realout = System.out;
System.setOut(pw);
System.out.println("junk");
realout.print("useful");
}
}
$ java SysOut
useful
$ cat a.txt
junk
You can use System.setOut() and System.setErr() to redirect stdout and stderr to instances of PrintStream.
While Java defines a standard System.out and System.err, these can be overwritten with your own streams. See http://www.devx.com/tips/Tip/5616
Basically you can set up new streams that either pipe to the logging, or simply let data flop off into nothingness. My preference would be the latter, as it would instantly cure developers from relying on System.out and err as anything they write there just disappears.
**Update:
I just reread your stipulations in the question and see you still need the console for the container application. This might still work if you write a wrapper around the standard stream so you can check each call and see if it is coming from the parent application (and pass it on) or a child application (and block it)
Use aversion therapy. A visit from "The Inspectors" is scheduled whenever any code is checked in containing unpleasant constructs.
Nice cubicle you got ere, be shame if anyfing appened to it.
If you have a headless build mechanism, ant or such like then you could add CheckStyle to the build and configure checkstyle to fail the build if it finds any System.out.println or e.printStackTrace in the code.
If you don't have a headless build I would recommend that you build one as it means you have repeatable, predictable builds.
System.setOut will redirect all output - but the PrintStream you supply can decide how the output is handled. Thus I'm sure you could provide such a stream that would only actually print statements from your application.
The only tricky part really is being able to detect what's a valid call and what's not. A working, but likely very slow way to do this, would be to call Thread.currentThread().getStackTrace() and see what code (or package, at least) is calling you (simply returning if it's not a valid one). I wouldn't recommend this though as the performance hit would be staggering, especially doing this on every byte read.
A better idea might be to set a ThreadLocal flag in all of your valid, container threads. Then you can implement the PrintStream something like the following:
public class ThreadValidity extends ThreadLocal<Boolean>
{
private static final INSTANCE = new ThreadValidity();
#Override Boolean initialValue() { return false; }
public static ThreadValidity getInstance() { return INSTANCE; }
}
class VerifyingPrintStream extends PrintStream
{
private boolean isValidThread()
{
return ThreadValidity.instance().get();
}
public void println(String s)
{
if (!isValidThread()) return;
super.println(s);
}
public void println(Object o)
{
if (!isValidThread()) return;
super.println(o);
}
// etc
}
Alternatively, if you're able to change the printlns in the container code, things get easier. You can hand off all the console writes to a specific worker; and have this worker "steal" System.out (store it in its own field and use it directly for writing output) while setting the actual System.out to a no-op writer.
The key here is to configure log4j before redirecting the output streams, e.g.
BasicConfigurator.configure();
System.setOut(...);
System.setErr(...);
System.out.println("I fail");
Logger.getLogger(...).info("I work");
Convert the System.out and System.err streams to special implementations that throw a RuntimeException("Use logging instead of System.out") every time a character is written.
If your container is important, they will get the idea pretty quickly :)
(For extra bonus throw OutOfMemoryException instead ;-))
What I have done is redirect the PrintStream for System.out and System.err to commons-logging as INFO and ERROR level logging respectively.
This gets trickier if you want some threads to be able to write to the console or you want logs to go to the console as well but it can be done.
You can actually get and store System.out/err before replacing them.
OutputStream out=System.getOut(); // I think the names are right
System.setOut(some predefined output stream, null won't work);
out.println("Hey, this still goes to the output");
System.out.println("Oh noes, this does not");
I've used this to intercept all the System.out.println's in the codebase and prefix each line of output with the method name/line number it came from.
Close the System.out and System.err streams.
We use the log4j trick but log to separate files (stdout.log, stderr.log). It's not useful to have their output mixed in with the parts that actually understand logging...