.class file from jython with pydev - java

My first attempt at jython is a java/jython project I'm writing in eclipse with pydev.
I created a java project and then made it a pydev project by the RightClick project >> pydev >> set as... you get the idea. I then added two source folders, one for java and one for jython, and each source folder has a package. And I set each folder as a buildpath for the project. I guess I'm letting you know all this so hopefully you can tell me wether or not I set the project up correctly.
But the real question is: how do I get my jython code made into a class file so the java code can use it? The preferred method would be that eclipse/pydev would do this for me automatically, but I can't figure it out. Something mentioned in the jython users guide implies that it's possible but I can't find info on it anywhere.
EDIT: I did find some information here and here, but things are not going too smooth.
I've been following the guide in the second link pretty closely but I can't figure out how to get jythonc to make a constructor for my python class.

Jythonc doesn't exist anymore, it has been forked off to another project called Clamp, but with that said...
...you can pre-compile
your python scripts to .class files
using:
jython [jython home]/Lib/compileall.py
[the directory where you keep your
python code]
Source - Jython Newsletter, March 2009
When I fed it a folder with Python 2.7 code (knowing it would fail in Jython 2.5) it did output a .class file, even though it doesn't function. Try that with your Jython scripts. If it works, please let us know, because I'll be where you are soon enough.
Once you're that far, it isn't hard to convert your command line statement to an External Tool in PyDev that can be called as needed.

Following the "Accessing Jython from Java Without Using jythonc" tutorial it became possible to use the jython modules inside java code. The only tricky point is that the *.py modules do not get compiled to *.class files. So it turns out to be exotic scripting inside java. The performance may of course degrade vs jythonc'ed py modules, but as I got from the jython community pages they are not going to support jythonc (and in fact have already dropped it in jython2.5.1).
So if you decide to follow non-jythonc approach, the above tutorial is perfect. I had to modify the JythonFactory.java code a bit:
String objectDef = "=" + javaClassName + "(your_constructor_params here)";
try {
Class JavaInterface = Class.forName(interfaceName);
System.out.println("JavaInterface=" + JavaInterface);
javaInt =
interpreter.get("instance name of a jython class from jython main function").__tojava__(JavaInterface);
} catch (ClassNotFoundException ex) {
ex.printStackTrace(); // Add logging here
}

Related

How do I access an environment variable during compile time, when building a Java application on Windows?

I have a Java application for Windows. I would like that Java application, when run, to create a new file on disk with a file name that includes a version number. That version number is available as an OS environment variable while the Java application is being built by my Azure Dev Ops (ADO) pipeline. The ADO pipeline builds my code using CMake (which runs the javac command).
A solution is given here when using Maven as the build system. I could not find how to do the same in my build system, which does not use Maven and pom.xml. Is there a way to do the same when using javac command line?
Thanks,
Darren
CMake runs on many platforms
maven runs on about just as many, though.
That version number is available as an environment variable while the Java application is being built
javac has absolutely no support for preprocessing and cannot do this, period. preprocessing and IDEs mostly hate each others guts, which probably explains the java ecosystem and communities extremely strong dislike of the notion of a preprocessor; they like IDEs.
Answering your question directly
Thus, you'll have to look elsewhere. For example, you can include some token value in your java source file, such as:
private static final String FULL_VERSION_ID = "{## INJECT_VERSION_HERE ##}";
and then, before invoking javac, use sed or some other search and replace tool. However, this complicates your build considerably: You'd have to take that source file (which is really no longer an actual source file, it's a template to a source file now), copy it over (applying the sed transformation on the fly), and then compile that. That means the source file has to live elsewhere or have a different extension and that plays absolute havoc with your editor, because this is not 'normal' in the java community, so no tools support this sort of thing. Your IDE will get confused and show all sorts of errors in your code due to the (to the IDE) missing file.
Another solution is some creative hackery, where sed will modify the file in flight:
private static final String FULL_VERSION_TEMPLATE = "{## INJECT_VERSION_HERE ##}1.12";
private static final String FULL_VERSION =
FULL_VERSION_TEMPLATE.substring(FULL_VERSION_TEMPLATE.indexOf("##}") + 3);
And then your sed tool can just 'replace on the spot', using a regexp that will find the whole thing, which leaves the {## ##} marker intact, and which just replaces the 1.12 (everything from after the marker up to the first quotation mark - and then you need a rule that versions cannot ever contain quotation marks. I hope you can make that promise or this gets even more complicated.
CMake runs off of file modification timestamps, right? Oof. Well, try to make it leave the late 80s and work off of hashes instead, or this is going to cause needless recompilation. Alternatively, try to make sed not update the time stamp if the requested change ends up being a no-op.
But wait...
Are you sure you want to go down that deep, dark rabbit hole? Can't you do this much more java-esque, much simpler thing?
Instead of modifying a source file, can you instead add 1 non-class file to the end result (I assume your CMake tool ends up making a dex or jar or something similar)? For example, ensure that version.txt is available in the 'root' of the jar file. In java, you can write code that goes: "Hey, look in the exact same place you're looking for the very class files that compose this very application, and gimme the contents of one of em":
public class MyApp {
public static void main(String[] args) {
System.out.println(readVersion());
}
public static String readVersion() {
try {
try (var in = MyApp.class.getResourceAsStream("/version.txt")) {
return new String(in.readAllBytes(), StandardCharsets.UTF_8).trim();
}
} catch (IOException e) {
throw new InternalError("version.txt not found");
}
}
}
That'll do the job. This seems much easier: Now your CMake script just needs to make sure version.txt has the right version in it and is included in the jar or whatever the output of your build pipeline is (I admit I'm not familiar with what ADO is).

Trouble Understanding/Locating a Jar file (JIDT package) needed for Octave to Java Array Conversion

In this previous question, I was trying to rework some Matlab code and figure out a package called javaplex to be compatible with Octave; it uses Java, but is tooled for Matlab, hence that issue. Now in an interval of time, I was busy/running simulations, and hadn't gotten around to a final step - actually using the package, with most all of the difficulties worked out. It turns out that another step exists: I need to convert an Octave array to a Java array (although I'm not sure why this issue didn't come up in Matlab).
To do so, I have turned to this script, in which the comments indicate that when using it, it
Assumes the JIDT [Java Information Dynamics Toolkit] jar is already on the java classpath - you will get a java classpath error if this is not the case.
So I go to the JIDT GitHub page and download this package. Now I am not a very avid user of java, so I believe I am failing to see something fairly straightforward: I am not sure where the "JIDT jar" is that is referenced in the above block quote! I can't find such a particular jar file to put in Octave's java classpath. In this tutorial for JIDT, they say you need the "infodynamics.jar" file in the classpath (page 9). I'm not sure what jar file I should be looking for, and where. Any help understanding the nature, name and location of this jar file (within the infodynamics toolkit folder) would be appreciated!
As an inevitable follow-up question, because this will come up upon resolving this issue, I would like to clarify the following procedure is how to add a jar file to the Octave (static) java classpath (following this answer here, I wasn't sure if I was implementing correctly):
I create a file called "javaclasspath.txt" inside of the directory I use in Octave.
I enter the name of files as follows: "./path/to/your-file.jar"
I suppose my main issue here is where do I start the path (all the way back with "C:/..."?), and do I put this "javaclasspath.txt" file in the directory folder I will be using most of the time in Octave?
Edit: I cannot find "infodynamics.jar" as shown here:
The JIDT jar is named infodynamics.jar and it is located in the root of the downloads infodynamics-dist-1.4.zip file.

Interaction betewen Makefile, the Java RMI module and Java packages

To start, this project was developed in Eclipse and then all the source files were moved onto a Unix system to be tested. There are four different stages to my problem.
All files are in the default package : Project runs
Files are seperated into packages : Project no longer runs
Files are returned to the default package : Project still doesn't run
File contents are copied into another project : Project run
So, in the first stage we have 6 files, all in the default package. They are:
Main.java (This chooses which type of RMI object to make and execute ie. Server/Client)
RMIFunction.java {implements MapperInterface}
RemoteInterface.java {implemets Remote}
ConnectionInterface.java (This is to allow polymorphism in Main)
RMIClient.java {implements ConnectionInterface}
RMIServer.java {implements ConnectionInterface}
At this stage of my project everything runs fine, and all RMI Functions work.
In the second stage of my project, I decided to organize my files into packages.
Application: Main.java
Objects: Everything else
Makefile: executes javac package/file.java for all files
At this point, my program has stopped working and I spend a good three hours researching my problem on Google (a good portion of that time on here). The errors might have something to do with the makefile changing the compiled files in some way that I don't know of(PS. I know practically nothing of makefiles, I took the one I used off the internet to compile all of my java files). I got a Connection error and I fooled around with rmiregistry calls(none of these worked, since the port was supposedly already being used by an unnamed program...)
My next stage was out of frustration, where I just put everything back into default package. I was hoping that everything would go back to the way it was. Lo and behold, it was still broken, but this time I had a different error:
UnmarshalException: ... nested exception; ClassNotFoundException
So, here I thought that the RMIFunctions_stub was not being found by my Main file, where the exception was being thrown. I did a lot of research into classpaths, which came up dry. I was particularly confused because I could see the file that was not found in the same directory as Main.
So, the fourth stage that I was reduced to was to make a whole new project, copy and paste all the contents of the 6 original files into new files(all named the same) and now it magically works.
If anyone can share some insight on how this problem happened/was resolved that would be fabulous. My intuition now is that there's some metadata stored somewhere in eclipse when you make a package, and that's what messed up the files in stage 3.
PS. If someone wants to see some actual code where my explanation is lacking, I'll put it up. I just didn't want to throw up 7 different files and overwhelm people trying to figure out the problem.
EDIT 02/08/2015 -
#immibis: stopped working was explained in the short explanations of the different stages, that is which errors were thrown and such.
#EJP: thanks for the suggestion

Matlab doesn't see .jar file

Ok, I'm stumped here. I'm using Matlab version 2013b with a Java RTE of 1.7.0_11 and I'm trying to run a simple piece of code to see if Matlab is able to read the .jar file and nothing seems to be working.
Here is the Java code, which is compiled to a .jar named JavaOCT.jar, which is placed in the Matlab working directory:
package VTK;
public class vtkVolumeView{
public int Test(){
return 10;
}
}
That is it, no other dependencies, nothing fancy. In Matlab, I try:
javaaddpath('\JavaOCT.jar'); %<-Directory and name are 100% correct
import VTK.*; %<-Package name from above
methodsview VTK.vtkVolumeView; %<-Can't find the class, argh!
Matlab kicks back that it can't find the class.
Things I've done to try and solve the problem:
Reverted to the exact same JDK as the Matlab RTE
Tried an older 1.6 JDK
Done lots of stack overflow research to try and solve it 1 2 3 4
Tried used javaclasspath and pointing to the compiled class instead
Read the Matlab documentation 5
Using clear -java after the javaaddpath
Any help would be appreciated, it is driving me nuts!
Update: Daniel R suggested just javaaddpath('JavaOCT.jar') which doesn't work either.
Final update: It finally works! I wasn't building the .jar properly. In IntelliJ, click on the project and hit F4. This brings up the Project Structure, then go to Artifacts and click the green + button and add DirectoryContent and then point to the out\production. Once this is done, as mentioned by others, it should show up in Matlab as an expandable .jar.
I don't know which operating system you are using, but the ./ seems invalid.
Try javaaddpath('JavaOCT.jar'); or javaaddpath(fullfile(pwd,'JavaOCT.jar'));.
What does exist(fullfile(pwd,'JavaOCT.jar')) return?
Some things to try:
Add the class file. When using a package, you need to add the class file in at the host of the package. For example, if your code is here:
\\full\path\to\code\VTK\vtkVolumeView.class
Then use:
javaaddpath('\\full\path\to\code')
I'm still suspicious of your *.jar path. You should usually use absolute paths when adding jar files. Try adding the results of which('JavaOCT.jar')
How did you make your jar file? Does it contain the appropriate directory structure implied by your package declaration?

Java - .jar unexpected issue with Netbeans

First of all, I am aware of Stack Overflow (and any competent forum-like website) policy of "search first, ask last", and, doing my homework, I searched various sources to find a solution to my issue. That said, I, failing to find any suitable answers, was left no choice but to ask this problem personally.
I have somewhat moderate programming skills, especially regarding the Java language. I am working on this 2D game with the default Java SE JDK. More specifically JDK 7u4. In this project, we have a class that manages most I/O operations. One of its methods returns the path to a file:
public static URL load(String resource) {
return ZM.class.getResource(resource);
}
Now, this method works fine when running the project on Netbeans (version 7.1). However, when building and cleaning the project, the resulting .jar file does not seem to agree with its creator. When running the .jar on command line, the JVM caught a NullPointerException. It seemed that the file was not being able to be read inside the .jar. Following my programmers instinct, I started debugging the project. My first attempt was to check whether the load method was the faulty member. I ran some tests and obtained a couple of interesting results:
When running the application on Netbeans and with "ZM.class" as the methods argument, it returned:
/D:/Projects/GeometryZombiesMayhem/build/classes/geometryzombiesmayhem/ZM.class
But when running it from the .jar file, it returned:
file:/D:/Projects/GeometryZombiesMayhem/dist/GeometryZombiesMayhem.jar!/geometryzombiesmayhem/ZM.class
Naturally, I tried removing the initial file: string from it. No effect. Then I tried taking the exclamation mark from [...].jar![...]. Again, nothing. I tried removing all the possible permutations from the path. No luck.
Testing the method against the very own .jar file worked okay. Now, when I try to access the inside of the file, it doesn't let me. On earlier versions of this project it worked just fine. I am not really sure of what is going on. Any help is welcome.
Thank you in advance,
Renato
When loading resources from a jar file, I've always used a classLoader. Everything seems to work the same whether you run from within the IDE, launch the executable jar file or run the program from a web site using JNLP.
Try loading the resource this way instead:
try {
ClassLoader cl = ZM.getClass().getClassLoader();
ImageIcon img = new ImageIcon(cl.getResource("images/programIcon.jpg"));
// do stuff with img.
}
catch(Exception failed) {
System.out.println(failed);
}
One more suggestion - you should create a separate folder for resources. In my example above, images is a folder inside of my src folder. This way it will automatically become part of the jar when I build it, but I am keeping resources separate from source code.
I suppose your problem is in loading an image from your jar file.
Here is how i do it
URL imageurl = Myclassanme.class.getResource("/test/Ergophobia.jpg");
Image myPicture = Toolkit.getDefaultToolkit().getImage(imageurl);
JLabel piclabel = new JLabel(new ImageIcon( myPicture ));
piclabel.setBounds(0,0,myPicture.getWidth(null),myPicture.getHeight(null));
This way I can get the Ergophobia.jpg file inside 'test' package.

Categories

Resources