I'm playing around with editing java.lang.Object for the Java Runtime Environment. I realize that there are probably better ways to do what I want, but that is not what my question is about.
Basically I've added a constructor to java.lang.Object which gets called everytime an object is created. I'm waiting for a certain class to load like so:
public Object() {
if (hookEnabled) {
hookEnabled = false;
objectCount++;
if (objectCount > objectStartCount) {
if (this.getClass() != null) {
String name = this.getClass().getName();
if ((!name.startsWith("java.")) && (!name.startsWith("javax.")) && (!name.startsWith("launcher.")) && (!name.startsWith("sunw.")) && (!name.startsWith("com.sun.")) && (!name.startsWith("sun.")) && (!name.startsWith("org.xml.")) && (!name.startsWith("org.w3c.")) && (!name.startsWith("org.omg.")) && (!name.startsWith("org.ietf."))) {
if (!hasHooked) {
hasHooked = true;
//startup beep
java.awt.Toolkit.getDefaultToolkit().beep();
//load interface
javax.swing.JFrame frame = new javax.swing.JFrame("");
frame.setBounds(0, 0, 400, 400);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
}
}
}
hookEnabled = true;
}
}
This works fine. It adds a window to whatever application is being run by the JVM.
However, when making a simple change by moving the JFrame code into a separate class, and calling that call the JVM simply crashes:
public Object() {
if (hookEnabled) {
hookEnabled = false;
objectCount++;
if (objectCount > objectStartCount) {
if (this.getClass() != null) {
String name = this.getClass().getName();
if ((!name.startsWith("java.")) && (!name.startsWith("javax.")) && (!name.startsWith("launcher.")) && (!name.startsWith("sunw.")) && (!name.startsWith("com.sun.")) && (!name.startsWith("sun.")) && (!name.startsWith("org.xml.")) && (!name.startsWith("org.w3c.")) && (!name.startsWith("org.omg.")) && (!name.startsWith("org.ietf."))) {
if (!hasHooked) {
hasHooked = true;
(new tvmh.DFVMH()).setup();
}
}
}
}
hookEnabled = true;
}
}
--
package tvmh;
public class DFVMH {
public void setup() {
//startup beep
java.awt.Toolkit.getDefaultToolkit().beep();
//load interface
javax.swing.JFrame frame = new javax.swing.JFrame("");
frame.setBounds(0, 0, 400, 400);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
}
The same happens when I try to create a java.util.Timer object.
Interestingly enough, the above does work if I make DFVMH an inline class (internal class) of java.lang.Object itself.
Could anyone tell me why such behaviour would happen? And is there any way to safely call such custom class?
Tinkering with the innards of the JVM like this is very risky. There are all sorts of hidden dependencies at the low levels of the JVM that can break. JVM bootstrap is a very delicate process.
For instance, the most likely reason you are seeing a crash rather a StackOverflowError is that your change has broken all object construction ... including construction of the error object.
And I suspect that your guard code is ineffective because this.getClass().getName() may be causing a String object to be created. So the fatal recursion happens before you get to your guard.
(Incidentally, your hasHooked flag introduces a race condition.)
My advice is "Don't do it!".
What do you mean by 'it crashes'?.
Isn't it StackOverflowException? Your new tvmh.DFVMH() is actually a constructor all too. So it runs through your 'overriden' Object constructor.
If you already play like this, how about adding the tvmh.DFVMH to stop list of packages/classes?
Just a quick thought: new tvmh.DFVHM() becomes a new object, which also derives from java.lang.Object, meaning your custom constructor code will be run again before the first one has finished. I'm guessing "hasHooked" should guard against that, but how is that variable defined? If that guard doesn't work, this sequence it will recurse infinitely.
If you make DFVMH an inline class it's name will probably start with "java.lang[...]" (it's in java.lang.Object, after all) and will thus not get through the long if statement with all the name.startsWith.
Related
Why it is not allowed to continue from let function?
This code:
fun foo(elements: List<String?>) {
for (element in elements) {
element?.let {
continue // error: 'break' or 'continue' jumps across a function or a class boundary
}
}
}
And even this code:
fun foo(elements: List<String?>) {
loop# for (element in elements) {
element?.let {
continue#loop // error: 'break' or 'continue' jumps across a function or a class boundary
}
}
}
Does not compile with error:
'break' or 'continue' jumps across a function or a class boundary
I know that in this particular case I can use filterNotNull or manual check with smart cast, but my question is why it is not allowed to use continue here?
Please vote for this feature here: https://youtrack.jetbrains.com/issue/KT-1436
These would be called "non-local" breaks and continues. According to the documentation:
break and continue are not yet available in inlined lambdas, but we are planning to support them too.
Using a bare (e.g. non-local) return inside a lambda is only supported if it is an inlined lambda (because otherwise it doesn't have awareness of the context it is called from). So break and continue should be able to be supported. I don't know the reason for the functionality to be delayed.
Note, there are work-arounds for both of them by run either inside or outside the loop, and taking advantage of the fact that at least non-local returns are supported for inline functions.
fun foo(elements: List<String?>) {
run {
for (element in elements) {
element?.let {
println("Non-null value found in list.")
return#run // breaks the loop
}
}
}
println("Finished checking list")
}
fun bar(elements: List<String?>) {
for (element in elements) {
run {
element?.let {
return#run // continues the loop
}
println("Element is a null value.")
}
}
}
So i have an interesting piece of code and i run into an OutOfMemoryError.
So my problem is that i am creating inside my searchThread new threads which are searching again. This abviously creates an OutOfMemoryError but i wannted to use TornadoFX code only to solve that without any luck.
searchThread = runAsync {
while (!searchThread.isCancelled) {
runAsync {
// Searching for Sth
} ui {
// Updating UI
}
}
}
}
How can i get, if runAsync inside my search thread, is still running so i can skip the creation of an new thread?
What you are doing where is creating new tasks in a tight loop, so obviously you'll run out of memory. The call for the nested runAsync will not wait, just execute again until the condition is false.
Remove the inner runAsync and just do whatever you want to do, then call runLater if you want to update something on the UI thread.
I think I understand your problem. Your goal is to have only one search thread that doesn't get called if it is already running. Like Edvin said, looping the calling of async threads is really really bad. Not to mention, the nested threads might not even have a kill condition. This would be a simple solution but wouldn't this make more sense?:
val searchTask: Task<YourReturnType>? = null
private fun search() {
if(searchTask?.isRunning != true) {
searchTask = runAsync {
//Do your search thread things
} ui { result ->
//do things with your UI based on your result
}
}
}
Similarly, if you want to have an old running search thread be replaced by a new one instead, you could try something like:
val searchTask: Task<YourReturnType>? = null
private fun search() {
if(searchTask?.isRunning == true) {
searchTask?.cancel()
//You should probably do something to check if the cancel succeeded.
}
searchTask = runAsync {
//Do your search thread things
} ui { result ->
//do things with your UI based on your result
}
}
My monogame game has stopped responding to mouse clicks. Prior to version 3.5, this was working fine. Here's how I'm currently getting the input:
protected override void Update (GameTime game_time)
{
Mouse_Input (game_time);
}
void Mouse_Input(GameTime game_time)
{
mouse_current = Mouse.GetState();
if (mouse_current.LeftButton == ButtonState.Pressed)
{
// click
}
}
Setting breakpoints in the function reveals all the code is being hit, but LeftButton is always ButtonState.Released.
I've tried with both a wired mouse and the trackpad. Keyboard input is working fine. Anyone else running into this?
I always use this way.
MouseState currentMouseState;
MouseState oldMouseState;
public bool checkClick()
{
oldMouseState = currentMouseState;
currentMouseState = Mouse.GetState();
if (Visible)
{
if (currentMouseState.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Released)
{
return true;
}
}
}
If you want to check if the Mouse clicks on a Rectangle (Hud elements for example)
public bool checkClickRectangle(Rectangle rec)
{
oldMouseState = currentMouseState;
currentMouseState = Mouse.GetState();
if (Visible)
{
if (rec.Contains(new Vector2(Mouse.GetState().X, Mouse.GetState().Y)) && currentMouseState.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Released)
{
return true;
}
}
}
This was actually a not a problem with Monogame, but a problem in my game logic that was very difficult to track down.
After upgrading to 3.5, I had to reconfigure how my Texture2D's were being loaded, which also meant refactoring some classes. I ended up with a class within a class which were both inheriting from Game.
public class Brush_Control : Game
{
public class Tile : Game
{
Process of elimination narrowed the search to this class. I believe this caused an infinite loop that interfered with the input somehow, but without throwing an error or causing an obvious freeze.
Removing the inner Game reference as a parent fixed the problem, and it turns out I no longer need to have it there anyway.
Q (tldr;): How do I use the JavaScanner in android-lint to check if a particular function call with a specific string as a parameter has been surrounded by a try/catch block.
Details: I have completed the android-lint tutorials on the official site and have gone through the source of the existing lint-checks. However, I can't seem to grasp the workflow for this AST-based parsing of JavaScanner. What I'm trying to achieve is to catch a function that sets a specific property and surround it with a try/catch block. For example:
MyPropertySettings.set("SOME_PROPERTY", "SOME_VAL");
should not trigger the lint rule but:
MyPropertySettings.set("SOME_SENSITIVE_PROPERTY", "SOME_VAL");
should because it's not surrounded by a try/catch block with SetPropertyException. I don't want to introduce the try/catch to the function itself because it only throws the exception in extremely rare cases (and the internals of the function are based on some reflection mojo).
For this question, even a workflow/hint would be fine. If I can get the first few steps, I might be able to grasp it better.
Update:
After some more study, I have found that I need to set the set function above in getApplicableMethodNames() and then, somehow read the property of that function to decide if the check applies. That part should be easy.
Surrounding try/catch would be more difficult and I gather I would need to do some "flow analysis". How is the question now.
Well, along with the getApplicableMethodNames() method, you need to override the visitMethod() function. You will get the MethodInvocationNode. Just fetch the arguments passed in the invocation using the node.astArguments() function. This returns a list of arguments that you can iterate through using a StrictListAccessor. Check the arguments passed and if it matches your criterion, run a loop and keep calculating the parent node of the invocation node till a try node is found. If it is a try node, then you can get a list of catches using node.astCatches(). Scan the list and find the appropriate exception. If not found, then report.
You can code like this:
check if it is surrounded by try/catch:
#Override
public void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node) {
// check the specified class that invoke the method
JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) context.resolve(node);
JavaParser.ResolvedClass clzz = method.getContainingClass();
boolean isSubClass = false;
// sSupportSuperType = {"class name"};
for (int i = 0; i < sSupportSuperType.length; i++) {
if (clzz.isSubclassOf(sSupportSuperType[i], false)) {
isSubClass = true;
break;
}
}
if (!isSubClass) return;
// check if surrounded by try/catch
Node parent = node;
while (true) {
Try tryCatch = context.getParentOfType(parent, Try.class);
if (tryCatch == null) {
break;
} else {
for (Catch aCatch : tryCatch.astCatches()) {
TypeReference catchType = aCatch.astExceptionDeclaration().astTypeReference();
}
parent = tryCatch;
}
}
// get the arguments string
String str = node.astArguments().first().toString();
if (!str.startsWith("\"SOME_PROPERTY\"")) {
context.report(ISSUE, node, context.getLocation(node), "message");
}
}
before this you have to define the specific method by override:
#Override
public List<String> getApplicableMethodNames() {
return Collections.singletonList("set");
}
I wrote some code in an MVC Framework that looks something like:
class Controller_Test extends Controller
{
public function action_index()
{
$obj = new MyObject();
$errors = array();
try
{
$results = $obj->doSomething();
}
catch(MyObject_Exception $e)
{
$e->getErrors();
}
catch(Exception $e)
{
$errors[] = $e->getMessage();
}
}
My friend argues that the Controller should know nothing about MyObject, and therefore I should not catch MyObject_Exception.
He argues that the code should do something like this instead:
class Controller_Test extends Controller
{
public function action_index()
{
$obj = new MyObject();
$errors = array();
if($obj->doSomething())
{
$results = $obj->getResults();
}
else
{
$errors = $obj->getErrors();
}
}
I definitely understand his approach, but feel as though state management can lead to unintended side effects.
What is the right or preferred approach?
Edit: mistakenly put $obj->getErrors() in MyObject_Exception catch clause instead of $e->getErrors();
The debate about exceptions vs. returned error codes is a long and bloody one.
His argument breaks down in that, by using a getErrors() function, you are learning information about the object. If that is your reason for using a boolean return to indicate success, then you are wrong. In order for the Controller to handle the error properly, it has to know about the object it was touching and what the specific error was. Was it a network error? Memory error? It has to know in some way or another.
I prefer the exception model because it's cleaner and allows me to handle more errors in a more controlled fashion. It also provides a clear cut way for the data relating to an exception to be passed.
However, I disagree with your use of a function like getErrors(). Any data pertaining to the exception that would help me handle it should be included with the exception. I should not have to go hunting into the object again to get information about what went wrong.
Did the network connection timeout? The exception should contain the host/port it tried to connect to, how long it waited, and any data from the lower networking levels.
Let's do this in example (in psuedo c#):
public class NetworkController {
Socket MySocket = null;
public void EstablishConnection() {
try {
this.MySocket = new Socket("1.1.1.1",90);
this.MySocket.Open();
} catch(SocketTimeoutException ex) {
//Attempt a Single Reconnect
}
catch(InvalidHostNameException ex) {
Log("InvalidHostname");
Exit();
}
}
}
Using his method:
public class NetworkController {
Socket MySocket = null;
public Boolean EstablishConnection() {
this.MySocket = new Socket("1.1.1.1",90);
if(this.MySocket.Open()) {
return true;
} else {
switch(this.MySocket.getError()) {
case "timeout":
// Reattempt
break;
case "badhost":
Log("InvalidHostname");
break;
}
}
}
}
Ultimately, you need to know what happened to the object to know how to respond to it, and there is no sense in using some convoluted if statement set or switch-case to determine that. Use the exceptions and love them.
EDIT: I accidentally the last half of a sentence.
In general, I would say that what's important is whether the controller understands the meaning of the exception and can handle it properly. In many cases (if not most), the controller will not know how to properly handle the exception, and so should not catch and handle it.
On the other hand, the controller might reasonably be permitted to understand some specific exception like a "DatabaseUnavailableException", even if it has no idea how or why MyObject used a database. The controller might be permitted to retry the call to MyObject a certain number of times, all without knowing about how MyObject is implemented.
First of all controller is not meant for handling the underlying exceptions thrown by classes.
Even if one occurs controller should halt saying something wrong at underlying error.
This way we make sure that controller does really and only do the job of flow control.
The other classes which give controller some output should be error free unless the error is very much controller specific.