Add local variable to JShell evaluation context - java

I'm using jdk.jshell.JShell to evaluate Java code programmatically and I'd like to add a local variable to the active evaluation context, so the value is useable in the shell.
I'm instantiating the JShell with a DirectExecutionControl, so it runs on the same JVM as the main code. I've spent quite a lot of time stepping through the source code of the JDK trying to see where I could plug myself, but it's quite opaque; simply getting an Object result out of eval(...) instead of a String required a number of hacks (Oracle, why?).
The answer here seems to suggest that this is not possible, without justification, but I'm too deep into this to accept that.
Ideas I have thought about:
- creating a class dynamically, with a field corresponding to the variable I want to add, and `import static`ing that class into the JShell (but I don't know how to dynamically add an import either)
- trying to find one of the internal auto-generated classes JShell is using to store the variables, and replacing them using arcane reflection magic

Related

Eclipse JDT - How to watch non-public variables?

I am not new to programming but I am just learning the Java language and Eclipse. I want to see how Java works internally for some of the various "standard" imported classes using Eclipse's debug facilities (JDT Debug). My setup (Oxygen w/ JDK SE8 on Windows 8.1) works fine as far as single stepping through the code but many of the imported Class variables are unable to be placed into a watchlist or expression monitor, which I think is because they are not defined as "public".
As an example: I want to learn how java.math.BigInteger works so I wrote a quick program which uses the pow() method. The program runs successfully, and when using debug mode I am able to track the flow fine as well. What I cannot seem to do is to see the values of the internal "default" (no access modifier) variables. Below are three such variables found in BigInteger.java (lines 2225-2231):
int powersOfTwo = partToSquare.getLowestSetBit();
long bitsToShift = (long)powersOfTwo * exponent;
if (bitsToShift > Integer.MAX_VALUE) {
reportOverflow();
}
int remainingBits;
Any suggestions on how to expose these variables to JDT Debug for learning purposes?
I guess this is not about public vs. non-public but about fields vs. local variables.
Compilation may drop information about local variables, so the debugger no longer has information about their names. In that case a watch expression using that name cannot be resolved. The Variables view should, however, still show the value, albeit with artificial names like arg0 ... You can still correlate the variable to what you see in the source code, as local variables are only added to the Variables view when during stepping you reach the corresponding declaration.

Custom Validator for Static Use of Reflection vs. Custom Rule in SonarQube (Java, Eclipse)

There may be some related questions, but I think my situation is peculiar enough to justify a question on its own.
I'm working on a historically grown huge Java project (far over one million LOC, due to other reasons we're still bound to Java 6 at the moment), where reflection is used to display data in tables - reflection is not used for dynamically changing the displayed data, but just for using some kind of short cuts in the code. A simplified part of the code looks like this.
TableColumns taco = new TableColumns(Bean.class);
taco.add(new TableColumn("myFirstMember"));
taco.add(new TableColumn("mySecondMember"));
...
List<Bean> dataList = getDataFromDB(myFilterSettings);
taco.displayTable(dataList);
So the values of the table cells of each row are stored in an instance of Bean. The values for the first cell comes from calling itemOfDataList.getMyFirstMember() (so here comes the reflection part of the code). The rendering of the table cells is done depending on the return type of the itemOfDataList.getMyFirstMember().
This way, it's easy to add new columns to the table, getting them rendered in a standard way without caring about any details.
Problem of this approach: when the getter name changes, the compiler doesn't notice and there will be an exception at runtime in case Bean.getMyFirstMember() was renamed to Bean.getMyFirstMemberChanged().
While reflection is used to determine which getter is called, the needed info is in fact available at compile time, there are no variables used for the column info.
My goal: having a validator that will check at compile time whether the needed getter methods in the Bean class do exist.
Possible solultions:
modifying the code (using more specific infos, writing an adapter, using annotations or whatever that can be checked at compile time by the compiler), I explicitely don't want a solution of this kind, due to the huge code basis. I just need to guarantee that the reflection won't fail at runtime.
writing a custom validator: I guess this shouldn't be too complex, but I have no real idea how to start, we use eclipse as ide, so it should be possible to write such a custom validator - any hints for a good starting point?
The validator should show a warning in eclipse if the parameter in the TableColumn(parameter) isn't final (should be a literal or constant). The validator should show an error in eclipse if the TableColumn is added to TableColumns and the corresponding Bean.getParameter() doesn't exist.
as we use SonarQube for quality checking, we could also implement a custom rule checking if the methods do exist - not completely sure if such a custom rule is possible (probably yes)
maybe other solutions that will give a fast feedback within eclipse that some tables won't render correctly after some getter methods were renamed
What I'm asking for:
what will be easier in this situation: writing a custom validator for eclipse or writing a custom rule for SonarQube?
hints where to start either approach
hints for other solultions
Thanks for your help.
Some alternatives:
You could migrate to more modern Java for this pattern, it is a prime candidate for method references. Then, your IDE of choice can automatically take care of the problem when you refactor/rename. This can be done bit-by-bit as the opportunity/necessity arises.
You could write your own custom annotations:
Which you can probably get SonarQube to scan for
Which could allow you to take advantage of javax.validation.* goodies, so your code may look/feel more like 'standard' Java EE code.
Annotations can be covered by a processor during the build step, various build tools have ways to hook this up -- and the processor can do more advanced/costly introspection so you can push the validation to compile-time as opposed to run-time.

How can i use redefineClasses() method in javaagents

I have been using premain() with addTransformer(). Since, it gives javassist.ClassNotFound exceptions for certain classes when i run the agent with a server, i thought to try the agentMain() with redefineClasses(). I went through many links, but so far i am unable to find a piece of code that gives me clear idea on how to set up a simple java agent using these two methods. Some help would be really appreciated.
Can we use redefineClasses() with premain()? (When we use redefineClasses() do we still need the transform method?)
I am trying to instrument set of methods of set of classes, where i know the fully qualified name of those classes as com.test.Foo. I wanted to instrument them without going through the entire set of classes loaded onto JVM. I have been reading those documents back and forth, but still i am unable to get a clear idea on how to use that redefineClasses method?
You can call redefineClasses from anywhere, also from a premain method which is nothing but an extension to a normal Java program run by the same JVM process previous to a main method.
A trivial example for running a redefinition is:
instrumentation.redefineClasses(new ClassDefinition(Foo.class, new byte[] {...}));
This way, Foo is set to be represented by the byte array that must contain a valid class file for Foo where all signatures of fields and methods are the same as by the loaded Foo.class. You can use a tool like ASM for instrumenting the class.
If you really only want to instrument Foo, then this might just be the way to go instead of using a ClassFileTransformer.

How to find static method calls in large Java project?

I'm refactoring some Java code to be more decoupled by changing some static method calls to non-static calls, for example:
// Before:
DAO.doSomething(dataSource, arg1, ..., argN)
// After:
dao.doSomething(arg1, ..., argN)
My problem is that in a large project, it can be hard to find where static method calls are being made. Is there an easy way to do this, either from the command line or in Eclipse?
Such a tool would need to let me ignore "benign" static method calls such as these (either by not finding them in the first place, or by allowing them to be easily deleted from the search results):
String.valueOf(...)
Integer.parseInt(...)
MyClass.someBenignStaticMethod(...)
Some clarifications:
I'm not interested in finding method calls made via reflection
I don't know what static methods currently exist in this project, so it's not as simple as searching for their callers using Eclipse's "Open Call Hierarchy" command (Ctrl-Alt-H), although an easy way to search for non-private static methods would let me use this approach
I'm also interested in finding calls to static methods located outside my project, e.g. javax.mail.Transport#send
I'm looking for a free (as in beer) solution
Do you really need to search? Why not comment out the static method calls one by one? When you compile it then it will flush out the references.
I'd use grep (-R on Linux) to search for initial caps-dot-camel case-open (I don't use it enough to give you the full command line). And then grep -v to get rid of some of the rubbish.
Well, really what I'd do is refactor incrementally. Changes a method, and see what breaks (if nothing breaks, delete the code).
Theoretically you could search through the class files looking for invokestatic. The FindBugs infrastructure would probably help out here (there may be better starting points).
Some IDEs provide support for refactoring. You can refactor every static method one-by-one.
In Eclipse, you can view the call hierarchy to see all the callers of such method. To view the call hierarchy you can select the method name and press Command-Alt-H, or Right-Click on symbol and choose 'Open Call Hierarchy).
We have a product called nWire for Java which might just help. nWire analyzes your code and builds a database of your code components and associations. You can see a brief demo on our web site.
We plan to have reporting capabilities added in the future. In the mean while, if you have some basic experience with databases, you can tap into the nWire repository and, with a simple SQL query, get a list of all your static methods (you can also see the invocations there). nWire uses the H2 database engine which is open-source and free.
I can assist in accessing the database. Drop me a line to support [at] nwiresoftware.com.
I've written a small Java program that uses the excellent ASM library. It lets you exclude packages like java.lang, and produces output that looks like this:
+ java
+ io
- File
# createTempFile(java.lang.String, java.lang.String)
+ javax
+ imageio
- ImageIO
# read(java.io.InputStream)
# write(java.awt.image.RenderedImage, java.lang.String, java.io.File)
+ mail
- Transport
# send(javax.mail.Message)
+ internet
- InternetAddress
# parse(java.lang.String, boolean)
+ xml
+ parsers
- DocumentBuilderFactory
# newInstance()
I'd prefer something that's more easily built into my existing build process, which uses CheckStyle, but this is the best solution I've come up with so far.
A possible solution could be a custom CheckSyle or PMD or ... warning. Currently I have the same challenge and trying it with CheckStyle. It seems to be right easy to write such an extention.

Remove uses of certain Java classes at compile time

I am looking for a way to remove all uses of a particular class, including the class itself, at compile time. Basically a form of pre-processing, but I'd like to do it without having to surround all the instances with #ifdebug ... #endif.
Is there any ant-based tool out there that can do this? If not, can anyone point me in the right direction for how to write such a tool? (not a minor undertaking I know, but if its the only option...)
The situation is I have a helper class for debugging function calls. This is instantiated at the beginning of a function and a call is made at the end. This is a JavaME application so I'm nervous about the overhead this is adding to performance. I already have a release and debug build that have pre-processor directives using ProGuard, so I would like to exclude the use of this helper class from the release build. It doesn't appear this can be done with ProGuard.
"This is instantiated at the beginning of a function and a call is made at the end. "
If this is all over your code maybe you need to look at AOP.
or a state design pattern for the helper class, in test mode it does one thing but in prod it does another(like nothing)
Do you know that this debug code will make the JavaME app slow? You could also try creating a way to conditionally call these debug methods.
A few more ideas ... I've never written a JavaME app, but I assume there is way to run/test with running on the actual device. Given this way of running/testing, perhaps you can use Eclipse/Netbeans to debug your code and use proper breakpoints instead of programmatically tracing method calls. No harm to compiled code in this case. Also consider using AspectJ to trace method calls, this can be conditionally done after code is compiled since AspectJ alters bytecode directly (not sure how this plays with JavaME). Lastly, I've heard of people using the standard GNU C/C++ preprocessor on Java. I have no idea if it works, google will help you.
Not exactly what you want but...
You could separate your code to modules (core and debug, in your case), then make sure modules call each other via reflection: use an interface available in core, create a wrapper class in core that will hide object instantiation via reflection detail/
Then, on production, just omit the debug code and have the wrapper "do nothing" if the instantiation fail / when you set a specific flag.
This way your debug classes won't make it into production and you won't have to "statically link" to them so your core production code won't care.
Of course, this is only possible if your debug code has no side effects visible to core code, but it seems that's your case (from your problem description).
Is it possible to just create the class once, on application startup, instead of creating an instance for each method? Your debug class could then look like this:
public class Debug // maybe make this a *gasp* singleton?
{
public static void start(); // called at start of method
public static void end(); // called at end, probably should be in a finally block
public static void setDebugMode(boolean debugOn); // turn off for production mode
}
Set debug mode to "true" in testing but "false" in production. When debug mode is off, none of the methods do anything (except check the state of debug mode, of course).
You don't avoid the overhead of the function call, and you do need to check the state of that boolean, but you do get to avoid jumping through hoops trying to avoid load the class at all.
This will need more work if you have a multithreaded application, too.

Categories

Resources