Java RMI Netbeans Packages - java

When using Netbeans I am able to run RMI applications if I don't put the source files in a package, however when I try and split it up into packages.
I start to get class not found exceptions any help would be greatly appreciated.

Post some code. Class not found exceptions usually mean that your classpath isn't set properly. I don't mean a CLASSPATH environment variable, either. NetBeans (and all IDEs) ignore environment variables and ask that you tell them where to find .class files.
Find out what NetBeans thinks your classpath is and make sure it's set properly.

RMI server returns the output with the package name and interface name. So, when the interface moved to another package, the server can't identify that. That is the problem you have.

Related

How do I set the classpath that rmiregistry uses?

I'm trying to make a Java RMI client/server app. I'm running into problems starting up the server side of my app, as it keeps running into a ClassNotFoundException during the call to the Registry.bind() method when I attempt to start up the server side of the app.
I started with the simple tutorial here: http://docs.oracle.com/javase/1.5.0/docs/guide/rmi/hello/hello-world.html. After following those instructions, it was initially throwing a ClassNotFoundException complaining that it couldn't find "example.hello.Hello". I was able to resolve that by starting the rmiregistry FROM the destDir directory in the tutorial, since rmiregistry, apparently, uses its initial starting directory as part of its classpath.
I started on my other test app after that, and I was fine until I started to use third-party jar files in my server class. Now Registry.bind() throws a ClassNotFoundException if my server class references anything in any jar file since the rmiregistry app doesn't know about those jar files.
As far as I can tell, rmiregistry does not accept any sort of classpath startup arg, so I'm wondering how I can tell it what classpath I want it to acknowledge. According to the tutorial here: http://docs.oracle.com/javase/tutorial/rmi/running.html, "you must make sure that the shell or window in which you will run rmiregistry either has no CLASSPATH environment variable set or has a CLASSPATH environment variable that does not include the path to any classes that you want downloaded to clients of your remote objects." That sounds like the opposite of what I need... or am I reading it incorrectly? Has anyone had any success starting up a RMI client/server that uses third-party jars (commons-io, commons-logging, and rmiio, in my case)?
This is on Windows, by they way.
Update
I found a way around it. See my answer below.
The remarks about unsetting the CLASSPATH only apply if you're using the RMI codebase feature, as the cryptic remark about downloading classes is intended to imply.
If you're not using the codebase feature, just either:
Set the CLASSPATH environment variable as required before starting rmiregistry, as shown elsewhere here, or
Start rmiregistry with -J-Djava.class.path=...
Start the Registry inside your server JVM, with LocateRegistry.createRegistry(). This is in many ways the best solution, as it lives and dies with the JVM, shares its classpath, and incidentally complies with the requirements for the codebase feature as well.
If you do (3), you must store the return value into a static variable to prevent it from being garbage-collected, which causes the registry to be unexported, which can lead to DGC of the remote object, which can lead to it being GC'd, which will lead to the listening thread exiting, which can lead to the whole JVM exiting.
There is no RMI Registry specific java class path. It should use the same classpath as the rest of the Java system. You can set your classpath by specifying it on the command line, or in your OS environment. Though a little dated, this doc should point you in the right direction.
(I had originally posted this answer as an update to my question. Per Zecas's suggestion in one of the comments, I'm moving it to the answer section.)
I was able to get the server part to start up by disobeying the suggestion in the second tutorial referenced in my question above:
"you must make sure that the shell or window in which you will run
rmiregistry either has no CLASSPATH environment variable set or
has a CLASSPATH environment variable that does not include the path to
any classes that you want downloaded to clients of your remote
objects."
I created a CLASSPATH environment variable and added my .class output directory and each of the third-party jar files to that. I thought I had tried that before, but I guess not... Just thought I'd leave my solution in case someone else has the same problem.
An example of how to set classpath for rmiregistry
Win32:
set CLASSPATH=c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar
UNIX:
setenv CLASSPATH /home/ann/src:/home/ann/public_html/classes/compute.jar

Java - How to make program run jar files internally

I was wondering ... I want to use a plugin-type thing with my Java program.
Here is the situation:
I have compiled a source file (.java) into a .jar file using MY .JAR program as a library. How to I make MY program run the other .jar file internally (using the main program as a reference).
I know this is weird (it sounds weird to me too), but if anyone understands what I am trying to say, please comment.
Thank you all in advance!
OK, here's a draft of how to do it.
Create an interface with a "run()" method.
Your .java plugin must implement that interface.
Load the all classes in classpath (help here Find Java classes implementing an interface)
run your plugin by executing the run method of the interface.
You would have to run the jar using the standard syntax. Your question is basically about running console commands inside java. Here is a nice answer to a similar question:
link!
This isn't necessarily exactly what you want, but it's goal is to put you on the right track, basically you would get the jar placement, then check for the system, then use the technique used there to run a command through the specific platform's console.

Are Tomcat jars meant to be added to the classpath?

Since jars like servlet.jar are usually not downloaded on their own, but rather come part of tomcat/lib folder, should I just add an entry to them in the classpath? Is that the common practice?
I use Ubuntu.
You only need to reference them yourself when you want to compile servlet classes. How to do that depends in turn on the tools used for compilation.
If you're using plain javac, then you could reference them in %CLASSPATH%. But even then, that's considered a poor practice since that would potentially pollute the default classpath of all other Java compilations/applications. Rather write a shell file which sets the classpath right on the current execution environment by utilizing the -cp attribute of javac command.
If you're using a bit decent IDE like Eclipse/Netbeans, then you should just integrate the server in the IDE and associate the project with it. The IDE will then take care about setting the buildpath right. You don't need to set any environment variables then.
You do not need to reference them when you want to run them. The servletcontainer will take care about it by itself.
See also:
How do I import Servlet API in Eclipse?
If you are running a web application on Tomcat then the servlet-api.jar is in the classpath.

how to make setup file

i have made an application using java....my source is in .java file ...now i want to create a setup file from these source files....
so can anyone tell me how i can make this setup files like another softwares...like device driver....etc...
please co-operate me....
Java can only be run on a machine with a JRE (Java Runtime Environment), so your setup file won't run quite the same as other application setup files; you won't be able to give someone your setup file and expect it to run correctly, unless they already have the appropriate JRE.
However, in Java, the usual way to do the "setup routine" is typically going to result in a "jar" file. Have a look at jar.exe (or "jar" if in linux/unix). It will chunk your classes into the appropriate container.
AdvancedInstaller offers features for installation of Java applications
Perhaps this will help you.

UnsatisfiedLinkError: The specified procedure could not be found

I'm writing some JNI code in C++ to be called from an applet on Windows XP. I've been able to successfully run the applet and have the JNI library loaded and called, even going so far as having it call functions in other DLLs. I got this working by setting up the PATH system environment variable to include the directory all of my DLLs are in.
So, the problem, is that I add another call that uses a new external DLL, and suddenly when loading the library, an UnsatisfiedLinkError is thrown. The message is: 'The specified procedure could not be found'. This doesn't seem to be a problem with a missing dependent DLL, because I can remove a dependent DLL and get a different message about dependent DLL missing. From what I've been able to find online, it appears that this message means that a native Java function implementation is missing from the DLL, but it's odd that it works fine without this extra bit of code.
Does anyone know what might be causing this? What kinds of things can give a 'The specified procedure could not be found' messages for an UnsatisifedLinkError?
I figured out the problem. This was a doozy. The message "The specified procedure could not be found" for UnsatisfiedLinkError indicates that a function in the root dll or in a dependent dll could not be found. The most likely cause of this in a JNI situation is that the native JNI function is not exported correctly. But this can apparently happen if a dependent DLL is loaded and that DLL is missing a function required by its parent.
By way of example, we have a library named input.dll. The DLL search order is to always look in the application directory first and the PATH directories last. In the past, we always ran executables from the same directory as input.dll. However, there is another input.dll in the windows system directory (which is in the middle of the DLL search order). So when running this from a java applet, if I include the code described above in the applet, which causes input.dll to be loaded, it loads the input.dll from the system directory. Because our code is expecting certain functions in input.dll which aren't there (because it's a different DLL) the load fails with an error message about missing procedures. Not because the JNI functions are exported wrong, but because the wrong dependent DLL was loaded and it didn't have the expected functions in it.
There is a chance that the DLL was built using C++(as opposed to C). unless you took care to do an extern on the procedure,this is one possible reason.
Try exporting all the functions from the DLL. If the list includes your function, then you're good.
Usually, when linking to other libraries, you need to link to the relevant .lib file. It sounds like you aren't referencing all the lib files you need. Check what isn't linking and make sure you add it's lib to the list for the linker.
Did you create the new external DLL using the standard JNI procedure? I.e., using javah and so forth? If so, then I am not sure what is wrong.
If not, then the procedure you're trying to call hasn't been exported (as mentioned by anjanb). I am aware of two way of exporting functions: a separate export list and marking specific functions with __declspec(dllexport).
Can't access variable in C++ DLL from a C app has a little more information the topic of DLLs.
Compile your c++ code in debug mode. Then insert the DebugBreak(); statement where you would like to start debugging. Run the java code. When the DebugBreak() statement is encountered you will get a popup with a Debug button on it. Click on it. Dev Studio will open with your program in machine code. Step over with the debugger twice and you should be able to step over your source code.
If you have done all programming issue at JNI manuals and examples but still you are getting same missing procedure error, problem can be at your path variable probably. Do below steps and run again:
Be sure about you set JAVA_HOME variable to your JDK folder(not JRE because JRE doesnt contain jni header)
Example:
At environment variable settings panel define var:JAVA_HOME val:C:\Program Files\Java\jdk1.7.0_11
add %JAVA_HOME%\bin to your path variable
After doing those steps, your application can find jni procedure name and links to JNI.dll in right way. So, i hope you dont get this missing procedure error again.

Categories

Resources