• Post Reply Bookmark Topic Watch Topic
  • New Topic

manipulating java code within program  RSS feed

 
Vincent Goh
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi
I'm trying to manipulate java source code file by adding a method in existing .java file within a running java program.


I thought maybe converting the to XML then manipulate the XML then convert back to .java is the easiest, although there is significant work involved.

any suggestion?
 
Mark Dexter
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi. Are you trying to do this at design time or at runtime? In other words, are you trying to process java source as text during the development process? In this case, you could do it a variety of ways. It would be some type of text processing. You could look at Eclipse, which already does a lot of source-code processing. And you can see exactly how they do it via Eclipse's source code. Hope this helps. Mark Dexter
 
Vincent Goh
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi there,
thanks for reply.
I'm trying to do this at runtime of a program who try to modify the source code of a java file.

So i'm looking for some library which would allow me to parse the code and add method to it, without too much hassle.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the purpose of modifying the source file?

It would be easier to modify the class file using a Library like Javassist.
 
Francesco Bianchi
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Vincent Goh:

I'm trying to do this at runtime of a program who try to modify the source code of a java file.


Hi. I had a personal project I wanted built around such a feature. It seems that it is not possible in Java, at least up to version 1.5 for many design choices. The only existing solution I'm conscious of is a library which from some specific source (usually a XML), creates a source code, compiles it at fly and runs it calling the classloader for the just generated bytecode. No way to skip the "bytecode generation" step.

A little hint but it's just an idea... not compiled languages usually have such a feature. The newer version of javascript, for example, allows you to do it. And Java 6 has a Script Interpretetation Engine built in. And I know about some OpenSource projects about a Javascript Engine. Probably this is the only way you can accomplish what you desire to.

Hope it helps somehow,
Francesco.
 
Vincent Goh
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Bianchi Francesco:
It seems that it is not possible in Java, at least up to version 1.5 for many design choices.


hi Francesco
thanks alot for reply.
I've been trying to google but still find nothing about it.

can you tell me in more details why it is not possible? I'm really curious about this, so I can tell me colleague about it too.

thanks alot,
vincent
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You still haven't told us why you want to modify the source code of a Java file. Depending on that, all kinds of things may be possible.

Would this be a class that is already running in the JVM? Should it be loaded after it has been modified? Is this just a source file on the hard disk that you want to modify, with no intention of loading at afterwards?

All of these are possible -with varying degrees of difficulties-, so tell us what it is that you actually want to do.
 
Francesco Bianchi
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Vincent Goh:

can you tell me in more details why it is not possible?


I don't have 100% guaranteed answers so take the following just as personal thoughts.

Java is a typed language designed to handle enterprise application. In an enterprise wide scenario, performance (especially memory consumption) are often not an issue. What is really crucial here is the reliability of the application, code clearness, maintainance easiness. For these reasons they build up a system which runs on a managed environment which really cares about errors and abnormal situations handling. But what Java engineers did does not end here. They decided to make it a typed language that means that an object is only ONE object at time. Of course through interfaces and inheritance it can SEEM to see object like having multiple faces..but if you really consider the thing..you will see that you are simply seeing views which are SUBSETS of the function of the real object you are using. So, when you write something like this:


when you use it in a piece of code like this:


you will be always playng with a MyClass instance by in case of test1, you will only see Object methods. Test2 will make you able to use every method the instance really implements. test 3 will show you uniquely the Interface method. In any case...the compiler will ALWAYS be sure about the REAL EXISTENCE of the method you will be calling. This translates in avoiding a bunch of exception. Detecting errors at compile time makes an application much safer (and writing it much easier/quickier and therefore cheaper).

Moreover, in this way you will always know at compile time which methods will be provided for the TYPE of reference you are using.

And what about interfaces? They are the Java implementation of a well documented design pattern to enhance reusability, realiability and avoiding coupling. What they give to you is the confidence about the methods a particular implementation of the interface will expose.

Now imagine that you can add or remove some methods at runtime, change their signature, changing implementation. You would lose all these benefits. You will not be sure anymore about the behaviour of an application. Let's suppose you are such a capable programmer to avoid malfunctions... (NoSuchMethodException, IllegalTargeException, InvocationException etc..). You will stille have big problems when to go for maintainance: do you think such a code would be of easy read? Wouldn't it sound a bit "spaghetti style"? In some certain cases you wouldn't even know which methods will be called or even exist.

These last motivation are among the ones plead by Java implementors for descouraging the use of Reflection/Introspection package if not in special circustamces. Try to use it a bit and you will see how obscure the application behaviour becomes and how many kind of Exceptions you'll have to handle

A last consideration: the only case in which I would find a real need for what you want to implement is an almost completely visual IDE which allows you to run a class and add/change methods to it at runtime without the need to restart the application or the application server. Or, of course, for merely academic purposes. In any other case, if you find out you have this need, I suggest you to consider doing another analisys stage and/or try to modify your application architecture.

Sorry for being so verbose...but I find the topic to be really interesting, stimulating and hard to expose clearly.

Cheers,
Francesco.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Indeed, it's not possible to modify an existing object, but it is possible to have a JVM using objects of class A, then to change class A, and later on have the JVM use objects of the new type A. It's going to take some juggling of classloaders (and some careful coding), but it is possible.

A simple example of this are servlet containers that can reload web applications (possibly containing changed classes) without the server having to shut down.

Vincent hasn't told what exactly he is trying to do, so we don't know whether his problem is of the kind you describe, or along the lines of what I describe above.
 
Francesco Bianchi
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ulf Dittmer:
It's going to take some juggling of classloaders (and some careful coding), but it is possible.


Thanks alot, really a great hint to spend some time wondering about


Originally posted by Ulf Dittmer:

Vincent hasn't told what exactly he is trying to do, so we don't know whether his problem is of the kind you describe, or along the lines of what I describe above.


Right and probably is more probably following your line instead of mine. But I was just answering about his question on "why is this limitation deliberately imposed by design?"

By the way...what's your opinion about my thoughts? Do you think I'm on the right track?

Thanks in advance
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By the way...what's your opinion about my thoughts? Do you think I'm on the right track?


You're certainly right about the reasons why it would wreak havoc if it was possible to change class methods and fields from underneath an existing object.

I think you're getting a little off track where you speculate about how it would have to work if it was indeed possible (namely, by using introspection and reflection). Because the only way it would work (and indeed can work in certain circumstances) -namely, involving classloaders- doesn't have those issues.
 
Vincent Goh
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi guys,
i want to say thank you and so sorry for the late reply.
I did not have internet access until today due to changing landlord etc, all the broadband got cutted off, now i have to pay my own wireless line

anyway, I'm doing this agent technology as my master thesis. One part of it is to for agent A to request code from agent B to execute for certain task.

I wish to transport the code in plain code instead of compiled bytecode, simply because TRUST is another issue with agents, same as you wouldn't want to help a stranger to carry a handbag through the customs at the airport, would you?

plain code is easily readable by human, thus reduce risks associated with executing the code received from agent B.

hope that clear things up abit.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That sounds interesting. One of the things you can do to lower the risk introduced by foreign code is to use a classloader in combination with a security manager. That way you can control in a very fine-grained manner what the foreigh code is allowed to do, and what not. I've written a little article about that here (it also has example code that demonstrates the concept.)
 
William Brogden
Author and all-around good cowpoke
Rancher
Posts: 13078
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This sounds to me like an ideal spot to use a scripting language. Lots of activity going on in scripting languages for Java.

Groovy - well integrated with the Java standard library
Jython - java version of Python - a well regarded scripting language.
JRuby - getting lots of publicity these days.

Plus countless others!
Bill
 
Francesco Bianchi
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Vincent Goh:

plain code is easily readable by human, thus reduce risks associated with executing the code received from agent B.


Sorry...I have a question a bit out of topic.. Could anyone explain me why should plain code be safer than bytecode when we a decompiler can easily convert from the compiled code to the original text? Ok...maybe obfuscation can reduce readibilty...but everything it does is changing variable names... And, again, I don't think people will read the code before it get executed... and once it has run..probably there is no so much need to still know if it is safe or unsafe.

Wouldn't be enough giving permissions only to signed/certified code?

Hope you don't misunderstood me.. Don't want to say you are all wrong. I simply cannot see what all of you are seeing as obvious..

Could you make it clearer to me please?

Thanks, Francesco.
 
Vincent Goh
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Bianchi Francesco:


Sorry...I have a question a bit out of topic.. Could anyone explain me why should plain code be safer than bytecode when we a decompiler can easily convert from the compiled code to the original text? Ok...maybe obfuscation can reduce readibilty...but everything it does is changing variable names... And, again, I don't think people will read the code before it get executed... and once it has run..probably there is no so much need to still know if it is safe or unsafe.

Wouldn't be enough giving permissions only to signed/certified code?

Hope you don't misunderstood me.. Don't want to say you are all wrong. I simply cannot see what all of you are seeing as obvious..

Could you make it clearer to me please?

Thanks, Francesco.


hey
thanks for reading.
what you said was correct.
I could have use bytecode, signed code and it should be safe. but i didn't have experience in that area, so I never thought of it.
now that you mention it, i'll take a look and see if it's applicable in my research. thanks again.


however, I didn't find any decompiler library which allow me to decompile from within main executing program.
 
Vincent Goh
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
oh. the other reason i wanted to store it in plain code is because i want to re-use the code after the jvm exit.
although one can argue that i can re-use the .class file anyway. many options.


so how easily is it to retrieve a method's bytecode to send to another agent?
and what does bytecode look like?


thanks!
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Vincent Goh:
so how easily is it to retrieve a method's bytecode to send to another agent?
and what does bytecode look like?


Bytecode is what's in class files. You can't really send bytecode for just one method - you'd transfer the complete class file instead.

I wouldn't go down the route of decompilation. Decompiled code is generally hard to understand, so it's not very useful if you're trying to figure out if it's dangerous to run.

But you shouldn't have to. Check out security managers - they can limit what code can do on a very fine-grained level. That's really the proper way to handle untrusted code.
 
Francesco Bianchi
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ulf Dittmer:

I wouldn't go down the route of decompilation. Decompiled code is generally hard to understand, so it's not very useful if you're trying to figure out if it's dangerous to run.


Sorry, I cannot agree with you about this. It happened to me to need to decompile some code and it came out exactly as the original source code was (with the only exception of comments which, it seems, are lost forever and generics which are converted in what the really are, simple casts).
Decompiled classes, variables and methods had exactly the same names as in the original source. This would be not true only in case of obfuscated compiled code..but probably, in Vincent intentions, such a case would immediately be treated as unsafe code so there would not even be the need to read/understand it.

Or maybe I am missing something? If so, please, tell me. Don't know much about this topic but I find it really charming

Thanks in advance.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Bianchi Francesco:
This would be not true only in case of obfuscated compiled code..but probably, in Vincent intentions, such a case would immediately be treated as unsafe code so there would not even be the need to read/understand it.


Yes, I was assuming obfuscated code. If someone distributes class files, but does not want to distribute source code, then the code will generally be obfuscated. But even if it was perfectly decompiled, trusting people to spot something that does not want to be spotted would mean to place overly much confidence into that persons code-reading ability. Much better to let the JVM's mechanisms deal with it. The first use for security managers were for securing applets, which are a bit like the agents Vincent describes.
 
Francesco Bianchi
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Ulf
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!