Equivalent of a debug macro in Java [duplicate] - java

This question already has answers here:
#ifdef #ifndef in Java
(8 answers)
Closed 9 years ago.
I'm writing a program that reads structures from a file. For debugging purposes, it would be very convenient if I could have a compile-time toggle that prints the names and values of everything read which could be disabled for better performance/code size in the production version. In C, I could use the preprocessor like such to accomplish this:
#ifdef DEBUG
#define READ(name, in) { name = read(in); printf("#name: %d\n", name); }
#else
#define READ(name, in) { name = read(in); }
#endif
void myreader(mystream_t *in)
{
int a, b, c;
READ(a, in);
READ(b, in);
READ(c, in);
}
Is there any way I can reproduce this construct? I thought about this:
private static final boolean DEBUG_ENABLED = true;
private int debugRead(MyInputStream in, String name) {
int val = in.read();
if (DEBUG_ENABLED) {
System.out.println(String.format("%s: %d", name, val));
}
return val;
}
public MyReader(MyInputStream in) {
int a, b, c;
a = debugRead(in, "a");
b = debugRead(in, "b");
c = debugRead(in, "c");
}
However, this requires me to type the name of all the variables twice as well as storing the strings corresponding to all the names even on the release version. Is there a better approach to this?
EDIT: The biggest concern I have is code verbosity. The last thing I want is to have my code cluttered with debug/print/trace statements that obscure the actual reading logic.

I'm not sure if this is an apples to apples solution, but one thing that's idiomatic in Java is to use a logging framework. With it, you can execute log.debug wherever you might need debugging. SLF4j is a common facade for logging frameworks. You could just use it with JUL logging.
Usually you leave the logging code there and you configure the logger externally to either print or not print the messages.
If you're using SLF4j, the debug message will look like this:
log.debug("Setting the creation timestamp to {}", timestamp);
Most loggers can be configured to tell you what time, class and method the logging message came from.
This has some pros and cons compared to what you're used to.
Cons
I have to admit, this will take a lot of effort to learn when all you really want right now is a System.out.println.
Most of the loggers are configured on the classpath. The classpath is a non-trivial part of java to learn but you will have to learn it eventually anyway. It's really important to understand.
It won't automatically print out the name of the variable passed in. AFAIK, you'll have to write that detail yourself
Pros
Using a logger is very robust. You can leave the code there for production and dev mode and just configure the verbosity appropriately
It can automatically print out the context of the class/method and date of the message and other things like that
You can configure the output in lots of different ways. For example, "output to the console and log.txt but when that file becomes > 100mb, rollover the old data to log2.txt and keep at most 5 log files."

To the general problem of emulating C/C++ macros in Java, there are several solutions. The particular case of logging is usually resolved in a simpler way. The simplest, conceptually closest, and puristic form is abstracting the macro in an interface and producing alternative implementations:
public class Sample {
class mystream_t {
}
public int read(mystream_t is) {
return 0 ;
}
static final boolean DEBUG= false ;
interface ReadType {
public void apply(int[] name,mystream_t in);
}
ReadType READ; {
if( DEBUG ) {
READ= new ReadType(){
public void apply(int[] name,mystream_t in) {
name[0]= read(in) ; System.out.printf("#name: %d\n",name);
}
};
} else {
READ= new ReadType(){
public void apply(int[] name,mystream_t in) {
name[0]= read(in) ;
}
};
}
}
void myreader(mystream_t in) {
int[] a= new int[1], b= new int[1], c= new int[1];
READ.apply(a, in);
READ.apply(b, in);
READ.apply(c, in);
}
}
This makes use of a simple, static form of code injection. I tried to make the code as close as possible to the original.
The second most relevant way of emulating C/C++ macros in Java requires Annotations and Annotation Processing. It's even closer to C/C++ macros, but requires more effort and resorts to a mechanism that could not be considered pure part of the language.
And the third one is using an Aspect-Oriented Programming framework like AspectJ.

Related

Can JNA be used for a complex Windows DLL like IMAPI

I've managed to get COM4J to use some functionality in the windows IMAPI (CD writing).
However I've failed to get any of the calls that return SAFEARRAYs working, but this project doesn't appear to be currently active ...
The DLL is usually in C:\Windows\System32\imapi2.dll, and using it also requires using C:\Windows\System32\imapi2fs.dll
Looking around for a JAVA-COM bridge project that is active led me to JNA.
The remit of the project to simplify JAVA-COM bridging intrigued me .... however I fell at the first hurdle, and am hoping someone can help.
So far I've taken the Microsoft IMAPI examples and written a Powershell application, from which I have the series of calls I need to make to the API.[CDInterface][1]
The first thing you need to do with IMAPI is create an Instance of IDiskMaster2, so I've declared that via an Imapi2 interface, like so
public interface Imapi2 extends Library {
Imapi2 INSTANCE = (Imapi2)
Native.load("C:/Windows/System32/imapi2.dll" , Imapi2.class);
public static class IDiscMaster2 extends Structure {
int getCount;
public int getCount() {
return getCount;
}
}
IDiscMaster2 createMsftDiscMaster2();
}
Then in the main code
Imapi2.IDiscMaster2 recorderList = Imapi2.INSTANCE.createMsftDiscMaster2();
System.out.println("Found " + recorderList.getCount() + " Recorders");
Just putting 'imapi2' in the call to Native.load() didn't work either.
I'm guessing I'm doing something fundamentally wrong, but it's not clear how you get JNA to 'see' a new dll you want to interface to ..... and also I am kind of afraid there is something very different about this API from the othe APIs that people are using JNA to talk to, so may not be worth trying!
public interface Imapi2 extends Library {
Imapi2 INSTANCE = (Imapi2)
Native.load("C:/Windows/System32/imapi2.dll" , Imapi2.class);
public class IDiscMaster2 extends Dispatch {
public static final CLSID CLSID_MsftDiscMaster2 = new CLSID("2735412F-7F64-5B0F-8F00-5D77AFBE261E");
public IDiscMaster2() {
}
private IDiscMaster2(Pointer pvInstance) {
super(pvInstance);
}
public static IDiscMaster2 create() {
PointerByReference pbr = new PointerByReference();
WinNT.HRESULT hres = Ole32.INSTANCE.CoCreateInstance(CLSID_MsftDiscMaster2, null, WTypes.CLSCTX_ALL, null, pbr);
if (COMUtils.FAILED(hres)) {
System.out.println("ERROR: Failed to create instance");
return null;
}
return new IDiscMaster2(pbr.getValue());
}
public WinNT.HRESULT _getCount(Pointer count ){
return (WinNT.HRESULT) _invokeNativeObject(2, new Object[]{count}, WinNT.HRESULT.class);
}
public long getCount() {
try {
long count = -1;
Pointer ptr = new Pointer(count);
WinNT.HRESULT result = _getCount(ptr);
COMUtils.checkRC(result);
return count;
} catch ( Exception e ) {
System.out.println("Error : " + e.getMessage());
}
return -1;
}
}
Then invocation in main changed to
Imapi2 imapi2Lib = Imapi2.INSTANCE;
Imapi2.IDiscMaster2 recorderList = new Imapi2.IDiscMaster2();
System.out.println("Found " + recorderList.getCount() + " Recorders");
IntelliJ shows up uninvoked methods, so it doesn't look like create() is getting called. Not sure if this is because I need to call it, or down to the function implementing IDispatch not IUnknown.
[1]: https://github.com/nosdod/CDInterface
I've answered this in a similar question which I originally marked this as a duplicate of. However, given the difficulty loading this, your case is unique enough that I'll attempt to give a separate answer.
The general case for COM is that there is an API function that creates the object. You have mapped this as createMsftDiscMaster2(). Note that you have allocated a resource here and it needs to be disposed of when you are done with it; the API documentation should tell you how to do that (possibly by calling Release() from IUnknown.)
Your next step is to map the IDiscMaster2 COM class. I see two mappings here, so I'm confused as to which one you want. The one at the top of your question is incorrect, but the one extending Dispatch later is the correct way to start, but I'm not clear where you've gone after that. The rest of the class should look similar to the internals of the Dispatch class in JNA.
In that class you can see the boilerplate that you will follow. Note that it extends Unknown which follows the same boilerplate for offsets 0, 1, and 2 for the first 3 COM functions QueryInterface, AddRef, and Release. Dispatch picks up with offsets 3, 4, 5, and 6 for COM functions GetTypeInfoCount, GetTypeInfo, GetIDsOfNames, and Invoke.
So in your mapping for DiskMaster2 you will pick up with offset 7, and your mapping will look like:
public HRESULT TheFunctionName(FOO foo, BAR bar) {
return (HRESULT) this._invokeNativeObject(7,
new Object[] { this.getPointer(), foo, bar },
HRESULT.class);
}
This is where you need to locate the actual header file for this class to determine the order in which the functions appear in the Vtbl. It looks like you attempted to do this with your code, but the offset 2 is already assigned in Unknown, the lowest one you'll be able to use is 7 (and continue on with 8, 9, 10 for each function in this COM interface, in the correct order -- which you must determine from the Vtbl.)
Based on this header, you can see those functions mapped in order and your offsets should be: 7: get__NewEnum, 8: get_Item, 9: get_Count, and 10: get_IsSupportedEnvironment. Use those header function mappings as a start and change them to the _invokeNativeObject() format above. (They all return HRESULT, you'll just be changing the argument list.)

How to automatically print all parameter values of Java function at runtime

I want to print automatically all the parameter values of my functions at runtime.
Just imagin that I have the following two methods:
public void doAction(String firstParam, String SecondParam) {
Util.printAllParameter(this);
}
public void doAction(String firstParam) {
Util.printAllParameter(this);
}
If I call to this functions:
doAction("a", "b"); --> Desired result: Print "a, b"
doAction("a"); --> Desired result: Print "a"
I don't want something like this (This is not reusable, it is static):
System.out.println(firstParam + "," + SecondParam);
I need a reusable method that I can use in different functions with different number of parameter. I want to call a function like "Util.printAllParameter()" and then print all the parameters.
Thanks in advance.
To do it generally would require rewriting the bytecode (probably with a Java Agent, or library using it) or the source code.
The way do it without hacking the code is to use an interface and a Proxy. Interfaces are often suggested, but Java gets in the way with its old fashioned, super verbose syntax.
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.stream.*;
// Gratuitous use of new fangled record feature and streams.
record TraceInvocation(PrintStream out) {
public <T> T trace(Class<T> type, T target) {
Objects.requireNonNull(target);
return type.cast(Proxy.newProxyInstance(
type.getClassLoader(),
new Class<?>[] { type },
(proxy, method, args) -> {
// Apparently args can be null. Ffs.
out.println(
(target==null ? type.getSimpleName() : escape(target))+
"."+method.getName()+
// There's probably a better way without {}.
"("+(args==null ? "" : String.join(", ",
Stream.of(args)
.map(TraceInvocation::escape)
.toArray(String[]::new)
))+")"
);
return method.invoke(target, args);
}
));
}
// Don't even think about allowing log injection.
// (Okay, weird syntax.)
private static String escape(Object object) {
// I am not a fan of streams.
int[] escaped = String.valueOf(object).codePoints().flatMap(cp ->
(cp == '\\' || cp == '.' || cp == ',') ?
IntStream.of('\\', cp) :
(' ' <= cp && cp <= '~' ) ?
IntStream.of(cp) :
("\\"+/*(int)*/cp+"\\").codePoints()
).toArray();
return new String(escaped, 0, escaped.length);
}
}
Use as:
CharSequence cs = new TraceInvocation(System.err)
.trace(CharSequence.class, "Scunthorpe");
cs.subSequence(4, 10).length(); // No log for length
cs.charAt(2);
cs.length();
Possible variation include filtering which methods to display, logging return values/exceptions, alternative to toString and tracing returned values.
I found this approach really useful when dealing with sending and receiving a stream in a proprietary format.
You can write a simple utility method that like:
public void trace(String methodName, Object... args) {
that then inspects all the arguments and prints a nice string for you.
But you have that explicit passing of the method name as string, which can't be avoided. Yes, theoretically, one call create a stack trace by throwing/catching an exception, and deduce the method name, but that is a real performance killer, which you absolutely can't do for ordinary tracing that is supposed to happen millions of time per day.
So: there are no "built-in" mechanisms in the Java language to get you there. No "macros" or some sort of "templating" to just "pull" such behavior into your production code without doing it explicitly.
But there is the concept of "Aspect Oriented Programming". Meaning: you have another tool that modifies your production code, for example to automatically add such trace statements, as a part of the build/compile process.
Certain technology stacks, for example spring might come with such technology.
If you are not using such frameworks, you would have to "add" something like that to your setup.

How to check Type Ranges with Java development tools (JDT)?

I want to parse a String, which contains a number, using JDT to find out whether the contained number is inside the valid Range of one of the Primitive Types.
Let's say i got a float value like this as String "1.7976931348623157e350" and want to see whether it is still inside the allowed range for primitive type 'double'. (In this case it would not be inside the valid range, because the maximum exponent of double is 308).
I don't want to use the standard methods like : Double.parseDouble("1.7976931348623157e350"), because I'm afraid it might be too slow if I have a big amount of primitive types, which I want to check .
If you know the Eclipse development environment you will know that inside a normal java file, eclipse is able to tell whether a variable is out of range or not, by underlining it red, in the the case of 'out of range'. So basically i want to use this functionality. But as you can guess - it's easier said then done!
I have started experimenting with the ASTParser from this library: org.eclipse.jdt.core.dom
But I must admit I was not very successful here.
First i tried calling some of those vistor methods using methods like:
resolveBinding() , but they always only returned me "Null".
I have found some interesting class called ASTSyntaxErrorPropagator , but i'm not sure how this is used correctly. It seems to propagate parsing problems or something like that and gets it's information delivered by some thing class called CodeSnippetParsingUtil I assume. Anyways, these are only speculations.
Does anyone know how to use this ASTParser correctly?
I would be really thankful for some advice.
Here is some basic code-snipped which I tried to debug:
public class DatatypesParser {
public static void main(String[] args) {
ASTParser parser = ASTParser.newParser(AST.JLS4);
Map options = JavaCore.getOptions();
JavaCore.setComplianceOptions(JavaCore.VERSION_1_7, options);
String statement = new String("int i = " + Long.MAX_VALUE + ";");
parser.setSource(statement.toCharArray());
parser.setKind(ASTParser.K_STATEMENTS);
parser.setResolveBindings(true);
parser.setBindingsRecovery(true);
ASTNode ast = parser.createAST(null);
ast.accept(new ASTVisitor() {
#Override
public boolean visit(VariableDeclarationStatement node) {
CodeSnippetParsingUtil util = new CodeSnippetParsingUtil();
return true;
}
});
}
I don't want to use the standard methods like :
Double.parseDouble("1.7976931348623157e350"), because i'm afraid it
might be too slow if i have a big amount of primitive types, which i
want to check .
Under the hood JDT is actually using the standard methods of Double to parse the value, and quite a bit more - so you should always use the standard methods if performance is a concern.
Here is how the double gets parsed by JDT.
From org.eclipse.jdt.internal.compiler.ast.DoubleLiteral:
public void computeConstant() {
Double computedValue;
[...]
try {
computedValue = Double.valueOf(String.valueOf(this.source));
} catch (NumberFormatException e) {
[...]
return;
}
final double doubleValue = computedValue.doubleValue();
if (doubleValue > Double.MAX_VALUE) {
// error: the number is too large to represent
return;
}
[...]
}

Best practice of using flags in Java method

What's the best practice for specifying flags in a Java method?
I've seen SWT using int as bitfields, like:
(example partially from "Effective Java, 2nd Ed." page 159):
public class Text {
public static final int STYLE_BOLD = 1 << 0; // 1
public static final int STYLE_ITALIC = 1 << 1; // 2
void printText(String text, int flags) {
}
}
and your client call looks like:
printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC);
..but this is discouraged as you can mixed flags (int values) from different classes together without any compiler checks.
In the same book ("Effective Java"), I see the use of EnumSet, but then your user call becomes:
printText("hello", EnumSet.of(Style.Bold, Style.ITALIC));
I find this a bit verbose and I prefer the elegance of SWT.
Is there any other alternative or is this basically the two tastes you must pick?
Guess you have hit a wall. I don't see any other option. Java is verbose that's a fact. In situations like this i usually add a local variable to make the code more readable. You can do this,
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC);
printText("hello", styles);
If you want bit style flags, Java wraps them in a BitSet. It's been around for ages, yet few people bother to use it (preferring embedding C style bit handling in ints).
The api for BitSet can be found here.
Coupled with a few well chosen static ints, it does pretty well until you start getting into checking and setting multiple bits in one pass.
I advise that you go with the EnumSet approach.
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);
This approach provides better type safety, and Style being an enum will have full-blown OO capabilities.
Late answer for anyone coming across this. Here is one way to do it to reduce memory and have a nice enum like api:
public static class MyFlag {
public static final MyFlag A = new MyFlag(1<<0);
public static final MyFlag B = new MyFlag(1<<1);
public static final MyFlag C = new MyFlag(1<<2);
public static final MyFlag ALL = A.and(B).and(C);
private final int flag;
private MyFlag(int flag){
this.flag = flag;
}
public MyFlag and(MyFlag limit){
return new MyFlag(flag & limit.flag);
}
public MyFlag not(MyFlag limit){
return new MyFlag(flag | ~limit.flag);
}
public boolean isSet(MyFlag limit){
if(limit ==null){
return false;
}
return (this.flag & limit.flag) != 0;
}
}
method:
public void doFoo(MyFlag flag){
if(MyFlag.A.isSet(flag)){
....
}
if(MyFlag.C.isSet(flag)){
....
}
}
call:
x.doFoo(MyFlag.A.and(MyFlag.C));
If you only have a limited number of methods that will be taking a set of styles (like printText, in your example), you can tweak their signature to take a variable number of Style params:
void printText(String text, Style... flags) {
EnumSet<Style> style = logicalOr(flags); // see comment below
...
}
And then your calls are very close to the untyped (int) flag route:
printText("hello", Style.BOLD, Style.ITALIC);
Sadly, there is no EnumSet.of(E... ) factory, just EnumSet.of(E first, E... more), so you'll need a generic logicalOr method to split your array into first + rest chunks. Left as an exercise to the reader =).

Wrapping an existing application with JNI

Most of the documentation that details how to get started with JNI described how to build a new JNI application using X-Code. Can anyone link me to a description of how to use JNI to interface with Objective-C in an existing application.
NOTE: I have completely re-written this answer from scratch, now that I know for sure it works ;-).
Use Rococoa instead of JNI.
Here is a brief sample I was able to whip up that displays the picture taker dialog (based on your comment to Stephen C's answer).
/***
* INCOMPLETE: Doesn't have imports or anything like that.
***/
public interface Quartz extends Library
{
public static Quartz instance = (Quartz)Native.loadLibrary("Quartz", Quartz.class);
}
public interface IKPictureTaker extends NSObject
{
public static final _Class CLASS = Rococoa.createClass("IKPictureTaker", _Class.class);
public interface _Class extends NSClass
{
/**
* Returns a shared {#code IKPictureTaker} instance, creating it if necessary.
* #return an {#code IKPictureTaker} object.
*/
IKPictureTaker pictureTaker();
}
NSInteger runModal();
}
public class IKPictureTakerTest extends JFrame
{
public static void main(String[] args) throws Exception
{
// You need a GUI before this will work.
new IKPictureTakerTest().setVisible(true);
NSAutoreleasePool pool = NSAutoreleasePool.new_();
// Initialize the Quartz framework.
Quartz.instance.toString();
// Display the dialog.
IKPictureTaker pictureTaker = IKPictureTaker.CLASS.pictureTaker();
NSInteger result = pictureTaker.runModal();
if (result.intValue() == 0) // NSCancelButton
{
System.out.println("User cancelled.");
}
else
{
assert result.intValue() == 1; // NSOKButton
System.out.println("User chose an image.");
}
System.out.println(pictureTaker.inputImage()); // null if the user cancelled
pool.release();
}
}
If you get lost, try the Rococoa mailing lists. The developers are very helpful.
You will still need to write a JNI library of some sort to wrap your access to the existing code (aka, shared object, DLL, service program, etc). This is because JNI requires a rather obtuse (but sensible) naming convention for the native functions invoked, because you need to move data in and out of Java memory space and because you need to have conceptual "bridging" code between Java and your native function.
For example, I wrote a JNI library to provide access to existing C functions on the iSeries. One such function to read from a data area looks as follows:
JNIEXPORT void JNICALL Java_com_xxx_jni400_DataArea_jniGetDataArea(JNIEnv *jep, jobject thsObj, jbyteArray qulnam, jint str, jint len, jbyteArray rtndta, jint rtnlen) {
jbyte *qn,*rd;
Qwc_Rdtaa_Data_Returned_t *drt;
QFBK2_T fbk;
byte nam[11],lib[11];
byte *ptr;
// SETUP
thsObj=thsObj;
qn=(*jep)->GetByteArrayElements(jep,qulnam,0);
rd=(*jep)->GetByteArrayElements(jep,rtndta,0);
fbk.pro=sizeof(fbk); fbk.avl=0;
// INVOKE
QWCRDTAA(rd,rtnlen,(byte*)qn,str,len,&fbk);
// HANDLE SUCCESSFUL INVOCATION
if(fbk.avl==0) {
drt=(Qwc_Rdtaa_Data_Returned_t*)rd;
if(drt->Length_Value_Returned>0) { /* pad with spaces until the length requested */
ptr=(byte*)(rd+sizeof(*drt)+drt->Length_Value_Returned);
for(; drt->Length_Value_Returned<len; drt->Length_Value_Returned++,ptr++) { *ptr=' '; }
}
}
// RELEASE JAVA MEMORY LOCKS
(*jep)->ReleaseByteArrayElements(jep,qulnam,qn,JNI_ABORT); /* discard array changes */
(*jep)->ReleaseByteArrayElements(jep,rtndta,rd,0 ); /* copy back changes */
// TRANSFORM NATIVE ERROR INTO AN EXCEPTION AND THROW
if(fbk.avl!=0) {
byte eid[8],dta[201];
word dtalen;
f2s(nam,sizeof(nam),(byte*)qn ,10);
f2s(lib,sizeof(lib),(byte*)(qn+10),10);
dtalen=(word)mMin( sizeof(fbk.dta),(fbk.avl-(sizeof(fbk)-sizeof(fbk.dta))) );
f2s(eid,sizeof(eid),fbk.eid,sizeof(fbk.eid));
f2s(dta,sizeof(dta),fbk.dta,dtalen);
if(mStrEquI(eid,"CPF1015") || mStrEquI(eid,"CPF1021")) {
throwEscape(jep,90301,"Could not find data area %s in library %s",nam,lib);
}
else if(mStrEquI(eid,"CPF1016") || mStrEquI(eid,"CPF1022")) {
throwEscape(jep,90301,"Not authorized to data area %s in library %s",nam,lib);
}
else if(mStrEquI(eid,"CPF1063") || mStrEquI(eid,"CPF1067")) {
throwEscape(jep,90301,"Cannot allocate data area %s in library %s",nam,lib);
}
else if(mStrEquI(eid,"CPF1088") || mStrEquI(eid,"CPF1089")) {
throwEscape(jep,90301,"Substring %i,%i for data area %s in library %s are not valid",str,len,nam,lib);
}
else {
if(strlen(dta)>0) { throwEscape(jep,90001,"System API QWCRDTAA returned error message ID %s (%s)",eid,dta);}
else { throwEscape(jep,90001,"System API QWCRDTAA returned error message ID %s",eid); }
}
}
}
Note the one-line invocation for underlying existing API, QWCRDTAA, which is provided by IBM; the rest is Java-centric wrapping which is necessary to make the call and deal with the results.
Also, be very careful that what you invoke is thread-safe, or that you protect the code from concurrent invocations globally in the Java layer, or that you protect the code with a mutex in the O/S layer.
PS: Note that non-threadsafe native code is globally non-threadsafe; you must prevent concurrent invocation with all other non-threadsafe native code, not just the one method you are invoking. This is because it might be unsafe due to an underlying call to some other function which other unsafe methods call (like strerror(), (if my C memory serves well)).
Assuming that the Object-C application can be run via the command line, a simpler (and less problematic) approach would be to launch it using one of the java.lang.Runtime.exec(...) methods.
JNI is fraught with complexity and stability issues, and it is best to avoid it if you can.
EDIT: The OP has explained that this is a "widget" not a command line application. That makes it harder to avoid using JNI. But I still think that you ought to try. For example, you could consider wrapping the Objective-C widget in an Objective-C application, that runs the widget in a new window.

Categories