Overload JNI Method - java

I have an existing JNI method with two parameters. Been around for a while, in use, so I don't want to just change it lest the wrath of angry customers be unleashed.
But, I now need to make an adjustment.
So, I thought, make a second overloaded method with the extra parameter and deprecate the two-parameter version. That part went fine, jar builds and runs with no issues.
The problem is in the C++ side... I defined two methods, one being a wrapper for the other (two parameter calls the three parameter version), but, when I went to export the two methods, I receive:
Error 1 error C2733: second C linkage of overloaded function 'Java_com_xxx' not allowed
So, what do I do to keep the old method name and add a new method with new parameters? Is this doable?

Run javah on your Java file declaring the native methods and you will see that you need two different Java_com_xxx functions. The C-level declarations must be unique.

Related

i keep getting "Unresolved dependencies", (in the image below) in a Jupyter notebook (java)

My project requires me to separate a program into multiple methods and call each method and test it, individually. Then have a separate method in which all the previous methods have been called to run the program. I can put the whole thing in one method but that is against the rules.
I have defined total_money and total_visitors in method 1 (the user inputs the value), and I want to use those values in my next method but when I define them again, I get Unresolved dependencies error.
I am using Jupyter Notebook.
Java is a strongly typed language hence you always must declare the variable's type.
Also, in order to pass parameters to a function, you must specify them in the function's signature.
public static void method2(int visitors, double money){

Eclipse: Programmatically manipulate class

I just came across the issue that I had 10 (or so) Java classes for all of which I wanted to:
Add a formal parameter "String newparam" to their constructor
Add this as an actual parameter to the super() call to the super class constructor (thus, the result should be super(..., newparam)).
The reason is, obviously, that the common super class of those classes now has one constructor parameter more and all extending classes had to adapt.
I just can't believe that I need to do this by hand for all classes. Eclipse must have all required concepts like "constructor", "parameter" etc. in its internals. Any way to create a script for this?
I apologize if this is trivial/well known, I have to confess that I really don't know and appreciate any hints.
Changing the constructor signature of every subclass might have to be done with some kind of script. I don't think an IDE would infer the new parameter automatically in each constructor since each subclass could potentially use the new parameter differently.
Since you're using Eclipse, you can at somewhat skip your second requirement by selecting your superclass's constructor and hitting alt+shift+c (shortcut for refactor -> Change method signature...).
When you add the parameter via the GUI provided, all references to that constructor (such as the super calls in the extending classes) will be updated as well. You can even define a default value if you want.
Then if desired you can modify each extending class's constructor to also include the new parameter (by hand, sadly).
Thank you for comments and answers. It currently seems that there is no (widely) known Eclipse-built-in approach to do what I want.
Which is, in short:
Add a new constructor parameter to the super class and, at the same time,
create
the same parameter in the constructors of all extending classes and pass this
parameter through to the super class constructor
It should be noted, however, that the function
Add a new constructor parameter to the super class and add a default value for this parameter to all extending classes
Does work via refactor -> Change method signature... (thanks #Zircon).
A rather obvious solution in case you really have a lot of classes would be to write a script. A Java class was proposed by brahimfes which would have the advantage of not requiring a new language or a new working environment since my question is Java-specific. I also think that maybe a sed script could do the trick. I did, however, not try to, first, recognize the correct lines (constructor and super class constructor call, even though the second one is trivial) and, second, identify the correct position to add the parameters and, third, actually add them. Might work, I didn't try, I just have doubts about how long you would work on such a script until it works with no errors.
Now the solution I finally went for.
I realized that I always have the same key strokes (after I added the new parameter manually to the superclass constructor) in each subclass:
Select the constructor line.
Put the cursor at the and and backtrack 3 positions (parenthesis).
Add the formal parameter.
Go down one line.
Go to the end of this line (which always happens to be the super() call) and backtrack one position.
Add the actual parameter.
There are programs out there allowing to create makros of this kind, I got a trial version of one of them (I'm on a Mac) and did it this way.
Of course, this is still not actually a solution to my question and thus I won't mark this post as a solution. While I now have a makro that that relieves me of almost all typing, I still have to open each class in the editor manually, click the correct line and then fire the makro.
This program will still save me time in the future for similar requirements. But it is not what I hoped it to be, which would be some Eclipse-built-in scripting language with access to Java syntax elements for a more high-level access then regular expressions can offer.

How to detect java local variables by an interface type and then find methods called on them?

I have some (maybe) strange requirements - I wanted to detect definitions of local (method) variables of a given interface name. When finding such a variable I would like to detect which methods (set/get*) will be called on this variable.
I tried Javassist without luck, and now I have a deeper look into ASM, but not sure if it is possible what I wanted.
The reason for this is that I like to generated a dependency graph with GraphViz of beans that depend on the same data structure.
If this thing is possible could somebody please give me a hint on how it could be done? Maybe there are other Frameworks that could do?
01.09.2015
To make things more clear:
The interface is self written - the target of the whole action is to create a dependency graph in the first step automatically - later on a graphical editor should be implemented that is based on the dependencies.
I wonder how FindBugs/PMD work, because they also use the byte code and detect for example null pointer calls (variable not initialized and method will be called on it). So I thought that I could implement my idea in the same way. The whole code is Spring based - maybe this opens another solution to the point? Last but not least I could work on a source-jar?
While thinging about the problem - would it be possible via ASM/javassist to detect all available methods from the interface and find calls to them in the other classes?
I’m afraid, what you want to do is not possible. In compiled Java code, there are no local variables in the form you have in the source code. Methods use stack frames which have memory reserved for local variables, which is addressed by a numerical index. The type is implied by what instructions write to it and may change throughout the method’s code as the memory may get reused for different variables having a disjunct scope. The names on the other hand are completely irrelevant.
When bytecode gets verified, the effect of all instructions to the stack frame will get modeled to infer the type of each stack frame slot at each point of the execution so that the validity of all operations can be checked. Starting with class file version 50, there will be StackMapTable attributes aiding the process by containing explicit type information, but only for code with branches. For sequential code, the type of variables still has to be derived by inference.
These inferred types are not necessarily the declared types. E.g., on the byte code level, there will be no difference between
CharSequence cs="foo";
cs.charAt(0);
and
String s="foo";
((CharSequence)s).charAt(0);
In both cases, there will be a storage of a String constant into a local variable followed by the invocation of an interface method. The inferred type will be String in both cases and the invocation of a CharSequence method considered valid as String implements CharSequence.
This disproves the idea of detecting that there is a local variable declared using the CharSequence (interface) type, as the actual declared type is irrelevant and not stored in the regular byte code.
There are, however, debugging attributes containing information about the local variables, see the LocalVariableTable attribute and libraries like ASM will tell you about the declarations if such information is present. But you can’t rely on these optional information. E.g. Oracle’s JRE libraries are by default shipped without them.
I don't sure I understood exacly what you want but .
you can use implement on each object ,
evry object that have getter you can implement it with class called getable .
and then you could do stuff only on object that have the function that you implement from the class getable .
https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html

getting the argument names of a function like netbeans does

Ok, this could be a tricky one. For a code generating tool I need to know methods and arguments of a class. The method name and argument types are the easy ones - just using reflection. But the argument name - and I need the real argument name - is a tricky one because this information is in the javadoc. In my case I use Netbeans 8 and I am pretty sure if Netbeans can get the arguments name I can too. Does anyone know how to read the javadoc to get the argument names of a method?
PS I know this question will pop up. I need the real argument names because the generated code provides an api and it is not very helpful for a developper to use an api where the api methods are something like set_a1, set_a2, and so on.
Indeed, this is tricky, and will involve a considerable effort if you intend to find a general solution that works for arbitrary (third-party) classes and arbitrary Java versions.
However, under certain conditions, there may be a simple solution:
If you can compile the classes on your onw, and if you can use Java 8, then you can use the Method Parameter Reflection infrastructure that was added in Java 8. When compiling the classes with javac -parameters ..., then the parameter names are added to the class file, and can be obtained from the method by calling getParameters on the Method object, and then Parameter#getName()
Parameter parameters[] = method.getParameters();
String name = parameters[0].getName();
...

Groovy: Dynamically addings methods with a specific signature

So, I need to dynamically create (or inject) methods into an object that have a specific return type and method signature, because a Java tool we're using will be finding this methods via Reflection and checks for void type. Method names will be determined at runtime.
Using metaClass. = { ... } however adds a closure which doesn't show up as a regular method (even if it can be used as one) and also has a return type.
I can't modify the method finding code, and it it not Groovy-aware.
I can't use methodMissing() or invokeMethod() because the method needs to actually exist. If I could overload class.getMethods() I think it would be possible, but I can't figure out how.
Is there any way to do this in Groovy?
You could use AST Transformations to add the code at compile time, but it wont work on classes that you don't compile, so I'm guessing that probably wont work.
You could probably replace the object with a CGLIB based proxy. If you can be more specific about the code in question...
EDIT: A little more info. Groovy metaClass magic is not available in Java unless the Java code were to explicitly call groovyClass.invokeMethod("someMethod",args);. So there isn't a way to do what you're asking with MetaClasses. CGLIB maybe.

Categories

Resources