Using eclipselink in Java code run from MATLAB - java

I am trying to provide an interface that I can call from MATLAB to access the contents of a database. I already have an existing Java interface that uses eclipselink to connect to the database and I would like to re-use it. I wrote a class to provide this and it works properly when I call it straight from Java, but when I try to call it from MATLAB I get the following exception:
javax.persistence.PersistenceException: No Perisistence provider for EntityManager named DatabaseConnection
Usually this exception occurs when I do not have the META-INF folder with the persistence.xml on the classpath properly, but I have tried putting the base folder that contains the META-INF folder on both the dynamic and static MATLAB javaclasspaths with no success. Again, this exact code (including the persistence.xml) work fine when run from java. Does anyone know what I am missing?
The one main difference that I was able to track down from what occurs when I run the java code is that MATLAB is using a OSGI classloader (felix) rather than the default classloader that Java uses, but I haven't figured out what difference that makes to finding the persistence.xml.

Related

java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()L

I can't run methods of a library.
My library is in my PATH and also getting loaded without errors by following code:
System.loadLibrary("FTDIInterface");
But the functions are not working.
I get the following exception:
Caused by: java.lang.UnsatisfiedLinkError: Messgeraet.src.net.sf.yad2xx.FTDIInterface.getDevices()[LMessgeraet/src/net/sf/yad2xx/Device;
at Messgeraet.src.net.sf.yad2xx.FTDIInterface.getDevices(Native Method)
at Messgeraet.src.Emu.EmuConnection.<init>(EmuConnection.java:22)
at Messgeraet.src.Emu.EmuModel.connect(EmuModel.java:27)
at Messgeraet.src.JavaFX.FXController.connect(FXController.java:112)
... 62 more
I am using eclipse. In IntelliJ it is working fine and I also got another eclipse project that includes the library without any problems.
Why it can't run my method FTDIInterface.getDevices?
Your package seems off; Messgereat.src sounds like you have a project dir named Messgereat, within you have a folder named 'src' with your java sources, and you've misconfigured your build tooling; the right package name sounds like it should be: package net.sf.yad2xx;, but due to a misconfigured build it wasn't working and you decided to fix the problem by updating your package statements, but that broke your JNI bindings.
The solution would then be to undo all the changes you've made to your package statements, and fix your build script instead.
Alternatively, if you really do intend to use that bizarre package, then make sure you have executed javah with the exact same build setup and use that as a basis for your JNI code. If you've done that, include the exported symbols in the library as the comment by #user2543253 suggested.
NB: It's a bit odd that your loadLibrary call works at all; PATH has nothing to do with it, but presuambly then your library so happens to be located in a place that is listed on your librarypath, which is the system property (of the VM, not of your OS) named 'java.library.path'; you set it with e.g.:
java -Djava.library.path=/path1:/path2 -cp /path/to/dep1.jar:/path/to/dep2.jar com.foo.Main
because of this confusion it is also possible that some different native lib file also named FTDIInterface is being loaded instead of the one you think is being loaded. If you want to be certain of what is being loaded, run System.load("/absolute/path/to/the/dll-jnilib-or-so-libraryfile.so"); - then you know for sure.

Create API jar like Android does with stubbed methods?

I'm looking to distribute a custom API and know the classes will be available at run time. I would like my public and protected methods / classes to be included in a jar I can distribute but I don't want any other source code and I would like to throw an exception if that jars code is actually executed.
This is the exact behaviour the Android framework jar has when you attempt to execute the jar directly.
My question is how to I create the same jar from my source without manually going through and creating each stubbed method. I would like this to scale as my API grows.
I believe you can use for that purpose the mkstubs tool: https://github.com/android/platform_development/tree/master/tools/mkstubs
As #CommonsWare mentioned stubs in AOSP are generated by javadoc DroidDoc script, read here: How are .java files in android_stubs_current_intermediates directory generated?
One possibility is to write a Java compiler which outputs a copy of your source code with empty method bodies or a body work a single statement which throws an exception. Then you can use normal dev tools to compile the generated classes.

Requiring Java Classes in LuaJ

I'm attempting to make a game library in Java that uses Lua for the scripts. The real issue appears when I try to require a Java class (that is inside of a jar), and whenever I try to do so, I get an error much like the one below:
Exception in thread "main" org.luaj.vm2.LuaError: #/C:/xampp/htdocs/LevelDesigner/Projects/Lua Test/bin/levels/Test.lua:2 module
'resources.GameLevel' not found: resources.GameLevel
no field package.preload['resources.GameLevel']
How can I require a Java class that is within a jar? Right now it seems that, with Lua, I can only require .lua files, and not .class files. This is obviously problematic as Java files are compiled down to class files...And that is what I need to require.
The answer to this question is to use luajava.bindClass as opposed to require in all of your Lua scripts.

java.lang.NoClassDefFoundError for nested class at run-time? (Dependency problems?)

Ok, here's the situation:
I have three files:
1. TScan.java
2. Test.java
3. ScanServlet.java
I write my mail class, TScan in the TScan.java file, and inside that class, there is a nested class (not a sub-class), called TEntry. TScan has a main() used for testing and other methods that use the nested TEntry class with no problems.
Also, Test.java is a fancier testing program that uses items from TScan.java, including the TScan and TEntry classes with no problems. TScan.java and Test.java were developed and tested in Eclipse (and it compiles/runs fine from the command line as well).
So TScan is working to a useful point, and I wanted to include it in a webapp. Installed Jetty and wrote ScanServlet.java, which runs in Jetty, no problems.
I started referencing TScan and it started giving the error above for TScan. Changing the ClassPath to include the TScan.class file didn't work, so I made a JAR file and stuck it in the WEB-INF/lib/ folder of the WebApp, and now ScanServlet compiles filen, and seems to find TScan at run-time, however it gives the NoClassDefFounfError TScan$TEntry at run-time. This doesn't make sense to me, since:
1. Obviously it's finding the TScan class now (Since it's not complaining about that at compile or run-time)
2. The error occurs in the TScan.java file (TEntry isn't reference directly except by TScan), which runs fine in stand-alone mode!
3. I made TEntry public, and it still doesn't work.
I have found a lot of questions about NoClassDefFoundError, but none dealing with nested classes, especially with Jetty.
Bear in mind I am more used to Delphi, where if it compiles, it runs. (And ABAP which is more or less the same).
If someone has a solution I will be thrilled, otherwise, I am considering:
Copy-Paste the whole TScan into ScanServlet (Shouldn't have a problem finding it if it's in the same file!) (not very modular)
Move TEntry into a separate class in a separate .java file? (May be a pain to cleanly extract).
Have ScanServlet call TScan.Java as a command line program. (Slow...)
How have you created your jar file and does it contain TScan$TEntry.class in the correct folder?
An inner or nested class still produces a .class file which you need to ship
Looks like you are limping along because your not using any formal build tools that apply rigor and convention to your development. Before messing around what is where and how to manage your handful of classes...start using a real build system that produces a jar file that contains what you need. Maven, Ant, Buildr, whatever...something that applies some convention or configuration. Don't leverage anything any IDE gives you in terms of compiling or exporting something that is supposed to be runnable...you can't trust any of that bunk.
With a proper build mechanism and ideally declarative dependencies and the like you can address your issue in a iterative fashion to resolve the NCDFE. my 2 cents at least
[edit]
On your specific issue, I suspect your running into the webapp classloader configuration. By default classes in /lib are not exposed to webapp contexts. You will need to setParentLoaderPriority on the webapp context to true or bundle your classes as a war file. Also use --dry-run on the cli to help sort out what jar files are being loaded up by jetty.

java.lang.NoSuchMethodError when the method definitely exists

I have a Spring framework based Java web application, which has been built in SpringSource Tool Suite ("STS"), and a local copy of Apache Tomcat. We also have a internal production server, again running Tomcat.
When I run the application on my development machine, and carry out a specific action in the web application, everything works correctly. However, when I deploy the web application to Tomcat on the server (via a war file produced by maven), and repeat those aforementioned specific actions, I'm presented with some unexpected behaviour. When I checked the server tomcat log file, I found this...
2011-11-16 19:36:45,090 [http-8280-Processor1] ERROR [attachments] invoke - Servlet.service() for servlet attachments threw exception java.lang.NoSuchMethodError: net.wmfs.coalesce.aa.dao.MediaDao.updateAlfrescoNodeRef(Ljava/lang/Long;Ljava/lang/String;)V
at net.wmfs.coalesce.aa.service.impl.MediaServiceImpl.doFileUpload(MediaServiceImpl.java:102)
at net.wmfs.coalesce.aa.servlet.MediaServlet.doFileUpload(MediaServlet.java:83)
at net.wmfs.coalesce.aa.servlet.MediaServlet.doPost(MediaServlet.java:55)
Now, the updateAlfrescoNodeRef method definitly exists in the MediaDao class - otherwise my code would not compile in STS...
package net.wmfs.coalesce.aa.dao;
public class MediaDao extends JdbcDaoSupport {
public void updateAlfrescoNodeRef(final Long recordId, final String nodeRef) {
// java code
}
}
As you can see, the method signature is correct.
I suspected that there may have been a problem when maven produced the war file, so I extracted the war files contents. In the WEB-INF/lib folder, I found the jar file which holds the MediaDao class, and extracted its contents. I then did a...
cat ./MediaDao.class
Now, as class files are binary files, I mostly saw gobledegook. However, I was able to clearly make out references to the updateAlfrescoNodeRef method, as well as the contents of a String in that method. So, this means that the method is definitely there.
The bean configuration in the Spring framework XML files is definitely correct, or the code would not run when I execute it on my development machine.
Googling suggested a library conflict on the server, but all the referenced classes - MediaServlet, MediaServiceImpl, MediaDao - are in the main project (the one with the WEB-INF folder in it). While its conceivable there may be multiple copies of the dependencies on the server, there is definitely only one copy of the main project jar.
Does anyone have any ideas why this is happening?
The problem has now been resolved. Thank you everyone for your assistance.
It turns out that the main project had a dependency which had another MediaDao class, in exactly the same package path. Someone had basically copied the class into that dependency (as a library resource so that lots of projects could use it without specifying the main project as a dependency). However, that someone had not removed the class in the main project.
So, when I modified the class in the main project (I added the updateAlfrescoNodeRef method), and ran the application in STS on my machine, Tomcat used the version of the class in the main project, and not in the library because the library project was closed. When the application was deployed to the server however, it looks like the version of the class in the library was used instead (which, of course, didn't have the updateAlfrescoNodeRef method in it).
Expert tip if you ever find yourself in a similar situation: In STS, press CTRL+SHIFT+T to open the "Open Type" dialog, and enter the name of the problematic class to see a list of projects that have a class with that name.
If the error occured in android studio, it also can be a bug of the Instant Run. In that case: File -> Invalidate Caches/Restart. It solved my problem
If you are using Tomcat 6+, look in ~tomcat/lib for conflicting classes and jars.
In Tomcat 5, look in ~tomcat/common/classes, ~tomcat/common/lib, ~tomcat/shared/classes and ~tomcat/shared/lib.

Categories