9 Replies Latest reply: Jul 6, 2010 4:58 AM by 807580 RSS

    Compiling to a byte[]

    807580
      Hello, i was just wondering if it were possible to use the JavaCompiler provided in the javax.tools package and get the class data as a byte[] instead of creating a local file, and then having to read the file. My reason for asking is because I'm using a module system in my newest application, and inside the modules, there are imports and references to certain classes that aren't contained in the module, but WILL be loaded with my class loader. So what are my options?
        • 1. Re: Compiling to a byte[]
          807580
          Possibly, but possibly not. A glance at the javadocs suggests implementing the interface JavaFileManager yourself might help, but I haven't delved into it. Why don't you want to compile to a file? Performance? You could always use an [in-memory filesystem|http://commons.apache.org/vfs/filesystems.html#ram].
          • 2. Re: Compiling to a byte[]
            807580
            Well not only because I don't want the end user of my application to have to compile to have the modules to run, I also CAN'T compile the sources because they rely on other classes that isn't in the CURRENT classpath, but will be when my own ModuleLoader, which is a ClassLoader child loads them all into the memory.. I also don't want a bunch of class files floating around their computer. So what i want is for them to be able to take their sources, pack them into one jar, then the application reads each JarEntry, compile it, sends the byte[] to the defineClass method which loads the class data and creates a new instance of that class in the memory.

            Edited by: Zymus on Jul 6, 2010 1:41 AM
            • 3. Re: Compiling to a byte[]
              EJP
              You're barking up the wrong tree here. This is a job for interfaces.
              • 4. Re: Compiling to a byte[]
                807580
                What do you mean?
                • 5. Re: Compiling to a byte[]
                  807580
                  He means you're probably way over-engineering the solution. Why don't you explain to us why you think you need this compile-on-the-fly behaviour? Don't just insist you do, explain the problem you're solving with it.
                  • 6. Re: Compiling to a byte[]
                    807580
                    The reason I'm feel I need to compile into memory is because each module is separate from the others. My problem is that with the way i have it planned out, different modules will need to access classes from other modules. Each module it its own jar. So basically, for example, lets say i have some Modules, Networking, and Core. Inside Networking are the various types of packets, and there's also the PacketHandler interface. Core has the various packet handler implementations. Ping, Focus Changed, Mouse clicked, etc. Now, when each of these modules is loaded into my own ClassLoader, the references and imports will be completely valid, if and only if I compile them into memory. If i try to compile them other wise, using javac or JavaCompiler, I will get various errors, classes not being found, etc.
                    • 7. Re: Compiling to a byte[]
                      807580
                      Zymus wrote:
                      The reason I'm feel I need to compile into memory is because each module is separate from the others.
                      That's no reason to do anything at all with on-the-fly compilation, or classloaders.
                      My problem is that with the way i have it planned out, different modules will need to access classes from other modules. Each module it its own jar. So basically, for example, lets say i have some Modules, Networking, and Core. Inside Networking are the various types of packets, and there's also the PacketHandler interface. Core has the various packet handler implementations. Ping, Focus Changed, Mouse clicked, etc.
                      Pretty standard.
                      Now, when each of these modules is loaded into my own ClassLoader, the references and imports will be completely valid, if and only if I compile them into memory.
                      Why?
                      If i try to compile them other wise, using javac or JavaCompiler, I will get various errors, classes not being found, etc.
                      Why?
                      • 8. Re: Compiling to a byte[]
                        807580
                        1. I want the modules to be able to be reloaded without having to restart the app.
                        2. The reason they'll be valid is because my classloader will have loaded all the classes at the same time, and so to my knowledge, the classes in the modules will be able to "see" the other classes loaded in my class loader.
                        3. Because Core has different packet handlers, but the PacketHandler interface isn't in the Core module. It's in the Networking module. And I can't compile them separately because, well, i'm not setting the class path to include the other modules, because i want the modules to be source code only, and so it wouldn't be able to compile either way.
                        • 9. Re: Compiling to a byte[]
                          807580
                          Zymus wrote:
                          1. I want the modules to be able to be reloaded without having to restart the app.
                          Use OSGi

                          2. The reason they'll be valid is because my classloader will have loaded all the classes at the same time, and so to my knowledge, the classes in the modules will be able to "see" the other classes loaded in my class loader.

                          What does this have to do with on-the-fly, in-memory compilation?
                          3. Because Core has different packet handlers, but the PacketHandler interface isn't in the Core module. It's in the Networking module. And I can't compile them separately because, well, i'm not setting the class path to include the other modules, because i want the modules to be source code only, and so it wouldn't be able to compile either way.
                          Why do you want the modules to be source code only? Have you considered BeanShell?

                          Alarm bells are ringing here, because often when someone comes up with a fancy, convoluted design like this, involving exotic steps like code generation, or dynamic compilation, but don't know how to implement it, they've over-complicated things unnecessarily. Particularly, delivering source code for some sort of runtime compilation looks shiny and flexible to some people, but actually isn't the solution they're looking for. "Re-think this design" would be my advice.