Compile java sources inside J2EE component

Discussion in 'Java' started by Stefan Siegl, Sep 7, 2004.

  1. Stefan Siegl

    Stefan Siegl Guest

    Hello,

    For my master thesis I have to create a customer relationship management
    system (CRM). The final program should be a J2EE component. The
    interesting part of this system is that the user can specify the data
    schema (model) of the CRM system at runtime. To define this model I
    created a metamodel. In order to allow an easy access to the model, I
    will generate java source classes according to the model (that is
    defined as instances of the meta classes). One problem is that the user
    is allowed to change the model at runtime, meaning that the source code
    files have to be recreated and compiled again.

    So much for the introduction ;). After creating the source files I need
    to compile them at runtime, is there a possibility to do so?

    As I said before if the model changes, the new source code files need to
    be compiled again. Is there a way to "unload" possible classes that were
    created for the last model, so that there won't be a clash with the
    newly created classes?

    Any suggestions?
    Best regards,
    Stefan
     
    Stefan Siegl, Sep 7, 2004
    #1
    1. Advertising

  2. On Tue, 07 Sep 2004 09:39:13 +0200, Stefan Siegl wrote:

    > After creating the source files I need
    > to compile them at runtime, is there a possibility to do so?


    Yes, but only by invoking classes for which
    Sun issues no public documentation, and
    reserves the right to change at any time.

    > As I said before if the model changes, the new source code files need to
    > be compiled again. Is there a way to "unload" possible classes that were
    > created for the last model, so that there won't be a clash with the
    > newly created classes?


    I am on unfamiliar ground here, but you
    might try using a custom class loader,
    and refreshing it.

    Better suggestions are probably forthcoming.

    But.. why does a CRM need to compile source
    'on the fly', it seems like you might be
    approaching the problem wrong. (And again,
    I am not that experienced with the area,
    but it has a strong whiff of 'overkill'.)

    --
    Andrew Thompson
    http://www.PhySci.org/ Open-source software suite
    http://www.PhySci.org/codes/ Web & IT Help
    http://www.1point1C.org/ Science & Technology
     
    Andrew Thompson, Sep 7, 2004
    #2
    1. Advertising

  3. On Tue, 07 Sep 2004 08:48:30 GMT, Andrew Thompson wrote:
    > On Tue, 07 Sep 2004 09:39:13 +0200, Stefan Siegl wrote:
    >> After creating the source files I need
    >> to compile them at runtime, is there a possibility to do so?

    >
    > Yes, but only by invoking classes for which Sun issues no public
    > documentation, and reserves the right to change at any time.


    Sun does advise against using classes in the sun.* hierarchy.

    However this Sun article showing how to use com.sun.tools.javac.Main
    to compile code from within a Java program seems to imply that the
    advice doesn't hold for the com.sun.* classes:

    http://java.sun.com/developer/JDCTechTips/2003/tt0722.html#2

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Sep 7, 2004
    #3
  4. Stefan Siegl

    jungi Guest

    Andrew Thompson wrote:
    > On Tue, 07 Sep 2004 09:39:13 +0200, Stefan Siegl wrote:
    >
    >
    >>After creating the source files I need
    >>to compile them at runtime, is there a possibility to do so?

    >
    >
    > Yes, but only by invoking classes for which
    > Sun issues no public documentation, and
    > reserves the right to change at any time.


    Not only. You can also use
    java.lang.Runtime.getRuntime().exec("javac", ...) or
    java.lang.Runtime.getRuntime().exec("jikes", ...), see Runtime javadoc.
    Other option is for example using KJC (part of Kopi
    (http://www.dms.at/kopi/)) it was not too fast 1,5 year ago, but authors
    improved it(i hope), and it had public API (should be still
    public).You can maybe find other compilers for java by googling ;-)

    --jungi

    >
    >
    >>As I said before if the model changes, the new source code files need to
    >>be compiled again. Is there a way to "unload" possible classes that were
    >>created for the last model, so that there won't be a clash with the
    >>newly created classes?

    >
    >
    > I am on unfamiliar ground here, but you
    > might try using a custom class loader,
    > and refreshing it.
    >
    > Better suggestions are probably forthcoming.
    >
    > But.. why does a CRM need to compile source
    > 'on the fly', it seems like you might be
    > approaching the problem wrong. (And again,
    > I am not that experienced with the area,
    > but it has a strong whiff of 'overkill'.)
    >
     
    jungi, Sep 7, 2004
    #4
  5. On 7 Sep 2004 11:10:12 +0200, Gordon Beaton wrote:
    > However this Sun article showing how to use com.sun.tools.javac.Main
    > to compile code from within a Java program seems to imply that the
    > advice doesn't hold for the com.sun.* classes:


    Ok I spoke too quickly, the article does seem to include a warning
    about using those classes too, although I'm certain it didn't when I
    first read it a year ago.

    It does refer to an API expected in 1.5 though. Could this be it?

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Compiler.html

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Sep 7, 2004
    #5
  6. Stefan Siegl

    Chris Uppal Guest

    Stefan Siegl wrote:

    > So much for the introduction ;). After creating the source files I need
    > to compile them at runtime, is there a possibility to do so?


    Yes. You can invoke Sun's compiler directly (I can't remember the precise
    class off-hand, but it's mentioned in another thread in this newsgroup today).
    Andrew's warning is to be taken seriously, but I wouldn't let it worry /me/ --
    I believe that Sun are intending to provide a public API to compilation soon
    (and that it only missed 1.5 because of time pressure), so I'd hope that if Sun
    do remove the private classes, then they'll replace them with something else
    you can use. You can always fall back to using javac if it really becomes
    necessary, anyway.

    However, if /I/ were doing this then I think I'd look at the option of
    interpreting the meta-model directly, rather than generating new classes. I
    think that would be easier, and I can't imagine it causing performance
    problems. Still, there's nothing wrong with generating classes, if that's
    what appeals to you, so...

    > As I said before if the model changes, the new source code files need to
    > be compiled again. Is there a way to "unload" possible classes that were
    > created for the last model, so that there won't be a clash with the
    > newly created classes?


    You need to load all the "disposable" classes through a specially created
    classloader (the standard URLClassLoader, or whatever it's called, should work
    OK, but you might want to write your own anyway). When you drop the reference
    to the classloader, and when there are no more instances of the classes
    themselves alive, then the classes will be removed from the runtime. When you
    want to create a new batch of classes, you create a new classloader to load
    them, so there's no interference with any defunct classes that might still be
    hanging around.

    You'll probably find it worthwhile to define a bunch of interfaces that are
    /not/ disposable, and which the various generated classes implement. Otherwise
    you'll have difficulty "talking about" instances of the disposable classes in
    other contexts.

    One thing that isn't helped by classloaders is migrating the state of the
    system as it is modified. If you create a new "version" of a class, the
    instances of the existing class won't be migrated. You'll have to transfer the
    state of the system from the old collection of objects to the new. Somehow...

    Again, I think that migration would probably be easier if you were interpreting
    the meta-model, and that's one reason why I'd consider that first.

    -- chris
     
    Chris Uppal, Sep 7, 2004
    #6
  7. Stefan Siegl

    Stefan Siegl Guest

    Andrew Thompson wrote:

    > On Tue, 07 Sep 2004 09:39:13 +0200, Stefan Siegl wrote:
    >
    >
    >>After creating the source files I need
    >>to compile them at runtime, is there a possibility to do so?

    >
    >
    > Yes, but only by invoking classes for which
    > Sun issues no public documentation, and
    > reserves the right to change at any time.
    >
    >
    >>As I said before if the model changes, the new source code files need to
    >>be compiled again. Is there a way to "unload" possible classes that were
    >>created for the last model, so that there won't be a clash with the
    >>newly created classes?

    >
    >
    > I am on unfamiliar ground here, but you
    > might try using a custom class loader,
    > and refreshing it.


    I hope this is possible, I will give it a try, but I suspect that it
    will not be that easy. I just thought that it must be possible to unload
    the classes, because other Java application can do it too, i.e. the
    JBoss app server with its hotdeploy feature.

    > Better suggestions are probably forthcoming.
    >
    > But.. why does a CRM need to compile source
    > 'on the fly', it seems like you might be
    > approaching the problem wrong. (And again,
    > I am not that experienced with the area,
    > but it has a strong whiff of 'overkill'.)


    The central requirement of the system is that the user should be allowed
    to define his specific CRM model at runtime. Therefore a metamodel is
    provided by me to define the general constructs a model can have (like a
    class, associations, and so on). The model will then be represented by
    instances of these metaclasses. based on this model the user is allowed
    to insert/query/delete data.

    The problem is that the handling of model is not easy if the model is
    stored as meta instances, because then i do not have a nice connection
    between the entered data and the model. That is why I wanted to have
    java classes that represent this model and instances of this model to
    represent the data. Using this approach I can directly check if the
    rules of the models are kept within the offered data.
     
    Stefan Siegl, Sep 7, 2004
    #7
  8. Stefan Siegl

    Chris Uppal Guest

    Gordon Beaton wrote:

    > It does refer to an API expected in 1.5 though


    I'm pretty sure I remember Neil saying here that the compiler interface was
    dropped from 1.5 for lack of time.

    > Could this be it?
    >
    > http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Compiler.html


    That is, I think, part of the architecture for allowing the JVM to host
    pluggable JITs.

    -- chris
     
    Chris Uppal, Sep 7, 2004
    #8
  9. On 7 Sep 2004 11:17:54 +0200, Gordon Beaton wrote:

    (Compile from within Java)
    > http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Compiler.html


    ...hmmm, dunno. It does not look like it,
    (it mentions hooks to alternate compilers),
    I would have to play with it to be sure,
    though what Chris was saying, suggests that
    whatever changes were in the pipeline missed 1.5.

    --
    Andrew Thompson
    http://www.PhySci.org/ Open-source software suite
    http://www.PhySci.org/codes/ Web & IT Help
    http://www.1point1C.org/ Science & Technology
     
    Andrew Thompson, Sep 7, 2004
    #9
  10. On Tue, 7 Sep 2004 10:50:29 +0100, Chris Uppal wrote:

    > Andrew's warning is to be taken seriously, but I wouldn't let it worry /me/ --


    (chuckles) It did not slow me down.

    I figure Sun would only change those classes
    if they saw good reason to do so, and given
    they have been in the same place/form through
    a number of releases, it suggests they are happy
    with them as is.

    <big snip>
    > One thing that isn't helped by classloaders is migrating the state of the
    > system as it is modified. If you create a new "version" of a class, the
    > instances of the existing class won't be migrated.


    At first I thought Serialize them, but then
    it struck me that this is one case where
    Sun's warning on serialization would become
    relevant. The class files change.

    XMLEncoder?

    --
    Andrew Thompson
    http://www.PhySci.org/ Open-source software suite
    http://www.PhySci.org/codes/ Web & IT Help
    http://www.1point1C.org/ Science & Technology
     
    Andrew Thompson, Sep 7, 2004
    #10
  11. Stefan Siegl

    Stefan Siegl Guest

    Chris Uppal wrote:

    Hi Chris, thanks for your thoughts about the topic :)

    > Stefan Siegl wrote:
    >
    >
    >>So much for the introduction ;). After creating the source files I need
    >>to compile them at runtime, is there a possibility to do so?

    >
    >
    > Yes. You can invoke Sun's compiler directly (I can't remember the precise
    > class off-hand, but it's mentioned in another thread in this newsgroup today).
    > Andrew's warning is to be taken seriously, but I wouldn't let it worry /me/ --
    > I believe that Sun are intending to provide a public API to compilation soon
    > (and that it only missed 1.5 because of time pressure), so I'd hope that if Sun
    > do remove the private classes, then they'll replace them with something else
    > you can use. You can always fall back to using javac if it really becomes
    > necessary, anyway.
    >
    > However, if /I/ were doing this then I think I'd look at the option of
    > interpreting the meta-model directly, rather than generating new classes. I
    > think that would be easier, and I can't imagine it causing performance
    > problems. Still, there's nothing wrong with generating classes, if that's
    > what appeals to you, so...


    I also thought about that, but there are also drawbacks.

    The model and the data is not tightly connected. If just have instances
    of meta classes and data (inside generic DTO's with a HashMap that
    stores key (=attribute name) and value (=value of the attribute)), I
    still have to check if this data is valid according to the model. If I
    would have classes I could use the Java Reflection and just try to set
    these attributes according to the given generic DTO. The check will then
    be done through the Reflection mechanism.

    What I did not describe so far is that my meta model allows to add rules
    to the model. This should provide the possiblity to put constraints on
    the model (i.e. each employee be older than 18). During the code
    generation I could create checks for these rules and inform the caller
    using an exception if he does not stick to these rules. If I use the
    meta model instances I additionally have to check these rules. An other
    idea I had for rules is to allow derivation rules to define how derived
    attributes are defined. This could also done with code generation but is
    much more complex when just checking the metamodel.

    The last thing is that the persistence will get a bit more complex.

    But I will thing about that again. Perhaps the code generation,
    compilation and unloading are much more complex so that this does not
    justify that approach.

    > One thing that isn't helped by classloaders is migrating the state

    of the
    > system as it is modified. If you create a new "version" of a class, the
    > instances of the existing class won't be migrated. You'll have to transfer the
    > state of the system from the old collection of objects to the new. Somehow...
    >
    > Again, I think that migration would probably be easier if you were interpreting
    > the meta-model, and that's one reason why I'd consider that first.


    This class and object lifecycle is not directly part of my master
    thesis, meaning that I do not have to provide a complete and working
    solution for that (which does not mean, that I do not want to do that
    *g*). Currently I was thinking that I will just store the database
    storing the old data and create a new database for the new schema and
    provide a way to read the old data and transfer them to the new schema.

    >
    > -- chris


    Thanks again,
    Stefan
     
    Stefan Siegl, Sep 7, 2004
    #11
  12. On Tue, 07 Sep 2004 12:01:39 +0200, Stefan Siegl wrote:

    >> I am on unfamiliar ground here, but you
    >> might try using a custom class loader,
    >> and refreshing it.

    >
    > I hope this is possible, I will give it a try, but I suspect that it
    > will not be that easy.


    Way no. It's p*ss easy. I defined my
    own URLClassLoader that came to about
    two dozen lines. Look at the example
    in the JavaDocs for ClassLoader.. it
    is almost there, as is.

    --
    Andrew Thompson
    http://www.PhySci.org/ Open-source software suite
    http://www.PhySci.org/codes/ Web & IT Help
    http://www.1point1C.org/ Science & Technology
     
    Andrew Thompson, Sep 7, 2004
    #12
  13. On Tue, 07 Sep 2004 12:01:39 +0200, Stefan Siegl wrote:

    (A.T.)
    >> But.. why does a CRM need to compile source
    >> 'on the fly', it seems like you might be
    >> approaching the problem wrong.

    ....
    > The central requirement of the system ..


    Whoop.. Whoa-up there. If nobody else in this
    thread seems concerned with it, it suggests to
    me I was wrong.

    '..as you were.'

    --
    Andrew Thompson
    http://www.PhySci.org/ Open-source software suite
    http://www.PhySci.org/codes/ Web & IT Help
    http://www.1point1C.org/ Science & Technology
     
    Andrew Thompson, Sep 7, 2004
    #13
  14. Stefan Siegl

    Sudsy Guest

    Stefan Siegl wrote:
    <snip>
    > What I did not describe so far is that my meta model allows to add rules
    > to the model. This should provide the possiblity to put constraints on
    > the model (i.e. each employee be older than 18). During the code
    > generation I could create checks for these rules and inform the caller
    > using an exception if he does not stick to these rules. If I use the
    > meta model instances I additionally have to check these rules. An other
    > idea I had for rules is to allow derivation rules to define how derived
    > attributes are defined. This could also done with code generation but is
    > much more complex when just checking the metamodel.

    <snip>

    I was half way through this paragraph when it hit me: you could do all
    of this with XML Schema and a validating parser! You don't have to re-
    invent the wheel and there are oodles of tools available. You could
    probably even find an Eclipse plug-in for editing the Schema.
    Just thowing out the idea for your consideration.
     
    Sudsy, Sep 7, 2004
    #14
  15. Stefan Siegl

    Will Hartung Guest

    "Stefan Siegl" <> wrote in message
    news:...

    > The central requirement of the system is that the user should be allowed
    > to define his specific CRM model at runtime. Therefore a metamodel is
    > provided by me to define the general constructs a model can have (like a
    > class, associations, and so on). The model will then be represented by
    > instances of these metaclasses. based on this model the user is allowed
    > to insert/query/delete data.
    >
    > The problem is that the handling of model is not easy if the model is
    > stored as meta instances, because then i do not have a nice connection
    > between the entered data and the model. That is why I wanted to have
    > java classes that represent this model and instances of this model to
    > represent the data. Using this approach I can directly check if the
    > rules of the models are kept within the offered data.


    As others have mentioned, ClassLoaders are what you need here. You can
    compile the code using either the "unsupported" sun classes, or forking a
    javac command.

    One other thought though, have you thought about implementing any of this in
    an embedded scripting language?

    Embedding Javascript or Python or Scheme is fairly trivial and they're a lot
    more lax about having their objects gratuitously changed behind their backs.
    They also have their own compiler/interpreters, so you just need to load the
    source code and go rather than fighting with javac and ClassLoaders (instead
    you get to fight with environments and what not with the embedded
    language -- similar issues, but perhaps less complicated overall).

    The real issue is if objects "leak out" of your custom ClassLoader, things
    can get Weird really quickly.

    Plus, technically, you're not supposed be playing games with ClassLoaders
    and what not, at least not at the EJB tier (which has a very complicated
    ClassLoader structure). Less of a problem in something like Tomcat.

    I acknowledge that this is all a Master Thesis, and it doesn't need to be
    bullet proof or production quality, etc, it just Needs To Work.

    But I'd consider any of the several scripting languages in your project.

    Regards,

    Will Hartung
    ()
     
    Will Hartung, Sep 8, 2004
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alfonso Melchionna

    how compile sources VB.NET & C# with command line?

    Alfonso Melchionna, Nov 19, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    5,876
    John Azzolina
    Dec 3, 2004
  2. jprintout sales
    Replies:
    0
    Views:
    426
    jprintout sales
    Feb 17, 2005
  3. Nagaraj
    Replies:
    1
    Views:
    876
    Lionel B
    Mar 1, 2007
  4. Replies:
    2
    Views:
    323
    Ingo R. Homann
    Mar 28, 2007
  5. Rajive Narain
    Replies:
    0
    Views:
    1,347
    Rajive Narain
    Sep 18, 2009
Loading...

Share This Page