I have a problem wit the software I'm working on.
We are accessing Windows system calls via JNA, and we have to define some Windows structure (Java class that extends the JNA Structure) to be able to access them.
The application has to work with 32-bit and 64-bit architecture, but the problem with the structures is that attributes in them change based on the system architecture (from int to long for example).
Is there an easy (and sane) way to do conditional compilation a-la #ifdef in Java using ant? Are there any other ways to achieve this kind of conditional #ifdef?
The other way we are contemplating is to create a general interface, create two different structures for 32-bit and 64-bit, and then handle the different case with some if-else.
Thanks.
Would the Ant condition clauses not do
http://ant.apache.org/manual/Tasks/condition.html
UPDATE:
I think I finally got what you're trying to do. Looking at the javac man here I don't think the Java compiler will let you do that, regardless of the conditions you put in Ant. Either way I found a post on stackoverflow on determining the system architecture and a thread on the sun forums that you might find helpful.
wwyt is a conditional compilation pre-processor for Java language. It accepts (commented out) directives like #if, #else, .... etc. It's a Windows command line tool and can be used as a pre-processor before calling Ant to make the build. (And after the build, it can restore the converted files back to their original state.) Not sure if this helps, just so you know. Link is here: http://www.adarian.com/wwyt
Related
I have a question which I'm pretty confused from.
I am aware of the differences between Java Runtime Enviroment and Java Developement Kit.
I'm writing a program that uses the ToolProvider.getSystemJavaCompiler() method to compile java code from within the code.
Now, I've been answered that I can't compile code from client side if my client doesn't have JDK installed. My main question is, how can I do that? I don't want my clients having to install JDK on their computer just to run my program.
Thanks in advance!
You need to compile it on your system, and distribute the class file of corresponding java source file to anyone.
That class file doesn't require JDK but JRE must be installed on that system to run the class file.
If you want to compile code, you need a compiler, so if the user can't be expected to have the compiler you need, you'll simply have to bundle it.
I really can't say I know how to bundle the standard javac compiler, though it's probably possible, strictly speaking, to find the Jar file that contains it and bundle that along with your code. No idea how robust such a solution would be, though.
But depending on your needs, you may not need the standard javac. There are tons of byte-code generation libraries out there, with more or less high-level functionality. I wouldn't really want to recommend anything that I have no personal experience with, but examples include Byte Buddy or ASM. You could probably use ABCL too.
Eclipse's compiler is worth a look as well.
There is also an so question here.
So there really is no way to do what it is you are wanting to do unless you bundle the compiler itself with you application, or unless you find a library that has all of the Java compiler code in it already so it doesn't have to use the JDK compiler, you will not get what you want, and what you want is the ability to turn a String containing source code into a Java class.
I do not understand what you wish to accomplish, but the BEST option I can give you is asm. If you are up for the task, you can manually write new classes at runtime without the presence of the JDK compiler. HOWEVER, this does not involve you using a String full of source code and turning it into a Class object. This is you working at the low level with the Java bytecode for the most part.
This tutorial can get you started:
https://www.javaworld.com/article/2071777/design-patterns/add-dynamic-java-code-to-your-application.html
And here is the Java documentation for class files. You can use this to expand on what you learned from the first link:
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
That is the only instance creating classes on the fly that I can give you. That being said, you could try writing your own Java compiler that can turn source code into classes without ever getting the Java compiler, but at that point you are literally recreating the Java compiler yourself, and I assure you that is no easy feat for one person.
I read about Java interoperability in Ruby, so using JRuby is an obvious choice. But somehow I don't really grasp the idea behind require 'java'. The documentation says:
... will give you access to any bundled Java libraries (classes within your java class path). However, this will not give you access to any non-bundled libraries.
Are there any more elaborated explanations?
To be more precise I don't understand why the following code works without require "java":
$ export CLASSPATH=".:lib/opennlp-tools-1.6.0.jar"
$ jruby -e 't = Java::OpennlpToolsTokenize::SimpleTokenizer.new; puts t.tokenize("I went to school").to_a'
There are two parts to this question which need answering and some clarification we should make to our documentation (I made an attempt already in https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby):
require 'java'. It loads the ability to load java classes and treat them as if they were Ruby objects/classes. However, Since JRuby 1.7.x, JRuby internally needs to require 'java' so it has already required 'java' by the time your expression is evaluated. So technically it is true that "require 'java'" loads Java interoperability, but since our kernel does this now it is largely a no-op by the time you call it (see return value of the require). We still recommend putting it at the top of any file where you use Java interop. just so it is documented in your code. Also, the fact that it happens to be loaded is more of an impl detail and not a semantic detail (e.g. in the distant future we maybe won't require it in our kernel).
Unclear verbiage: "However, this will not give you access to any non-bundled libraries.". So if you want to access a library not in your CLASSPATH (this was stipulated in the parenthesis) you need to add them to your LOAD_PATH (or via direct require'ing). I tweaked that sentence to hopefully make it more clear.
I'm thinking about trying to convert a Scons (Python) script to another build system but was wondering if there was a Python-analysis library available in order to 'interrogate' the Scons/Python script?
What I'm [possibly] after is something along the lines of Java's reflection mechanism, in fact, if this is possible via say Jython/Java, coding in Java, that would be best for me as a Java dev (I have no real background in Python).
What I need to be able to do is extract the variable assigment values etc. for certain named class types and methods within the script, so that I can transfer them to my new output format.
Any ideas?
Thanks
Rich
If your current scons files are very regular and consistent it may be easier to do something "dumb" with standard text-editing tools. If you want to get smarter, you should notice that scons is itself a Python program, and it loads your build files which are also Python. So you could make your own "special" version of scons which implements the functions your build scripts use (to add programs, libraries, whatever). Then you could run your build scripts in your "fake" scons program and have your functions dump their arguments in a format suitable for your new build system.
In other words, don't think of the problem in terms of analyzing the Python grammar completely--realize that you can actually run your build scripts as Python code and hijack their behavior.
Easier said than done, I'm sure.
I doubt it's the best tool for migrating scons, but python's inspect module offers some reflection facilities. For the rest, you can simply poke inside live classes and objects: Python has some data hiding but does not enforce access restrictions.
How does one start a Java VM from C? Writing the C code seems to be straigtforward -- I've been following the code that appears on p. 84 of Liang's "The Java Native Interface". It's the linking process that has me stymied. Liang's book is 10+ years out of date in that regard and I can't find anything on the net which addresses this goal (and which works).
To be clear, what I want to do is launch a standard windows program (written in C), which then launches the JVM and calls a main() in a Java class (which I have written). This program should not rely the presence of jvm.dll or jvm.lib -- the user shouldn't have to install Java to run the program. Maybe this isn't possible without an unreasonable amount of effort.
The development environment is MinGW under windows. I'm able to link in such a way that the program works when the .dll is in a separate file, but not in a way so that there's only a single executable without any .dlls or .libs.
In hindsight, I can see now that this was a dumb question, or at least one that hadn't been thought through. The moral of the story is that the "JVM" is not a single executable, or even an executable plus some JAR files; the JVM relies on a slew of independently stored files with various mutual dependencies. Unraveling all of these relationships so that they could be brought into a single file (or even two files) would be a massive undertaking. Thanks for the knock in the head.
So, to be clear - you want to launch a JVM without the requirement of a JVM being present? How do you propose to accomplish that? Unless you're contemplating writing your own JVM implementation (which I'd say falls under the category "unreasonable amount of effort"), having a JVM installed is a reasonable requirement. Assuming that, you can just spawn a java process and include the appropriate command-line parameters (classpath, class to run etc).
Disclaimer: I don't think that having a Java runtime installed is unreasonable for users. That said, I do understand your motivations for a low-friction install for users.
Using the Sun JRE is probably not going to be fruitful here. In theory, you could grab the Sun JRE, modify it to build as a static library instead of a DLL and figure out a way to cram all the resources that get bundled with it (fonts, images, cursors, SSL certificates, localized message files, etc.) into a single resource and then modify the runtime to load from there. But this is almost certainly an "unreasonable amount of effort."
You might want to look at GCJ instead: its architecture is different than the Sun JRE which lends itself more to being embedded in another application, or it can compile your Java to native machine code.
(Also, do check the licensing to ensure that you can properly redistribute this no matter which route you take.)
First, I have no experience doing this. But like the beginning of any good program, I have problem that I need to fix, so I'm willing to learn.
So many of you are probably already familiar with pdftk, the handy utility for handling various pdf-related tasks. So far as I can tell, most of these features are available in much newer, lighter libraries/extensions, except the one I need (and probably the only reason it still exists): merging form data files (fdf and xfdf) with a form PDF and getting a new file as the output.
The problem is that my server doesn't have gcj, which is fundamental to build/compile pdftk. I don't know if it's because I'm on Solaris or if it's for some other sysadmin-level reason, but I'm not getting gcj anytime soon. And there are no pre-compiled binaries for Solaris as far as I can find.
So I'm thinking that the MAKE file and C code can be rewritten to import the Java library (very ancient version of itext) directly, via javac.
But I'm not sure where to really start. All I know is:
I want a binary when I'm done, so that there won't be a need for a Java VM on every use.
The current app uses GCJ.
So my first thought was "Oh this is easy, I can probably just call the classes with some other C-based method", but instead of finding a simple method for doing this, I'm finding tons of lengthy posts on the various angles that this can be approached, etc.
Then I found a page on Sun's site on how to call other languages (like C) in a Java class. But the problems with that approach are:
I'd have to write a wrapper for the wrapper
I'd probably be better off skipping that part and writing the whole thing in Java
I ain't ready for that just yet if I can just import the classes with what is already there
I'm not clear on if I can compile and get a binary at the end or if I'm trapped in Java being needed every time.
Again, I apologize for my ignorance. I just need some advice and examples of how one would replace GCJ dependent C code with something that works directly with Java.
And of course if I'm asking one of those "if we could do that, we'd be rich already" type questions, let me know.
I'm not sure what you are looking for exactly, so I provided several answers.
If you have java code that needs to run, you must:
Run it in a jvm. You can start that vm within your own custom c-code, but it is still using a jvm
Rewrite it in another language.
Compile with an ahead-of-time compiler (eg gcj)
Incidentally, you could compile a copy of gcj in your home folder and use that. I believe the magic switch is --enable-languages=java,c (see: here for more)
If you have c-code you want to call from java, you have four options:
Java Native Interface (JNI). It seems you found this
Java Native Access (JNA). This is slower than JNI, but requires less coding and no wrapper c-code. It does require a jar and a library
Create a CLI utility and use Runtime.Exec(...) to call it.
Use some sort of Inter Process Communication to have the Java code ask the c-code to perform the operation and return the result.
Additional platform dependent options
Use JACOB (win32 only: com access)
I am not sure if I understand what you are looking for.
If you are looking to incorporate the C code into Java to make a native binary without the gcj, I think you are out of luck. You can include the C in Java, but it would be a primarily Java program meaning you would need the JVM on each run. Is there anything stopping you from compiling the gcj yourself?