Javassist - addMethod that returns an Object[][] - java-native-interface

My goal is to create in runtime an additional method inside a specific .class file.
A method that returns an Object[][].
For that I found an amazing framework called - Javassist, a bytecode modifier framework, which helps you modify your compiled class in runtime in order to add more bytecode that represents a new method.
Managed to create a void method, and a method that returns a string but, for some reason, I'm unable to generate a method that returns an array or a matrix.
So far I've been struggling to find the proper way of creating such method, and got a continuous CannotCompileException.
Code:
private static CtMethod generateMethod1(CtClass declaringClass)
throws CannotCompileException {
StringBuffer sb = new StringBuffer();
sb.append("public ").append(Object[][].class.getName()).append(" ").append("method1").append("(){")
.append("return new").append(Object[][].class.getName()).append("{{ 1,2 }}").append("; }");
System.out.println(sb.toString());
return CtMethod.make(sb.toString(), declaringClass);
}
The toString of the generated method above is:
public [[Ljava.lang.Object; method1(){return [[Ljava.lang.Object;{{ 1,2 }}; }
Probably fails due to false jni syntax.

Well, solved it by just replacing the Object[][].class.getName() with Object[][] literally...

Related

Override System class in Java and more precisely currentTimeMillis [duplicate]

Aside from recompiling rt.jar is there any way I can replace the currentTimeMillis() call with one of my own?
1# The right way to do it is use a Clock object and abstract time.
I know it but we'll be running code developed by an endless number of developers that have not implemented Clock or have made an implementation of their own.
2# Use a mock tool like JMockit to mock that class.
Even though that only works with Hotspot disabled -Xint and we have success using the code bellow it does not "persist" on external libraries. Meaning that you'd have to Mock it everywhere which, as the code is out of our control, is not feasible. All code under main() does return 0 milis (as from the example) but a new DateTime() will return the actual system millis.
#MockClass(realClass = System.class)
public class SystemMock extends MockUp<System> {
// returns 1970-01-01
#Mock public static long currentTimeMillis() { return 0; }
}
3# Re-declare System on start up by using -Xbootclasspath/p (edited)
While possible, and though you can create/alter methods, the one in question is declared as public static native long currentTimeMillis();. You cannot change it's declaration without digging into Sun's proprietary and native code which would make this an exercise of reverse engineering and hardly a stable approach.
All recent SUN JVM crash with the following error:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000, pid=4668, tid=5736
4# Use a custom ClassLoader (new test as suggested on the comments)
While trivial to replace the system CL using -Djava.system.class.loader JVM actually loads up the custom classLoader resorting to the default classLoader and System is not even pushed trough the custom CL.
public class SimpleClassLoader extends ClassLoader {
public SimpleClassLoader(ClassLoader classLoader) {
super(classLoader);
}
#Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return super.loadClass(name);
}
}
We can see that java.lang.System is loaded from rt.jar using java -verbose:class
Line 15: [Loaded java.lang.System from C:\jdk1.7.0_25\jre\lib\rt.jar]
I'm running out of options.
Is there some approach I'm missing?
You could use an AspectJ compiler/weaver to compile/weave the problematic user code, replacing the calls to java.lang.System.currentTimeMillis() with your own code. The following aspect will just do that:
public aspect CurrentTimeInMillisMethodCallChanger {
long around():
call(public static native long java.lang.System.currentTimeMillis())
&& within(user.code.base.pckg.*) {
return 0; //provide your own implementation returning a long
}
}
I'm not 100% sure if I oversee something here, but you can create your own System class like this:
public static class System {
static PrintStream err = System.err;
static InputStream in = System.in;
static PrintStream out = System.out;
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
System.arraycopy(src, srcPos, dest, destPos, length);
}
// ... and so on with all methods (currently 26) except `currentTimeMillis()`
static long currentTimeMillis() {
return 4711L; // Your application specific clock value
}
}
than import your own System class in every java file. Reorganize imports in Eclipse should do the trick.
And than all java files should use your applicatikon specific System class.
As I said, not a nice solution because you will need to maintain your System class whenever Java changes the original one. Also you must make sure, that always your class is used.
As discussed in the comments, it is possible that option #3 in the original question has actually worked, successfully replacing the default System class.
If that is true, then application code which calls currentTimeMillis() will be calling the replacement, as expected.
Perhaps unexpectedly, core classes like java.util.Timer would also get the replacement!
If all of the above are true, then the root cause of the crash could be the successful replacement of the System class.
To test, you could instead replace System with a copy that is functionally identical to the original to see if the crashes disappear.
Unfortunately, if this answer turns out to be correct, it would seem that we have a new question. :) It might go like this:
"How do you provide an altered System.currentTimeMillis() to application classes, but leave the default implementation in place for core classes?"
i've tried using javassist to remove the native currentTimeMills, add a pure java one and load it using bootclasspath/p, but i got the same exception access violation as you did. i believe that's probably because of the native method registerNatives that's called in the static block but it's really too much to disassemble the native library.
so, instead of changing the System.currentTimeMills, how about changing the user code? if the user code already compiled (you don't have source code), we can use tools like findbugs to identify the use of currentTimeMillis and reject the code (maybe we can even replace the call to currentTimeMills with your own implementation).

ArrayOfXXX class out of soap input param of array type

I have a method with input param as Array. When I generate stub out of it creates List type.
But I want to know how to create a wrapper class around array type e.g. for class Apple it should create ArrayOfApple.
Is there any change needs to be done in class or any specific plugin need to be used?
Note: I am using JAXWS with Apache CXF implementation
Below is the sample code:
EmployeeService.java:
#WebService(endpointInterface="com.test.EmployeeService")
#SOAPBinding(style=Style.DOCUMENT)
public class EmployeeService {
public String updateEmpRoles(#WebParam(name="EmpRoles")EmpRole[] empRoles) {
return "SUCCESS";
}
}
EmpRole.java :
#XmlType(name="EmpRole")
public class EmpRole {
private String empRole;
public String getEmpRole() {
return empRole;
}
public void setEmpRole(String empRole) {
this.empRole = empRole;
}
}
After publishing, wsdl is getting generated as below -
But what I expect is WSDL should create ArrayOfEmpRole and it should wrap List<EmpRole>.
Kindly help
In short - I want something that Björn doesn't want in below link. (In his case, it's automatically creating ArrayOfXXX, this is what I need) - Arrays in SOAP method Parameters generated via JAX-WS?
I would switch from Code first to a Contract first approach which means start with the WSDL and generate a stub using wsdl2java from it. This way you can ensure that the WSDL looks like the way you want.
If you want to stick to the current approach, the easiest way to achieve a wrapper is probably to introduce another class.

Extension method information from Roslyn

I am trying to using Roslyn to extract various method call information from a give source file. To elaborate - I want to find all method invocations that happen inside the input file.
One problem I am hitting is to do with extension methods. Consider any Linq method like Aggregate, Sum etc. How can I figure out from an InvocationExpressionSyntax that the method being invoked is an extension method and not a simple member method of the class.
The source file I input can be expected to compile - meaning that GetDiagnostics() will not have any errors.
---- Some code to get to the property mentioned by #Kevin in his answer ----
var methodInfo = model.GetSymbolInfo(invocation);
if (methodInfo.Symbol != null)
{
var mSymbol = (IMethodSymbol)methodInfo.Symbol;
if (mSymbol.ReducedFrom != null)
{
// this is an extension method !
}
}
You can find the actual static extension method for an instance invocation of an extension method using the IMethodSymbol.ReducedFrom property.

Luabind objects disapearing when I enter a new file

I'm using Luabind to bind my Lua scripts to my C++ engine. (it uses lua 5.1.4)
I added a new lua script called "controller.lua" which my entities script, called "cat.lua", will reference and use. One the c++ calls the method "Update" it's all in the hands of Lua.
But once I try to pass my binded c++ methods to the new script file, it feels like all the bindings from that c++ object disapear. I get the following error:
Expression: scripts/controller.lua:5(method MoveUp)
scripts/controller.lua:5: attempt to call method 'GetComponent' (a nil value)
Here is some C++ snippets
// Definitions
module(luaState)
[
class_<Entity>("Entity")
.def("GetComponent", &Entity::GetComponent)
class_<Component>("Component")
.enum_("eComponentTypes")
[
value("Steering", kComponentType_Steering)
],
class_<SteeringComponent>("SteeringComponent")
];
// The script components update
void ScriptComponent::Update() {
const Entity* owner = this.GetOwner();
mLuaDataTable["Update"](owner); // Executes the Update function on the script Cat.lua
}
The entities code being called by c++ (When it executes it returns the Cat table to c++.)
-- Cat.lua
local controller = loadfile("scripts/controller.lua")
local Cat = {}
function Cat.Update(entity)
steeringComponent = entity:GetComponent(Component.Steering) -- Works fine
controller:MoveUp(entity)
end
return Cat
and the Controller
--controller.lua
local up = vec2(0.0, 1.0)
local Controller = {}
function Controller.MoveUp(entity)
steeringComponent = entity:GetComponent(Component.Steering) -- Fails
end
return Controller
Bonus points:
When I make a change to the controller that doesn't work (like if I just threw an s character anywhere), the controller loads up nil, no warnings. Is there some way to make it throw warnings?
Is there a better way I should be doing to "link" to other lua files, like the way im working with Controller?
Thanks to ToxicFrog on Freenode chat for helping me figure this one out.
Basically: I was calling controller MoveUp like so:
controller:MoveUp(entity)
which of course translates into
controller.MoveUp(controller, entity)
and the function was defined as
function Controller.MoveUp(entity)
this "entity" was accepted as the first parameter, controller, while the actual entity is discarded per spec.
http://lua-users.org/wiki/ObjectOrientationTutorial

Creating a new instance from within CFC

Now this would seem to be something very straight forward, but seemingly not so in ColdFusion. I need to create an instance of a CFC from within itself as in var a = new this() but this obviously does not work. The CFC name can't be used as it is a base that will be extended so I am attempting a hack around the issue with the following:
component {
public function subQuery (required string table) {
var classPath = getMetaData(this).fullname;
return createObject("component", classPath).init(table, this.dsn);
}
}
This would be acceptable but the class path returned from getMetaData(this).fullname is incorrect. The CFC is within a folder named with a hypen as in my-folder and the returned path looks like my.-folder.myCFC with a period inserted before the hyphen. Obviously I could manipulate this string with a Regex but that is just not a road I want to go down.
Hoping someone has a cleaner approach, thanks.
You should be able to do it without any context on the object name in theory, as it will be being executed from within itself and it should check its current directory.
The following should therefore do the job you need
var classPath = ListLast(getMetaData(this).fullname,'.');
return createObject("component", classPath).init(table, this.dsn);
This way it doesn't matter what the directory names are, and it will work on any objects that extend that one regardless of directory structure, or for a complete example
public function cloneMe() {
return CreateObject('component', ListLast(getMetaData(this).fullname,'.')).init(argumentCollection=arguments);
}
This way any arguments passed in will be passed through into the init. I.e. an extending CFC may redefine the method as the following (if you want errors when the init arguments aren't supplied)
public function cloneMe(required string table) {
return super.cloneMe(table=arguments.table,dsn=this.dsn);
}